R:不能同时使用'data.table'的环境、基环境和全局环境

bq3bfh9z  于 2023-02-17  发布在  其他
关注(0)|答案(1)|浏览(83)

考虑下面的虚拟示例:我想在循环中对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方括号内的名称访问列。
我尝试过将envirenclos参数设置为eval()baseenv()globalenv()parent.frame(),但没有找到一个有效的组合。
例如,设置envir = globalenv()似乎会导致访问DTi,但不能从lm()内的DT中删除XY。设置envir = baseenv()会丢失全局env,并且无法访问DTenvir = baseenv(), enclos = globalenv()不会改变它)。使用envir = list(baseenv(), globalenv())会导致无法访问数据内部的任何内容。我想是table的方括号,错误消息:“[.data.frame(x,i)中的错误:选择了未定义的列”。

lb3vh1jj

lb3vh1jj1#

问题是变量是按字典顺序解析的,你可以试着传入表达式,并在求值前专门替换i的值,这样就不需要显式解析了。

f1 <- function(code) {
  code <- substitute(code)
  
  for (i in c(20,30,50)) {
    cmd <- do.call("substitute", list(code, list(i=i)))
    print(cmd)
    result <- eval.parent(cmd)
    print(result)
  }
}

f1(lm(X ~ Y, data = DT[sample(.N, i)]))

相关问题