这是我偶然发现的一个问题的最小例子:
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
,但是有没有办法让mylm
parent.frame
lm
内的环境变为现实?
答案 0 :(得分:2)
在这种情况下,您是对的,对model.frame
(实际上是model.frame.default
)的调用正在mysubset
中寻找.GlobalEnv
。但是,更好的概括是说它正在尝试评估传递给data
的对象中的各种对象,或者如果它们不在那里,则在您传递给formula
的环境中进行评估。它。那个环境是.GlobalEnv
。
所以model.frame.default
调用
eval(substitute(subset), data, env)
转换为“评估mysubset
中的对象data
,或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
应该能够找到{{1}}。