R语言如何按条件将A列缺失值替换为B列值生成新列C
R语言按条件填充缺失值生成新列实现方案
需求说明
现有数据集所有列均为字符型,其中A列存在缺失值,需要新增C列,赋值规则为:
- A列无缺失的行,C列取对应行A列的原始值
- A列存在缺失值的行,C列取对应行B列的值
原始数据集样例
| A | B |
|---|---|
| 13 A 1 | 15 A 2 |
| 15 A 2 | 15 A 2 |
| NA | 15 A 8 |
| 10 B 3 | 15 A 2 |
| NA | 15 A 5 |
期望输出结果
| A | B | C |
|---|---|---|
| 13 A 1 | 15 A 2 | 13 A 1 |
| 15 A 2 | 15 A 2 | 15 A 2 |
| NA | 15 A 8 | 15 A 8 |
| 10 B 3 | 15 A 2 | 10 B 3 |
| NA | 15 A 5 | 15 A 5 |
原有代码问题
之前尝试用for循环实现,但返回结果不符合预期,原有代码如下:
for(i in 1:length(df$A)) { if(is.na(df$A[i])) { df$C <- df$B } else { df$C<- df$A } }
问题根源:循环内每次执行赋值操作时,都是将整列B或整列A赋值给C列,而非针对当前遍历的第i行赋值,最终C列的结果完全由最后一行的判断逻辑决定,和逐行赋值的预期逻辑完全不符。
可行实现方案
R语言做这类逐行判断优先用向量化操作,无需写循环,代码简洁且运行效率更高。
1. 基础R原生方案(无需加载第三方包)
用向量化判断函数ifelse()直接逐行判断赋值:
df$C <- ifelse(is.na(df$A), df$B, df$A)
2. dplyr包方案(代码可读性高)
用dplyr包中专门处理缺失值填充的coalesce()函数,函数会按顺序取第一个非缺失值,完全匹配当前需求:
library(dplyr) df <- df %>% mutate(C = coalesce(A, B))
3. data.table方案(适合大数据量场景)
data.table的fcoalesce()函数处理速度更快,适合百万行以上的大数据集:
library(data.table) setDT(df)[, C := fcoalesce(A, B)]
修正后的循环写法(不推荐,仅作参考)
如果一定要用循环实现,必须提前初始化C列,并且每次循环仅对第i行的C值赋值,不要覆盖整列:
# 提前初始化和数据集行数等长的C列 df$C <- character(nrow(df)) for(i in 1:nrow(df)) { if(is.na(df$A[i])) { df$C[i] <- df$B[i] } else { df$C[i] <- df$A[i] } }
这种写法运行效率远低于上面的向量化方案,数据量较大时运行速度会有明显差距,不建议使用。
内容的提问来源于stack exchange,提问作者thib plass
相关产品推荐
相关产品推荐

