如何将相同的函数应用于data.table中的每个指定列
我有一个data.table,我想在某些列上执行相同的操作。 这些列的名称是在一个字符向量中给出的。 在这个特殊的例子中,我想把所有这些列乘以-1。
一些玩具数据和一个向量指定相关的列:
library(data.table) dt <- data.table(a = 1:3, b = 1:3, d = 1:3) cols <- c("a", "b")
现在我正在这样做,遍历字符向量:
for (col in 1:length(cols)) { dt[ , eval(parse(text = paste0(cols[col], ":=-1*", cols[col])))] }
有没有办法做到这一点,没有for循环?
这似乎工作:
dt[ , (cols) := lapply(.SD, "*", -1), .SDcols = cols]
结果是
abd 1: -1 -1 1 2: -2 -2 2 3: -3 -3 3
这里有一些技巧:
- 因为在
(cols) :=
有圆括号,结果被分配cols
指定的列,而不是一些名为“cols”的新variables。 -
.SDcols
告诉调用我们只查看那些列,并允许我们使用.SD
,与这些列相关联的数据集。 -
lapply(.SD, ...)
在.SD
上.SD
,这是列的列表(如所有的data.frames和data.tables)。lapply
返回一个列表,所以最后j
看起来像cols := list(...)
。
编辑 :这是另一种可能更快的方式,如@阿伦提到的:
for (j in cols) set(dt, j = j, value = -dt[[j]])
我想添加一个答案,当你想改变列的名字。 如果你想计算多列的对数,这在实证工作中经常是这样。
cols <- c("a", "b") out_cols = paste("log", cols, sep = ".") dt[, c(out_cols) := lapply(.SD, function(x){log(x = x, base = exp(1))}), .SDcols = cols]