使用dplyr按组抽样填充NA值(排除group=C组)
分组条件下NA值的抽样替换解决方案
问题原因
你之前的代码失效,核心是两个问题:
mutate的向量化计算特性:不管if/case_when的条件是否满足,分支里的表达式都会被完整计算。比如C组中,sample(X1[!is.na(X1)], ...)会被执行,但C组没有非NA值,直接触发抽样错误。- 抽样向量长度不匹配:你生成了和组内总行数等长的抽样向量,但实际只需要给组内的NA行赋值,导致向量长度不匹配,
case_when无法正确映射。
正确实现方式
以下是两种可靠的写法,均基于分组操作,只对group != "C"的组内NA值进行抽样替换:
方法1:用replace精准替换NA位置
library(dplyr) # 原始数据框 df <- data.frame( id = 1:10, group = c(rep("A",5),rep("B",4),"C"), X1 = c(NA, 2, 1, NA,4, 3, NA, 8, 9, NA)) %>% group_by(group) %>% mutate( X3 = X1, # 仅处理非C组的NA值 X3 = if (first(group) != "C") { replace(X3, is.na(X3), sample(X3[!is.na(X3)], sum(is.na(X3)), replace = TRUE)) } else { X3 } ) # 查看结果 df
方法2:用ifelse匹配替换长度
df %>% group_by(group) %>% mutate( X3 = ifelse( is.na(X1) & group != "C", # 仅抽取当前组需要替换的NA数量 sample(X1[!is.na(X1)], sum(is.na(X1) & group != "C"), replace = TRUE), X1 ) )
代码说明
- 两种方法都先按
group分组,确保抽样仅基于当前组的非NA值。 - 仅对
group != "C"的组执行替换逻辑,避免C组触发空值抽样错误。 - 抽样长度严格匹配当前组需要替换的NA数量,解决向量长度不匹配问题。
内容的提问来源于stack exchange,提问作者Johannes
相关产品推荐
相关产品推荐

