eval和data.table中的引用

时间:2013-04-09 22:41:10

标签: 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))] # Error in eval(expr, envir, enclos) : object 'a' not found

发生了什么事?我正在运行R 2.15.0data.table 1.8.9

1 个答案:

答案 0 :(得分:20)

UPDATE(eddi):version 1.8.11开始,这已得到修复,并且在表达式可以就地评估的情况下不需要.SD,例如在OP中。由于目前.SD的存在触发了完整.SD的构建,因此在某些情况下这将导致更快的速度。


正在进行的是对eval()的调用的处理方式与实现[.data.table()的代码中的调用方式不同。具体而言,[.data.table()包含以符号i开头的jeval表达式的特殊评估分支。当您在调用eval时将调用包装到sum()时,eval不再是已解析/替换表达式的第一个元素,并且会跳过特殊评估分支。

以下是通过输入getAnywhere("[.data.table")显示的怪物功能中的一些代码,它通过eval()的{​​{1}}传递给[.data.table()的来电特别许可 - 参数:

j

作为一种解决方法,请遵循data.table FAQ 1.6(pdf here)中的示例,或明确指向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]] } eval(),即保存任何数据列的局部变量。您正在操作的表格(此处为.SD)。 (有关d角色的更多解释,请参阅this answer的前几段。

.SD