如何将case_when脚本转为dt_case_when?TRUE分支失效问题求助
解决dt_case_when中默认分支不生效的问题
问题说明
用dt_case_when替换dplyr::case_when时,原代码中用来捕获所有剩余情况的TRUE ~ 0分支未生效,导致Status为NA的行无法被赋值为0,而case_when可以正常处理这种情况。
问题重现代码
df <- data.frame(Name = c("ID_1", "ID_2", "ID_3","ID_4"), Status = c(NA_character_, "Alive", "Alive", NA_character_)) # case_when 预期结果:NA的Status对应Value=0 df %>% mutate( Value = case_when( Status == "Alive" ~ 1, TRUE ~ 0 ) ) # dt_case_when 问题:NA的Status对应Value为NA,TRUE分支未生效 df %>% mutate( Value = dt_case_when( Status == "Alive" ~ 1, TRUE ~ 0 ) )
解决方案
方案1:明确处理NA情况
因为Status只有"Alive"和NA两种情况,直接针对NA写分支:
library(dtplyr) library(dplyr) df %>% mutate( Value = dt_case_when( Status == "Alive" ~ 1, is.na(Status) ~ 0 ) )
如果Status还有其他非NA的取值,可以用更通用的条件覆盖剩余情况:
df %>% mutate( Value = dt_case_when( Status == "Alive" ~ 1, !is.na(Status) & Status != "Alive" ~ 0, is.na(Status) ~ 0 ) )
方案2:使用.default参数(dtplyr >=1.3.0)
如果你的dtplyr版本足够新,可以直接用.default指定所有未匹配情况的默认值,无需写TRUE分支:
df %>% mutate( Value = dt_case_when( Status == "Alive" ~ 1, .default = 0 ) )
原因解释
dt_case_when基于data.table的表达式逻辑,和dplyr::case_when的行为不同:
- 当
Status为NA时,Status == "Alive"返回的是NA而非FALSE,不会触发后续的TRUE分支 dt_case_when不会将TRUE视为“匹配所有剩余行”的通配条件,必须明确处理NA或使用.default参数覆盖未匹配的情况
内容的提问来源于stack exchange,提问作者PMG
相关产品推荐
相关产品推荐

