嗨,当我偶然发现一些奇怪的行为时,我试图为R中的闭包准备一个小的演示代码。从使用Debug我意识到故障发生的原因是lm内部正在执行此行
mf <- eval(mf, parent.frame())
然而,它似乎打破了使用闭包编程的功能方面?
我错过了什么?这是我的小例子
# typical closure use
foo <- function(formula,data,weight=NULL) {
if(is.null(weight)) w=ones(nrow(data),1) else w=weight
force(w)
lm(formula,data,weights=w)
}
setup_something <- function(...) {
function(formula,data) {
foo(formula,data,...)
}
}
# set up our model function
model <- setup_something()
# set up our data
df = data.frame(x=seq(1,10,1),y=c(1:10)^1.5 * 3 + 2)
model(y~x,df)
eval(expr,envir,enclos)中的错误:object&#39; w&#39;找不到
答案 0 :(得分:1)
实例化一个公式(即x~y
)会捕获它所创建的环境,在您的情况下会发生parent.frame()
model()
的{{1}}。
如果您想要征服环境,可以在致电lm(formula,data,weights=w)
之前添加此行,明确地这样做:
# explicitly replace the formula's environment with the current frame
attr(formula,'.Environment') <- sys.frame(sys.nframe())
或隐含地将您对lm(formula,data,weights=w)
的调用替换为:
#instantiate a new forumla based on the existing formula
lm(stats::formula(unclass(formula)),data,weights=w)
作为背景,如果您在调用lm()
之前将以下行粘贴到mf <- eval(mf, parent.frame())
:
print(ls(envir=parent.frame()))
您将获得包含"w"
的对象名称列表。但是,由于这一行,正在评估的'mf'对象是stats::model.frame
:
mf[[1L]] <- quote(stats::model.frame)
和stats::model.frame
在公式的mf
属性的上下文中评估.Environment
的参数。