You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在data.table中根据列名跨引用对应行的列值?

解决data.table中根据列名列逐行提取对应值的问题

我明白你的问题了——你想让每行根据v1列里存储的列名,提取对应列的对应行值,但用get()的时候得到了整列的重复值,而不是逐行匹配的结果。这是因为get()在data.table的j表达式里是按列向量处理的:它只会取v1的第一个元素(也就是'vs')对应的列,然后把整列的值赋值给v2,所以才得到了[0,0,1](也就是vs列的前三个值),而不是你期望的[0,1,4]。

下面给你几种可行的解决方案:

方法1:逐行分组(最直观的data.table风格)

利用data.table的分组功能,按每行索引(.I)分组,这样每个分组里v1是单个字符串,然后直接用.SD[[v1]]提取当前行对应列的值:

library(data.table)
dt = data.table(mtcars)
sub = dt[1:3]
sub[, v1 := c('vs', 'am', 'gear')]

# 核心代码
sub[, v2 := .SD[[v1]], by = .I]

运行后sub的v2列就是[0,1,4],完全符合你的期望。

方法2:使用mapply逐行匹配

mapply可以遍历v1的每个元素,结合行号提取对应位置的值:

sub[, v2 := mapply(function(col, idx) .SD[[col]][idx], v1, .I)]

这个方法的逻辑是:对每个行号idx和对应的列名col,提取.SD中col列的第idx个元素,最终组合成v2列。

方法3:矩阵索引技巧

先把v1指定的列转换成矩阵,然后提取对角线元素(每行对应列名的位置):

sub[, v2 := as.matrix(sub[, ..v1])[cbind(1:.N, 1:.N)]]

这里..v1表示取v1中存储的列名对应的列,转换成矩阵后,cbind(1:.N,1:.N)会定位到每行的目标列位置,提取出对应的值。

验证结果

无论使用哪种方法,最终sub的结构都会是:

mpg cyl disp  hp drat    wt  qsec vs am gear carb  v1 v2
1: 21.0   6  160 110 3.90 2.620 16.46  0  1    4    4  vs  0
2: 21.0   6  160 110 3.90 2.875 17.02  0  1    4    4  am  1
3: 22.8   4  108  93 3.85 2.320 18.61  1  1    4    1 gear  4

内容的提问来源于stack exchange,提问作者Marvin Taschenberger

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:31:19