考虑 a 中的以下列选择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
理想情况下,我想摆脱eval()
调用[.data.table
并将其限制在 while 的定义中,.ab
同时避免将数据表传递dt
给函数.ab
。
.eab <- function() eval(quote(list(a, b)))
dt[, .eab()]
# Error in eval(expr, envir, enclos) : object 'b' not found
发生了什么?如何解决这个问题?
我怀疑困扰我的是 R 的词法作用域以及正确评估list(a,b)
依赖于它在数据表的J环境中的事实dt
。唉,我不知道如何获取对正确环境的引用并将envir
其enclos
用作dt
.
# .eab <- function() eval(quote(list(a, b)), envir = ?, enclos = ?)
编辑
这种方法几乎有效:
.eab <- function(e) eval(quote(list(a, b)), envir = e)
dt[, .eab(dt)]
有两个缺点:(1)不返回列名,(2)dt
必须显式传递(我宁愿避免)。我也宁愿避免硬编码dt
作为选择环境。这些考虑导致了提出上述问题的另一种方式:是否有一种dt
从内部获取环境的程序化方式.eab
?