R data.table中的求值和报价

R data.table中的求值和报价,r,data.table,R,Data.table,我错过了什么 d = data.table(a = 1:5) d[, a] # 1 2 3 4 5 d[, sum(a)] # 15 d[, eval(quote(a))] # 1 2 3 4 5 d[, sum(eval(quote(a)))] # 15 quoted_a = quote(a) d[, eval(quoted_a)] # 1 2 3 4 5 d[, sum(eval(quoted_a))]

我错过了什么

d = data.table(a = 1:5)

d[, a]                   # 1 2 3 4 5
d[, sum(a)]              # 15

d[, eval(quote(a))]      # 1 2 3 4 5
d[, sum(eval(quote(a)))] # 15

quoted_a = quote(a)
d[, eval(quoted_a)]      # 1 2 3 4 5
d[, sum(eval(quoted_a))] # Error in eval(expr, envir, enclos) : object 'a' not found
发生了什么事?我正在运行
R 2.15.0
数据。表1.8.9
更新(eddi):至此已被修复,并且在表达式可以就地计算的情况下,如在OP中,不需要
.SD
。因为当前存在
.SD
会触发完整
.SD
的构造,在某些情况下,这将导致更快的速度


所发生的事情是,对
eval()
的调用的处理方式与您在实现
[.data.table()
的代码中可能想象的不同。具体来说,
[.data.table())
包含以符号
eval
开头的
i
j
表达式的特殊求值分支。将对
eval的调用包装在对
sum()的调用中时
eval
不再是解析/替换表达式的第一个元素,并且跳过特殊求值分支

下面是monster函数中的代码位,通过键入
getAnywhere(“[.data.table”)
显示,该函数特别允许通过
[.data.table()
j
-参数传入对
eval()
的调用:

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()中的示例,或者明确地将
eval()
指向
.SD
,这是一个局部变量,用于保存您正在操作的任何data.table的列(此处为
d
)(有关
.SD
角色的更多说明,请参阅的前几段)


如果不使用
[.data.table
中的特殊情况,那么
quoted_a@eddi如何?使用正确的环境进行
eval
([this answer]n()可能有用(使用
sum(eval(quoted_a.SD))
将起作用……)@Arun——哦,我明白了。我想你只需要知道
.SD
在所有
I
j
表达式的评估中的核心作用。中的开场白应该清楚地说明为什么
.SD
是你想要的环境。我希望你不能通过调用
parent.frame()
找到这一点,因为
[.data.table
避开了R的一些典型范围规则。@Arun--你说得很有道理.data.table的强大是以用户为代价的,他们不得不构建一个完整的附加模型来说明它的神奇“真的”是如何发生的。我自己仍然处在学习曲线的陡峭部分;)尽管如此,我认为
data.table
不应该做任何破坏命令行中嵌套函数预期行为的事情。如果
regular_matrix[,sum(eval(quoted_a))]
“起作用,”然后
数据。table
未能这样做应该被视为一个bug。我今天遇到了这样一个问题;通过使用
quote(sum(a))
而不是
表达式(sum(a))
解决了。不知道这有什么关系。
d[, sum(eval(quoted_a, envir=.SD))]