This came up recently in a discussion of lm() on the R-devel list. I'd assume the same issue applies to glm.

The problem is that the argument to weights is evaluated in the same way as arguments in the formula: first in data, then in the environment of the formula. The latter will eventually lead back to the global environment, but won't lead to the local evaluation frame in myglm().

The easiest solution is to add newweights to the data argument, but there are a few gotchas here.

First, if newweights is already a column in data, you'll mess things up. So be sure to use a name that can't be there. That's okay in your example.

The second problem is that a dot in the formula will cause problems, because it will try to include newweights as a predictor variable. It's possible to work around this, but it's probably better to use a more complicated solution instead: modify the formula environment so it starts with a small environment holding newweights. You don't want to add newweights directly to environment(formula), because that will have side effects outside your function.

This version of your function takes this more complicated approach:

 myglm <- function(formula, data, weights){
     ## this works
     print(glm(formula, data, family=gaussian(), weights))
     env <- new.env(parent = environment(formula))
     env$newweights <- rep(1, n)
     environment(formula) <- env

     glm(formula, data, family=gaussian(), weights=newweights)
 }

Duncan Murdoch


On 28/08/2020 11:32 a.m., John Smith wrote:
Dear R-help:

I am writing a function based on glm and would like some variations of
weights. In the code below, I couldn't understand why the second glm
function fails and don't know how to fix it:

Error in eval(extras, data, env) : object 'newweights' not found
  Calls: print ... eval -> <Anonymous> -> model.frame.default -> eval -> eval
  Execution halted

### R code
y <- rnorm(100)
  x <- rnorm(100)
  data <- data.frame(cbind(x, y))
  weights <- rep(1, 100)
  n <- 100
  myglm <- function(formula, data, weights){
      ## this works
      print(glm(formula, data, family=gaussian(), weights))
      ## this is not working
      newweights <- rep(1, n)
      glm(formula, data, family=gaussian(), weights=newweights)
  }
  myglm(y~., data, weights)

        [[alternative HTML version deleted]]

______________________________________________
R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.


______________________________________________
R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.

Reply via email to