使用R dplyr实现多列原地Mutate:基于行内条件替换NA值
使用dplyr按条件替换指定列的NA值
需求说明
对数据框中的var1-var3列执行修改,规则如下:
- 若某行的
var1-var3中存在至少一个值为1,则将该行这些列里的NA替换为0 - 若该行
var1-var3全为NA,则保持NA不变
测试数据
df <- data.frame("var1" = c(1,NA,1,NA,NA), "var2" = c(NA,NA,NA,1,1), "var3" = c(1,NA,NA,1,NA), "age" = c(25,41,39,60,36) , "satisfaction" = c(5,3,2,5,4) )
期望输出
# var1 var2 var3 age satisfaction # 1 1 0 1 25 5 # 2 NA NA NA 41 3 # 3 1 0 0 39 2 # 4 0 1 1 60 5 # 5 0 1 0 36 4
原代码问题
你写的代码存在两个主要问题:
mutate_at是dplyr旧版函数,现已被mutate(across(...))替代case_when语法错误,且if_any(.x, ==, 1)用法不当——.x在mutate_at的函数中代表单个列,无法用if_any检查整行的var列
正确解法
方法1:使用临时标记列
library(dplyr) df <- df %>% # 标记每行是否有至少一个1 mutate(has_one = if_any(starts_with("var"), ~ .x == 1)) %>% # 按规则替换NA mutate(across(starts_with("var"), ~ ifelse(has_one & is.na(.x), 0, .x))) %>% # 移除临时列 select(-has_one)
方法2:一步完成(无需临时列)
df <- df %>% mutate(across(starts_with("var"), ~ { # 判断当前行是否存在1 row_has_one <- if_any(starts_with("var"), ~ .x == 1) # 替换逻辑 ifelse(row_has_one & is.na(.x), 0, .x) }))
结果验证
运行上述代码后,var1-var3列会按照需求完成替换,非目标列(age、satisfaction)保持不变。
内容的提问来源于stack exchange,提问作者saddas
相关产品推荐
相关产品推荐

