r-当使用ifelse对具有多个条件的新列进行变异时,如何处理或忽略NA(已解决)



我是dplyr的新手,曾尝试使用dplyr和ifelse从三个不同的年龄变量创建一个新的复合变量。我制作了一个数据框架来解释如下情况:

library(dplyr)
z <- data.frame("j6" = c(6, 19, NA, NA, NA, NA, NA, 8, 20, 20, NA), 
"j7" = c(27, 20, NA, 7, 19, NA, NA, 20, 30, 9, NA),
"j8" = c(8, 22, NA, 20, NA, 8, 30, NA, NA, NA, 3))
z <- z %>% 
mutate(., age_event = NA) %>% 
mutate(., age_event = ifelse(j6 < 18 | j7 < 18 | j8 < 18, 1, 0))

我的期望:

  • 三列(j6、j7和j8(表示年龄,如果其中至少有一列年龄小于18岁,则新列(age_event(应为"1",否则为0
  • 如果三列中的两列都是18岁或以上,而另一列是NA,则age_event变量应为0
  • 同样,如果三列中的一列为18岁或18岁以上,而其他列为NA,则age_event变量应为0
  • 如果这三列都是NA,那么它也是NA

然而,结果和问题如下所示:

> z
j6 j7 j8 age_event
1   6 27  8         1
2  19 20 22         0
3  NA NA NA        NA
4  NA  7 20         1
5  NA 19 NA        NA  <-- should be 0, but NA
6  NA NA  8         1
7  NA NA 30        NA  <-- should be 0, but NA
8   8 20 NA         1
9  20 30 NA        NA  <-- should be 0, but NA
10 20  9 NA         1
11 NA NA  3         1

我想知道是否有办法使用mutateifelse将上面的第5、第7和第9个观测值转换为0。如有任何建议,我们将不胜感激!


更新(2020年2月27日(:当使用mutateifelse:时,我发现了pmin的解决方案

z <- z %>% 
mutate(., age_event = ifelse(is.na(j6) & is.na(j7) & is.na(j8), NA,
ifelse(pmin(j6, j7, j8, na.rm = T) < 18, 1, 0)))
> z
j6 j7 j8 age_event
1   6 27  8         1
2  19 20 22         0
3  NA NA NA        NA
4  NA  7 20         1
5  NA 19 NA         0
6  NA NA  8         1
7  NA NA 30         0
8   8 20 NA         1
9  20 30 NA         0
10 20  9 NA         1
11 NA NA  3         1

您可以使用rowMeans()来代替if_else(),后者将处理全部为NA的情况。

z %>% 
mutate(age_event = +(rowMeans(. < 18, na.rm = TRUE) > 0))
j6 j7 j8 age_event
1   6 27  8         1
2  19 20 22         0
3  NA NA NA        NA
4  NA  7 20         1
5  NA 19 NA         0
6  NA NA  8         1
7  NA NA 30         0
8   8 20 NA         1
9  20 30 NA         0
10 20  9 NA         1
11 NA NA  3         1

我们可以使用rowSums来计算一行中NA值的数量和小于18的值的数量。然后,我们可以使用case_when根据不同的条件进行编号。

library(dplyr)
z %>%
mutate(calc = rowSums(!is.na(.), na.rm = TRUE),
ls18 = rowSums(. < 18, na.rm = TRUE), 
age_event = case_when(calc == 0 & ls18 == 0 ~ NA_integer_,
ls18 > 0 ~ 1L, 
TRUE ~ 0L)) %>%
select(-calc, -ls18)
#   j6 j7 j8 age_event
#1   6 27  8         1
#2  19 20 22         0
#3  NA NA NA        NA
#4  NA  7 20         1
#5  NA 19 NA         0
#6  NA NA  8         1
#7  NA NA 30         0
#8   8 20 NA         1
#9  20 30 NA         0
#10 20  9 NA         1
#11 NA NA  3         1

最新更新