2012-10-26 31 views
1

这里是我偶然发现了一个问题,是一种最小的例子:模型拟合函数和environemnts

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()) 

右侧这里mfmodel.frame一个构造巧妙呼叫的线路。我传递mysubset,但eval在基本环境中寻找它(我相信,但如果我错了,请纠正我),但没有找到它。我知道我可以使用lm.fit,但是有没有办法让mylmparent.framelm

回答

2

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

所以model.frame.default调用

eval(substitute(subset), data, env) 

这转化中data为“评估对象mysubset或者,如果不存在,在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