考虑下面的虚拟示例:我想在循环中对data.table的一系列子集运行一个模型,并且想指定要迭代的确切行作为字符串(使用迭代器i
)
library(data.table)
DT <- data.table(X = runif(100), Y = runif(100))
f1 <- function(code) {
for (i in c(20,30,50)) {
eval(parse(text = code))
}
}
f1("lm(X ~ Y, data = DT[sample(.N, i)])")
显然,这不会返回任何输出,因为lm()
只是在后台执行了3次,实际的用例更加复杂,但这只是理论上的简化。
尽管如此,上面的例子还是很好用的,当函数f1
包含在包中,而不是在全局环境中定义时,问题就开始了,如果我没有弄错的话,在这个例子中f1
是在包的基env中定义的,那么从全局env调用f1
会出现错误:Error in [.data.frame(x, i) : undefined columns selected
.R可以正确地访问其基env中的迭代器i
和全局env中的迭代器DT
,但不能通过data.table方括号内的名称访问列。
我尝试过将envir
和enclos
参数设置为eval()
、baseenv()
、globalenv()
、parent.frame()
,但没有找到一个有效的组合。
例如,设置envir = globalenv()
似乎会导致访问DT
和i
,但不能从lm()
内的DT
中删除X
和Y
。设置envir = baseenv()
会丢失全局env,并且无法访问DT
(envir = baseenv(), enclos = globalenv()
不会改变它)。使用envir = list(baseenv(), globalenv())
会导致无法访问数据内部的任何内容。我想是table的方括号,错误消息:“[.data.frame(x,i)中的错误:选择了未定义的列”。
1条答案
按热度按时间lb3vh1jj1#
问题是变量是按字典顺序解析的,你可以试着传入表达式,并在求值前专门替换
i
的值,这样就不需要显式解析了。