代码之家  ›  专栏  ›  技术社区  ›  Helix123

父帧和当前帧中的eval

r
  •  2
  • Helix123  · 技术社区  · 6 年前

    我在找一个优雅的(和安全的!)在父帧中计算已修改调用的方法。我的意思是,我修改了这个调用,使它指的不是父帧中包含的内容,而是另一帧中包含的内容。我想也有人会说:“发点东西上去,但只做评估”。

    下面的例子说明了我想要什么,它在某些情况下有效,但不是全部。这个 update 功能( stats:::update.default )用途 eval 我加上了 weights 与某事争论( res )这与评估所处的环境不同。所以我用 get("res", pos = -1L) 我希望这是一个安全的方法来指代环境 物件 住在里面。对于以变量作为公式估计的模型,两种定义的方法都失败:

    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 属于 get (我知道我可以创造自己的临时环境 物件 与之相关,使用类似 envir = my.eny ).

    2 回复  |  直到 6 年前
        1
  •  1
  •   akrun    6 年前

    我们可以通过创建 quote d“language”对象,然后更新 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
    
        2
  •  1
  •   stephematician    6 年前

    很难回避这样一个事实: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() .

    另一种选择(不推荐)是使用assign,例如。

    wls4 <- function(x) {
     assign('res', residuals(x)^2, envir=environment(formula(x)))
     result <- update(x, weights=1/res)
    }
    

    然而,这有一个意外的结果,即留下变量 res 在全球环境中。