嵌套if_else语句异常:仅部分条件生效,Nursery/Other返回NA
解决嵌套if_else返回NA的问题
看起来你遇到的问题根源在于NA值的处理——当Cultivation Type或Processing Type为NA时,str_detect()会返回NA,而dplyr::if_else()在条件为NA时不会继续执行后续的else分支,直接返回NA,这就导致Nursery和Other的判断根本没机会触发。
我给你两种解决方案,优先推荐第一种,因为case_when()比嵌套if_else更易读,也更容易处理复杂条件:
方案1:用case_when替代嵌套if_else(推荐)
case_when()会按顺序判断每个条件,而且可以明确处理NA的情况,避免条件返回NA导致的中断:
library(dplyr) library(stringr) DF.2 <- DF.1 %>% mutate( Type = case_when( # 匹配Micro:先排除NA,再检测是否包含micro (!is.na(`Cultivation Type`) & str_detect(tolower(`Cultivation Type`), "micro")) | (!is.na(`Processing Type`) & str_detect(tolower(`Processing Type`), "micro")) ~ "Micro", # 匹配Standard:同理排除NA (!is.na(`Cultivation Type`) & str_detect(tolower(`Cultivation Type`), "standard")) | (!is.na(`Processing Type`) & str_detect(tolower(`Processing Type`), "standard")) ~ "Standard", # 匹配Nursery:仅检测Cultivation Type,排除NA !is.na(`Cultivation Type`) & str_detect(tolower(`Cultivation Type`), "nursery") ~ "Nursery", # 所有其他情况(包括所有字段都是NA的情况) TRUE ~ "Other" ) )
方案2:修复原有的嵌套if_else
如果你坚持要用if_else,需要在每个条件里先处理NA,把NA转为FALSE,这样条件就不会返回NA:
DF.2 <- DF.1 %>% mutate( Type = if_else( # 用is.na把NA转为FALSE,确保条件是TRUE/FALSE (!is.na(`Cultivation Type`) & str_detect(tolower(`Cultivation Type`), "micro")) | (!is.na(`Processing Type`) & str_detect(tolower(`Processing Type`), "micro")), "Micro", if_else( (!is.na(`Cultivation Type`) & str_detect(tolower(`Cultivation Type`), "standard")) | (!is.na(`Processing Type`) & str_detect(tolower(`Processing Type`), "standard")), "Standard", if_else( !is.na(`Cultivation Type`) & str_detect(tolower(`Cultivation Type`), "nursery"), "Nursery", "Other" ) ) ) )
为什么原来的代码失效?
举个例子看第11行数据:Cultivation Type是"Nursery",Processing Type是NA。原代码的第二个条件是:str_detect(tolower("Nursery"), "standard") | str_detect(tolower(NA), "standard")
前者是FALSE,后者是NA,所以整个条件结果是FALSE | NA = NA。而if_else()遇到NA的条件时,不会进入else分支,直接返回NA,所以永远到不了判断Nursery的那一步。
用上面的方案处理后,第11行会正确返回"Nursery",所有全NA的行会返回"Other"。
内容的提问来源于stack exchange,提问作者SteveM
相关产品推荐
相关产品推荐

