edd*_*ddi 18 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
Run Code Online (Sandbox Code Playgroud)
到底是怎么回事?我跑R 2.15.0和data.table 1.8.9.
Jos*_*ien 20
更新(eddi):从版本1.8.11开始,这已得到修复,并且.SD在表达式可以就地进行评估的情况下不需要,例如在OP中.由于目前存在.SD触发器构造已满.SD,这将在某些情况下导致更快的速度.
发生的事情是,调用eval()的处理方式与您在实现的代码中可能想象的不同[.data.table().具体来说,[.data.table()包含特殊的评估分支i和j以符号开头的表达式eval.当您将调用包装到调用eval内部时sum(),eval不再是已解析/替换表达式的第一个元素,并且会跳过特殊求值分支.
这是通过键入显示的怪物函数中的一些代码,它通过' -argument 传入的getAnywhere("[.data.table")调用特殊允许:eval()[.data.table()j
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]]
}
Run Code Online (Sandbox Code Playgroud)
作为一种变通方法,要么效仿在data.table常见问题1.6(PDF这里),或明确指出eval()对.SD,持有任何data.table你在(这里工作的列局部变量d).(有关.SD角色的更多解释,请参阅本答案的前几段).
d[, sum(eval(quoted_a, envir=.SD))]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6208 次 |
| 最近记录: |