以编程方式选择变量的两种方法:
-
with = FALSE:
DT = data.table(col1 = 1:3)
colname = "col1"
DT[, colname, with = FALSE]
# col1
# 1: 1
# 2: 2
# 3: 3
-
'点点'(..)前缀:
DT[, ..colname]
# col1
# 1: 1
# 2: 2
# 3: 3
有关“点点”(..) 表示法的进一步说明,请参阅New Features in 1.10.2(目前未在帮助文本中描述)。
要分配给变量,请将:= 的LHS 括在括号中:
DT[, (colname) := 4:6]
# col1
# 1: 4
# 2: 5
# 3: 6
后者被称为列plonk,因为你通过引用替换了整个列向量。如果存在子集i,它将通过引用进行子分配。 (colname) 周围的括号是 CRAN 2014 年 10 月 v1.9.4 版本中引入的简写。这里是 the news item:
现在在所有情况下都不推荐使用 with = FALSE 和 :=,因为包装
:= 带括号的 LHS 已被首选一段时间。
colVar = "col1"
DT[, (colVar) := 1] # please change to this
DT[, c("col1", "col2") := 1] # no change
DT[, 2:4 := 1] # no change
DT[, c("col1","col2") := list(sum(a), mean(b))] # no change
DT[, `:=`(...), by = ...] # no change
另请参阅?`:=` 中的详细信息部分:
DT[i, (colnamevector) := value]
# [...] The parens are enough to stop the LHS being a symbol
为了在评论中回答进一步的问题,这里有一种方法(像往常一样有很多方法):
DT[, colname := cumsum(get(colname)), with = FALSE]
# col1
# 1: 4
# 2: 9
# 3: 15
或者,您可能会发现eval 和paste 更容易读取、写入和调试,类似于构造动态 SQL 语句以发送到服务器:
expr = paste0("DT[,",colname,":=cumsum(",colname,")]")
expr
# [1] "DT[,col1:=cumsum(col1)]"
eval(parse(text=expr))
# col1
# 1: 4
# 2: 13
# 3: 28
如果你经常这样做,你可以定义一个辅助函数EVAL:
EVAL = function(...)eval(parse(text=paste0(...)),envir=parent.frame(2))
EVAL("DT[,",colname,":=cumsum(",colname,")]")
# col1
# 1: 4
# 2: 17
# 3: 45
现在data.table 1.8.2 自动优化j 以提高效率,最好使用eval 方法。例如,j 中的 get() 会阻止一些优化。
或者,有set()。 := 的低开销、函数形式,在这里可以。见?set。
set(DT, j = colname, value = cumsum(DT[[colname]]))
DT
# col1
# 1: 4
# 2: 21
# 3: 66