使用dplyr中mutate嵌套ifelse生成infected列结果异常求助
问题描述
需要基于现有数据列创建新列infected,规则如下:
- 当
nb_positif > 0(存在至少1个阳性案例)时,infected = 1 - 当
nb_positif为NA且nb_negatif > 0时,infected = 0 - 当
nb_positif和nb_negatif均为NA时,infected = NA
数据结构:
structure(list(nb_positif = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 43L, 7L, 2L, NA, NA, NA, 1L, 6L, NA, NA, 2L, NA, NA, NA, NA, NA, NA, NA, NA), nb_negatif = c(1L, 2L, 3L, 1L, 1L, 2L, 6L, 2L, 11L, 1L, 5L, 45L, 35L, 12L, 2L, 3L, 11L, 12L, 9L, 2L, 2L, 10L, 2L, 14L, 12L, 3L, 2L, 1L, 1L, 15L)), reshapeWide = list( v.names = NULL, timevar = "grpName", idvar = "ID", times = c("NEGATIF", "POSITIF", "INDETERMINE"), varying = structure(c("resultatanalyse.NEGATIF", "n.NEGATIF", "resultatanalyse.POSITIF", "n.POSITIF", "resultatanalyse.INDETERMINE", "n.INDETERMINE"), .Dim = 2:3)), row.names = c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 12L, 14L, 16L, 18L, 19L, 20L, 21L, 23L, 25L, 26L, 27L, 29L, 30L, 31L, 32L, 33L, 34L, 35L, 36L ), class = "data.frame")
用户编写的代码及运行结果:
test_stack %>% mutate(infected=ifelse(nb_positif!="NA",1, ifelse(nb_negatif!="NA",0,"NA"))) #> nb_positif nb_negatif infected #> 1 NA 1 NA #> 2 NA 2 NA #> 3 NA 3 NA #> 4 NA 1 NA #> 5 NA 1 NA #> 6 NA 2 NA #> 7 NA 6 NA #> 8 NA 2 NA #> 9 NA 11 NA #> 10 NA 1 NA #> 11 NA 5 NA #> 12 43 45 1 #> 14 7 35 1 #> 16 2 12 1 #> 18 NA 2 NA #> 19 NA 3 NA #> 20 NA 11 NA #> 21 1 12 1 #> 23 6 9 1 #> 25 NA 2 NA #> 26 NA 2 NA #> 27 2 10 1 #> 29 NA 2 NA #> 30 NA 14 NA #> 31 NA 12 NA #> 32 NA 3 NA #> 33 NA 2 NA #> 34 NA 1 NA #> 35 NA 1 NA #> 36 NA 15 NA
问题原因
- 缺失值判断错误:R中的
NA是特殊的缺失值类型,不是字符串"NA"。原代码用nb_positif != "NA"无法识别真正的缺失值,导致第二个ifelse分支永远不会触发。 - 逻辑条件不符合需求:原代码第一个条件是判断
nb_positif不是字符串"NA",但实际需求是nb_positif > 0,逻辑匹配不准确。
解决方案
推荐使用dplyr::case_when编写清晰的多条件判断,可读性更强:
library(dplyr) test_stack %>% mutate(infected = case_when( nb_positif > 0 ~ 1L, is.na(nb_positif) & nb_negatif > 0 ~ 0L, is.na(nb_positif) & is.na(nb_negatif) ~ NA_integer_, TRUE ~ NA_integer_ # 兜底处理未覆盖的边界情况 ))
也可以修正ifelse嵌套写法:
test_stack %>% mutate(infected = ifelse(nb_positif > 0, 1L, ifelse(is.na(nb_positif) & nb_negatif > 0, 0L, NA_integer_)))
运行后,所有nb_positif为NA且nb_negatif > 0的行,infected会被赋值为0;两个字段均为NA的行保持infected为NA,完全符合需求。
内容的提问来源于stack exchange,提问作者Camillionnaire
相关产品推荐
相关产品推荐

