我正在寻找一种优雅(且安全!)的方法来评估父框架中的修订呼叫。所谓“修改”,是指我以某种方式修改了该调用,使其引用父框架中未包含但其他框架中的内容。我猜可能还会有人说:“发送一些内容,但仅用于评估”。
下面的示例阐明了我想要的内容,该示例在某些情况下有效,但并非在所有情况下都有效。 update
函数(stats:::update.default
)使用eval
,我在weights
参数中添加了与评估所用环境不同的内容(res
)地点。因此,我使用了get("res", pos = -1L)
,希望它是引用res
所处环境的一种安全方法。对于以变量作为公式估算的模型,两种定义的方法均会失败:
mod <- lm(mpg ~ cyl, data = mtcars)
form <- mpg ~ cyl
mod2 <- lm(form, data = mtcars)
wls1 <- function(x) {
res <- residuals(x)^2 # example
result <- update(x, weights = 1/get("res", pos = -1L))
return(result)
}
wls2 <- function(x) {
res <- residuals(x)^2 # example
result <- update(x, weights = 1/res)
return(result)
}
wls3 <- function(x) {
data(ChickWeight)
ChickWeight$cyl <- ChickWeight$weight
ChickWeight$mpg <- ChickWeight$Time
result <- update(x, data = ChickWeight)
return(result)
}
wls1(mod) # works
wls1(mod2) # errors
wls2(mod) # works
wls2(mod2) # erros
wls3(mod) # works
wls3(mod2) # works
通常如何以安全的方式解决此问题?
我一直在寻找可以提供当前环境的函数(类似虚构的this.environment()
函数),因此请避免使用pos
参数,而应使用envir
的{{1}}(我知道可以创建我自己的临时环境,并将get
与之关联以使用类似res
的东西。
答案 0 :(得分:1)
我们可以通过为公式创建quote
d'语言'对象,然后更新模型的call
form <- quote(mpg ~ cyl)
wlsN <- function(x, formula) {
x$call$formula <- formula
res <- residuals(x)^2
update(x, weights = 1/res) # it is in the same environment. No need for get
}
wlsN(mod2, form)
#Call:
#lm(formula = mpg ~ cyl, data = mtcars, weights = 1/res)
#Coefficients:
#(Intercept) cyl
# 37.705 -2.841
-检查其他公式
form1 <- quote(disp ~ cyl + vs)
form2 <- quote(mpq ~ gear + carb)
mod1 <- lm(form1, data = mtcars)
mod2 <- lm(form2, data = mtcars)
wlsN(mod1, form1) # works
wlsN(mod2, form2) # works
答案 1 :(得分:1)
很难解决以下事实:R在data
或formula
的环境中寻找权重的值-在变量form
中您的例子是全球环境。
一种与akrun's答案相同的主题:
wls3 <- function(x) {
environment(x$call$formula) <- environment()
res <- residuals(x)^2
result <- update(x, weights=1/res)
}
我可以看到,在这种平常的解决方案中,如果使用x
的公式已经具有不包含该调用环境的环境(可能会错误使用该术语),该丑陋的处理方式将变得很难看到wls3()
。
另一种替代方法(不建议)是使用分配,例如
wls4 <- function(x) {
assign('res', residuals(x)^2, envir=environment(formula(x)))
result <- update(x, weights=1/res)
}
但这会带来意外的结果,就是将变量res
保留在全局环境中。