update() inside a function only searches the global environment?

前端 未结 2 2099
半阙折子戏
半阙折子戏 2020-12-16 21:09

I tried to write a wrapper function to do likelihood ratio tests in batches. I tried to include update() to update the initial model. However, it seems that instead of looki

相关标签:
2条回答
  • 2020-12-16 21:22

    I've been bitten by this behaviour before too, so I wrote my own version of update. It evaluates everything in the environment of the formula, so it should be fairly robust.

    my_update <- function(mod, formula = NULL, data = NULL) {
      call <- getCall(mod)
      if (is.null(call)) {
        stop("Model object does not support updating (no call)", call. = FALSE)
      }
      term <- terms(mod)
      if (is.null(term)) {
        stop("Model object does not support updating (no terms)", call. = FALSE)
      }
    
      if (!is.null(data)) call$data <- data
      if (!is.null(formula)) call$formula <- update.formula(call$formula, formula)
      env <- attr(term, ".Environment")
    
      eval(call, env, parent.frame())
    }
    
    library(nlme4)
    
    fake <- data.frame(
      subj = rep(1:5, 4), 
      factor1 = rep(LETTERS[c(1,2,1,2)], each = 5), 
      factor2 = rep(letters[1:2], each = 10), 
      data = sort(rlnorm(20)))
    
    foo <- function() {
      temp <- fake
      model1 <- lmer(data ~ factor1 * factor2 + (1 | subj), fake)
      model1a <- my_update(model1, ~ . - factor1:factor2)
      model1a
    }
    foo()
    
    0 讨论(0)
  • 2020-12-16 21:29

    Although I really like @Hadley's answer (and will likely use that function myself), you can also specify a data argument in the update function. (Here, I assumed you wanted to pass temp to your models.)

    model1a <- update(model1, ~.-factor1:factor2, data = temp)
    

    EDIT

    If you're looking to compare models with anova, update will mung up the name of the data argument and "trick" anova into believing that the two models were fit using two different datasets. Updating only the formula and creating a new model will avoid this:

    foo <- function(){
                      temp <- fake
                      model1 <- lmer(data~factor1*factor2 + (1 |subj), data=temp)
                      newForm <- update.formula(formula(model1), ~.-factor1:factor2)
                      model1a <- lmer(newForm, data=temp)
                      anova(model1, model1a)
                }
    
    0 讨论(0)
提交回复
热议问题