首页 > 解决方案 > 评估父框架和当前框架

问题描述

我正在寻找一种优雅(且安全!)的方式来评估父框架中修改后的调用。通过“修改”,我的意思是我修改了调用,使其引用不包含在父框架中但在另一个框架中的东西。我想也可以说:“发送一些东西,但仅用于评估”。

下面的示例阐明了我想要什么,它在某些情况下有效,但不是全部。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参数并使用envirof get(我知道我可以创建自己的临时环境并res与之关联以使用类似的东西envir = my.eny)。

标签: r

解决方案


很难解决这样一个事实,即 R 在其中一个data或环境中查找权重的值formula- 在您的示例中命名的变量的情况下form,它是全局环境。

与akrun 的回答主题相同的替代方案:

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但是,这会导致将变量留在全局环境中的意外后果。


推荐阅读