R 在父帧和当前帧中求值
我正在寻找一种优雅(而且安全!)的方法来评估父框架中修改后的调用。我所说的“修改”是指我修改了调用,使其引用的内容不包含在父框架中,而是包含在另一个框架中。我想人们也可以说:“发送一些东西,但仅用于评估” 下面的例子阐明了我想要什么,它在某些情况下有效,但不是所有情况下都有效。R 在父帧和当前帧中求值,r,R,我正在寻找一种优雅(而且安全!)的方法来评估父框架中修改后的调用。我所说的“修改”是指我修改了调用,使其引用的内容不包含在父框架中,而是包含在另一个框架中。我想人们也可以说:“发送一些东西,但仅用于评估” 下面的例子阐明了我想要什么,它在某些情况下有效,但不是所有情况下都有效。update函数(stats:::update.default)使用eval,我添加了weights参数,其中包含与评估发生时不在同一环境中的内容(res)。因此,我使用了get(“res”,pos=-1L),我希望这是一
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
mod我们可以通过为公式创建一个quote
d'language'对象,然后更新模型的调用来实现这一点
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
form很难绕过这样一个事实:R在数据
或公式
的环境中查找权重值,在您的示例中,对于名为form
的变量,这就是全局环境
与答案主题相同的备选方案:
但是,这会导致将变量res
留在全局环境中的意外后果。当然。然而,这让人感觉在围绕着它工作。我正在寻找一些更一般的东西(我不想检查哪些元素是令人不快的…)。我的原始代码不应该工作吗?@Helix123它是通用的。我不是在检查元素,只是在调用中替换公式。如果您在不更改的情况下检查调用
,它将是表单
,而不是mpg~cyl
,这将创建issue@Helix123无论如何,您的所有示例都只需将公式作为参数传递即可\n感谢Arun的提示支持。我想我在问题的第一段表达了我感兴趣的内容。试着调试一下(model.frame),看看它是如何确定环境来评估中的额外参数的。我认为wls4
更重要的缺点是,在全局环境中存在的名为的变量会被覆盖(当然,你可以通过测试找到一个不同的名称,但可以循环使用,例如res1,…resN)。我想知道,在解决方案功能get(“res”)中,是否没有办法更直接地(通过绝对地址)寻址环境,envir=
,这样eval
就知道在哪里可以找到res
。哦,哇,这些天来,似乎在r-devel上独立出现了同样的问题:-让我们看看会发生什么。r-devel上也出现了这样的问题,这并不奇怪,但时间是什么!我想另一个方法是在wls
中添加一个参数,这需要一个用户希望在中放置残差-因此用户可以控制表单
和res
的环境。关于获取
,您仍然需要提供(现在作为获取
的参数)在表单
环境中可见的内容-因此您遇到了与以前相同的问题(我完全建议您尝试debug(model.frame)
,看看您的示例会出现什么问题)。旅途愉快!
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
wls3 <- function(x) {
environment(x$call$formula) <- environment()
res <- residuals(x)^2
result <- update(x, weights=1/res)
}
wls4 <- function(x) {
assign('res', residuals(x)^2, envir=environment(formula(x)))
result <- update(x, weights=1/res)
}