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))]