更新(eddi):从版本 1.8.11开始,这已得到修复,并且.SD
在可以就地评估表达式的情况下不需要,例如在 OP 中。由于当前存在.SD
触发器构建 full .SD
,因此在某些情况下这将导致更快的速度。
发生的情况是调用eval()
的处理方式与您在实现[.data.table()
. 具体来说,包含以符号 开头的和表达式的[.data.table()
特殊评估分支。当您将调用包装到调用内部时,不再是已解析/替换表达式的第一个元素,并且会跳过特殊评估分支。i
j
eval
eval
sum()
eval
这是通过键入显示的怪物函数getAnywhere("[.data.table")
中的一段代码,它特别允许eval()
通过[.data.table()
's j
-argument 传入的调用:
jsub = substitute(j)
...
# Skipping some lines
...
jsubl = as.list.default(jsub)
if (identical(jsubl[[1L]], quote(eval))) { # The test for eval 'on the outside'
jsub = eval(jsubl[[2L]], parent.frame(), parent.frame())
if (is.expression(jsub))
jsub = jsub[[1L]]
}
作为一种解决方法,要么遵循 data.table FAQ 1.6(此处为 pdf)中的示例,要么明确指向eval()
保存.SD
您正在操作的任何 data.table 列的局部变量(此处d
)。(有关 ' 角色的更多解释,请参阅此答案.SD
的前几段)。
d[, sum(eval(quoted_a, envir=.SD))]