R语言根据D列条件从A/B/C列取值填充数据框新列E
需求说明
现有数据框df,包含ID、A、B、C、D五列,需要新增列E,填充规则为:
- D列值为1时,取同行A列的字符值
- D列值为2时,取同行B列的字符值
- D列值为3时,取同行C列的字符值
示例数据及预期输出如下:
| ID | A | B | C | D | E |
|---|---|---|---|---|---|
| t1 | tsg | tlm | NA | 1 | tsg |
| t2 | tsg | tlm | NA | 2 | tlm |
| t3 | tfp | tsl | tgg | 3 | tgg |
| t4 | tsg | tfp | NA | 2 | tfp |
| t5 | tlm | NA | NA | 1 | tlm |
| t6 | tgg | tlm | NA | 1 | tgg |
原尝试代码运行未得到预期结果,代码如下:
df$E[df$D == 1 ] <- df$A df$E[df$D == 2 ] <- df$B df$E[df$D == 3 ] <- df$C
问题原因
原代码的核心错误是赋值时左右两侧长度不匹配:左侧仅筛选了符合D值条件的行位置,长度为对应条件的行数,但右侧传入的是整列数据,长度等于数据框总行数,触发R的向量循环赋值规则,最终导致值错位、结果不符合预期。
base R 可行方案
方案1(推荐,简洁高效):矩阵索引法
R原生支持行、列位置组成的二维矩阵批量提取对应单元格的值,无需逐次判断,运行效率最高:
# 列位置映射:A是第2列、B是第3列、C是第4列,对应D值+1即可得到目标列号 col_pos <- df$D + 1 # 构造「行号,列号」矩阵,批量取值赋值给E列 df$E <- df[cbind(seq_len(nrow(df)), col_pos)]
方案2(适配原有思路,易理解):修正筛选逻辑
保留原有的条件判断写法,仅需要在赋值时给右侧的列也加上相同的行筛选条件,保证左右长度完全匹配即可:
# 先初始化E列为字符型空值,避免赋值类型异常 df$E <- NA_character_ df$E[df$D == 1] <- df$A[df$D == 1] df$E[df$D == 2] <- df$B[df$D == 2] df$E[df$D == 3] <- df$C[df$D == 3]
两种方案运行后得到的E列均与示例预期结果完全一致。
内容的提问来源于stack exchange,提问作者GDon
相关产品推荐
相关产品推荐

