1

这是我偶然发现的问题的一种最小示例:

mylm <- function(formula,data,subset=NULL){
  mysubset <- subset # some other clever manipulation
  lm(formula,data,mysubset)
}
mydata <- data.frame(x=rnorm(10),y=rnorm(10))
mylm(y~x,mydata) # this fails!

最后一行失败的原因是,它lm包含对 的调用model.frame,它在 中进行评估parent.frame,即lm包含代码行

mf <- eval(mf, parent.frame())

右侧mf的 是对 的巧妙构造的调用model.frame。我正在传递mysubset,但eval在基本环境中寻找它(我相信,但如果我错了请纠正我)并没有找到它。我知道我可能会使用lm.fit,但是有没有办法mylmparent.framefor里面制作环境lm

4

1 回答 1

2

在这种情况下,您是对的,对model.frame(实际上,model.frame.default)的调用mysubset正在.GlobalEnv. 但是,更好的概括是说它正在尝试评估传递给它的对象中的各种对象,data或者如果它们不存在,则在formula您传递给它的环境中评估各种对象。而那个环境就是.GlobalEnv.

所以model.frame.default打电话

eval(substitute(subset), data, env)

这转化为“评估对象mysubsetdata或,如果不存在,在env(即environment(formula))。

解决此问题的一种方法是在函数中重新创建公式,它将假定调用函数时创建的环境,其中mysubset存在:

mylm <- function(formula,data,subset=NULL){
  mysubset <- subset # some other clever manipulation
  lm(formula(deparse(formula)),data,subset=mysubset)
}

这样一来,model.frame.default应该就能找到了mysubset

于 2012-10-26T12:17:30.287 回答