R语言使用ifelse函数做条件判断时如何保留缺失值
R数据框新增条件判定列解决方案
需求回顾
需要为数据框新增列,判定规则如下:
- x1、x2、x3三列取值全部为1时,新列标注为
yes - x1、x2、x3三列取值全部为2时,新列标注为
no - 行中存在NA缺失值时,新列对应位置保留NA
- 三列取值不满足全1/全2条件时,新列对应位置保留NA
原代码问题排查
你写的代码存在3个核心问题,导致结果错误:
- 语法错误:
d$x2 ==1与d$x3 ==1之间缺失逻辑与连接符&,运行会直接抛出语法错误 - 逻辑缺失:没有覆盖「三列全为2标注no」的分支,仅做了全1的判断;且
!is.na()的判断位置完全错误,会把所有非NA的判断结果统一归为yes,完全不符合规则 - 类型隐患:示例数据中x1/x2/x3为字符型存储(取值为带引号的
"1"/"2"),直接和数值1、2对比依赖R的隐式类型转换,遇到特殊值时容易出现非预期结果。
可直接运行的实现代码
首先加载示例数据:
d <- structure(list(x1 = c("1", "1", "1", "2", NA, "2", "2", NA,NA, "1", "1", "1"), x2 = c(NA, NA, "1", NA, "2", NA, "2", "2", "1", "1", "1", "1"), x3 = c(NA, NA, "1", NA, "2", NA,"1", "1", "2", "1", "2", "1")), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -12L))
方法1:基础R实现(无需加载额外包)
R中逻辑运算遇到NA时会自动返回NA,刚好匹配保留缺失值的需求,不需要额外写NA判断逻辑:
d$new <- ifelse(d$x1 == "1" & d$x2 == "1" & d$x3 == "1", "yes", ifelse(d$x1 == "2" & d$x2 == "2" & d$x3 == "2", "no", NA))
方法2:dplyr实现(可读性更高,适合tidyverse工作流)
用case_when拆分判断分支,逻辑更清晰,不容易出现嵌套错误:
library(dplyr) d <- d %>% mutate(new = case_when( x1 == "1" & x2 == "1" & x3 == "1" ~ "yes", x1 == "2" & x2 == "2" & x3 == "2" ~ "no", TRUE ~ NA_character_ ))
结果校验
运行代码后得到的新列符合预期:
- 第3行三列全为"1",new列返回
yes - 第5行三列全为"2",new列返回
no - 其余存在NA、或三列值不统一的行,new列均返回NA
内容的提问来源于stack exchange,提问作者Lisa
相关产品推荐
相关产品推荐

