R语言 将fill()与条件一起使用

vzgqcmou  于 2023-03-20  发布在  其他
关注(0)|答案(2)|浏览(193)
library(tidyverse)
df <- tibble(X = c("A1", "A2", "A3", "A4", "A5", "A5", "A6", "A7", "A8", "A8", "A9", "A9"),
             Y = c(31, 52, 45, 86, NA, 50, 93, 85, 59, NA, 85, NA),
             Z = c(70, 64, 51, 38, 18, NA, 76, 54, NA, 69, NA, 96),
             D = c(1,1,1,1,2,2,1,1,2,2,2,2))
> df
# A tibble: 12 x 4
   X         Y     Z     D
   <chr> <dbl> <dbl> <dbl>
 1 A1       31    70     1
 2 A2       52    64     1
 3 A3       45    51     1
 4 A4       86    38     1
 5 A5       NA    18     2
 6 A5       50    NA     2
 7 A6       93    76     1
 8 A7       85    54     1
 9 A8       59    NA     2
10 A8       NA    69     2
11 A9       85    NA     2
12 A9       NA    96     2

X具有重复值,有时重复两次。列D正在测量这些值的出现次数。列YZ具有一些得分。我希望这些得分在列X内的重复观测中重复。我尝试使用fill()方法,输出如下所示

df %>%
  filter(D == 1) %>%
  bind_rows(df %>%
              filter(D != 1) %>%
              fill(c("Y", "Z"), .direction = "downup")
  )

# A tibble: 12 x 4
   X         Y     Z     D
   <chr> <dbl> <dbl> <dbl>
 1 A1       31    70     1
 2 A2       52    64     1
 3 A3       45    51     1
 4 A4       86    38     1
 5 A6       93    76     1
 6 A7       85    54     1
 7 A5       50    18     2
 8 A5       50    18     2
 9 A8       59    18     2
10 A8       59    69     2
11 A9       85    69     2
12 A9       85    96     2

然而,无论我使用什么.direction选项,我似乎都不能得到正确的数字。例如,在上面的输出中,对于A9Z应该重复96两次。A8也有同样的问题。
我想要的输出如下

X         Y     Z     D
   <chr> <dbl> <dbl> <dbl>
 1 A1       31    70     1
 2 A2       52    64     1
 3 A3       45    51     1
 4 A4       86    38     1
 5 A6       93    76     1
 6 A7       85    54     1
 7 A5       50    18     2
 8 A5       50    18     2
 9 A8       59    69     2
10 A8       59    69     2
11 A9       85    96     2
12 A9       85    96     2
l0oc07j2

l0oc07j21#

您可以:

library(tidyverse)

df %>%
  group_by(X) %>%
  mutate(across(Y:Z, ~ first(na.omit(.))))

输出:

# A tibble: 12 x 4
# Groups:   X [9]
   X         Y     Z     D
   <chr> <dbl> <dbl> <dbl>
 1 A1       31    70     1
 2 A2       52    64     1
 3 A3       45    51     1
 4 A4       86    38     1
 5 A5       50    18     2
 6 A5       50    18     2
 7 A6       93    76     1
 8 A7       85    54     1
 9 A8       59    69     2
10 A8       59    69     2
11 A9       85    96     2
12 A9       85    96     2

您也可以像下面这样使用fill,但根据我的经验,这可能会相当慢:

df %>%
  group_by(X) %>%
  fill(Y, Z, .direction = 'downup')
2wnc66cl

2wnc66cl2#

可以使用group_by和mutate将NA的值更改为组中的另一个值

df %>% 
  dplyr::group_by(X) %>% 
  dplyr::mutate(
    Y = dplyr::case_when(
      is.na(Y) ~ Y[!is.na(Y)],
      TRUE ~ Y),
    Z = dplyr::case_when(
      is.na(Z) ~ Z[!is.na(Z)],
      TRUE ~ Z))

相关问题