在data.table中的eval和quote [英] eval and quote in data.table

查看:218
本文介绍了在data.table中的eval和quote的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这里缺少什么?

  d = data.table(a = 1:5)
b $ bd [,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))]#eval中的错误(expr,envir,enclos):object'a'not found

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

解决方案

UPDATE(eddi):截至版本1.8.11 已修复, .SD 在表达式可以就地评估的情况下不需要,如在OP中。由于当前存在 .SD 触发构建完整 .SD ,在某些情况下会导致更快的速度。






所做的是调用 eval()处理不同于你可能想象在实现 [。data.table()的代码。具体地, [。data.table()包含 i j 以符号 eval 开头的表达式。当你调用 sum() eval / code>不再是解析/替换表达式的第一个元素,并跳过特殊的求值分支。



这里是代码的位通过键入 getAnywhere([。data.table)显示的怪物函数对调用 eval()通过 [。data.table()' j - 提交:

  jsub = substitute(j)
...
跳过某些行
...
jsubl = as.list.default(jsub)
if(identical(jsubl [[1L]],quote(eval))){#在外部测试eval'
jsub = eval
if(is.expression(jsub))
jsub = jsub [[1L]]
} $ jsub [[2L]],parent.frame作为一种解决方法,请按照data.table中的示例常见问题1.6( //datatable.r-forge.r-project.org/datatable-faq.pdf\">此处),或明确指向 eval() .SD 是保存您正在操作的任何data.table列的局部变量(这里 d )。 (有关 .SD 的更多解释,请参阅 this answer )。

 code> d [,sum(eval(quoted_a,envir = .SD))] 


What am I missing here?

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

What is going on? I'm running R 2.15.0 and data.table 1.8.9.

解决方案

UPDATE (eddi): As of version 1.8.11 this has been fixed and .SD is not needed in cases where the expression can be evaluated in place, like in OP. Since currently presence of .SD triggers construction of full .SD, this will result in much faster speeds in some cases.


What's going on is that calls to eval() are treated differently than you likely imagine in the code that implements [.data.table(). Specifically, [.data.table() contains special evaluation branches for i and j expressions that begin with the symbol eval. When you wrap the call to eval inside of a call to sum(), eval is no longer the first element of the parsed/substituted expression, and the special evaluation branch is skipped.

Here is the bit of code in the monster function displayed by typing getAnywhere("[.data.table") that makes a special allowance for calls to eval() passed in via [.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]]
}

As a workaround, either follow the example in data.table FAQ 1.6 (pdf here), or explicitly point eval() towards .SD, the local variable that holds columns of whatever data.table you are operating on (here d). (For some more explanation of .SD's role, see the first few paragraphs of this answer).

d[, sum(eval(quoted_a, envir=.SD))]

这篇关于在data.table中的eval和quote的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆