如何在data.table中利用向量存储的列名程序化创建新列
在data.table中用向量存储的列名计算新列的解决方法
你遇到的问题很典型——直接用字符向量里的列名字符串做运算,R只会把它们当成普通字符串处理,而不是对应的数据表列,所以会报错。下面给你几个实用的解决办法,都能完美实现你的需求:
方法一:使用.SD和.SDcols(最推荐)
.SD是data.table里的特殊变量,代表"Subset of Data",配合.SDcols可以指定要操作的列,这样就能直接通过索引调用列了:
library(data.table) x <- data.table(`2021` = rep(10, 3), `2022` = rep(5, 3)) years <- c("2021", "2022") # 计算新列d x[, d := .SD[[2]] / .SD[[1]] - 1, .SDcols = years]
解释:.SDcols = years告诉data.table只把years里的列纳入.SD,之后.SD[[1]]就是2021列,.SD[[2]]就是2022列,直接运算即可。
方法二:使用get()函数
get()函数可以根据字符串获取对应的对象(这里就是数据表的列),非常适合这种场景:
x[, d := get(years[2]) / get(years[1]) - 1]
解释:get(years[2])会找到列名为"2022"的列数据,get(years[1])找到"2021"列,这样就能正常做除法运算了。
方法三:用eval()配合as.name()(补全你之前的尝试)
你之前试了eval和as.name但没成功,应该是没正确嵌套。其实这样写是可以的:
x[, d := eval(as.name(years[2])) / eval(as.name(years[1])) - 1]
解释:as.name()把字符串转成列名符号,eval()执行这个符号,从而获取对应的列数据,两者结合就能实现需求。
为什么原代码不行?
你原来的x[, d := years[2] / years[1] -1]里,years[2]是字符串"2022",years[1]是字符串"2021",R会尝试做字符串除法,这显然是不合法的,所以会报错。我们需要告诉R,要把这些字符串当成列名去引用对应的数据,上面的几种方法都是在做这件事。
内容的提问来源于stack exchange,提问作者Francesc VE
相关产品推荐
相关产品推荐

