考虑 data.table
中的以下列选择:
library(data.table) # using 1.8.7 from r-forge
dt <- data.table(a = 1:5, b = i <- rnorm(5), c = pnorm(i))
dt[, list(a,b)] #ok
为了简化我在具有许多和可变列的某些计算中的代码,我想用函数替换 list(a,b)
. 这是第一次尝试:
.ab <- function() quote(list(a, b))
dt[, eval(.ab())] #ok - same as above
理想情况下,我想获得从 [.data.table
通话摆脱 eval()
,并限制在的 .ab
而同时避免将数据表 dt
的功能 .ab
的定义 .
.eab <- function() eval(quote(list(a, b)))
dt[, .eab()]
# Error in eval(expr, envir, enclos) : object 'b' not found
发生了什么?怎么解决这个问题?
我怀疑's biting me is R'的词法范围以及 list(a,b)
的正确评估依赖于它在数据表 dt
的J环境中的事实 . 唉,我不知道如何获取对正确环境的引用,并将其用作 dt
中的 envir
或 enclos
参数 .
# .eab <- function() eval(quote(list(a, b)), envir = ?, enclos = ?)
EDIT
这种方法几乎可行:
.eab <- function(e) eval(quote(list(a, b)), envir = e)
dt[, .eab(dt)]
有两个缺点:(1)不返回列名,(2) dt
必须明确传递(我宁愿避免) . 我宁愿避免硬编码 dt
作为选择环境 . 这些考虑导致了另一种询问上述问题的方法:是否有一种编程方式从 .eab
中获取环境 dt
?
2 回答
警告,如果
[.data.table
的内部机器发生变化,这可能是不稳定的,缓慢的和/或可能会中断,但如果由于某种原因,'s no way around it, here'的功能似乎符合您的要求 . 如果你开始在[.data.table
中使用by
等其他选项,我也可以想象它不起作用 .同样,这有很好的理由颠覆/减少了很多代码 .
目的是创建表达式而不是函数 .
这种方法是分组数据快速的原因之一 . 表:在所有组的静态环境中评估
j
,因此可以避免每个函数调用的(小)开销 .但如果
.ab
由于某种原因确实需要成为一个函数,那么我们当然可以进一步思考 .