如何在R的data.table中按行提取对应列号的列值并新增列
在data.table中根据指定列号提取对应列值新增列
这个需求在data.table里用矩阵索引就能高效解决,我给你演示一下具体操作:
首先,先确认我们的测试数据是正确的:
library(data.table) dt <- fread(" V1 V2 V3 V4 V5 1 10 7 4 3 2 11 8 5 2 3 12 9 6 1 4 1 10 7 4 5 2 11 8 4 6 3 12 9 3 7 4 1 10 3 8 5 2 11 1 9 6 3 12 2")
接下来就是核心的新增列操作,一行代码就能搞定:
# 新增V6列,取值为每行V5指定列号对应的列值 dt[, V6 := dt[cbind(seq_len(.N), V5)]]
原理说明
这里用到了data.table的矩阵索引特性:
seq_len(.N)生成从1到数据总行数的序列,也就是每行的行号cbind(seq_len(.N), V5)组合成一个N行2列的矩阵,每一行代表「行号,要提取的列号」- 用这个矩阵作为索引传入
dt[],就能精准提取每行对应列位置的数值,直接赋值给新列V6
这种方法是矢量化操作,比逐行循环或者分组处理效率高得多,尤其适合大数据集。
验证结果
执行完代码后查看dt,会得到符合预期的结果:
V1 V2 V3 V4 V5 V6 1: 1 10 7 4 3 7 2: 2 11 8 5 2 11 3: 3 12 9 6 1 3 4: 4 1 10 7 4 7 5: 5 2 11 8 4 8 6: 6 3 12 9 3 12 7: 7 4 1 10 3 1 8: 8 5 2 11 1 8 9: 9 6 3 12 2 6
比如第一行V5是3,对应V3的数值7,V6就为7;第三行V5是1,对应V1的数值3,V6就为3,完全符合需求。
补充方法(效率稍低)
如果你习惯用.SD的方式,也可以逐行分组提取,但这种方法在数据量大时效率不如矩阵索引:
dt[, V6 := .SD[[V5]], by = seq_len(.N)]
内容的提问来源于stack exchange,提问作者Lazarus Thurston
相关产品推荐
相关产品推荐

