From wdun|@p @end|ng |rom t|bco@com  Mon Aug 10 20:25:58 2020
From: wdun|@p @end|ng |rom t|bco@com (William Dunlap)
Date: Mon, 10 Aug 2020 11:25:58 -0700
Subject: [Rd] lm() takes weights from formula environment
In-Reply-To: <CC3F936D-DA0C-4681-A5F0-1A2C790147D3@win-vector.com>
References: <C57EF170-CC1D-426A-A659-3EA8B198EBC6@win-vector.com>
 <509f3b0d-d531-20cd-ea34-bd340d5be3b0@gmail.com>
 <CC3F936D-DA0C-4681-A5F0-1A2C790147D3@win-vector.com>
Message-ID: <CAF8bMcaiWzHH5Ui-gs3z6vjAyvC-GZqsiP5rbqPfWNwNb9yBHA@mail.gmail.com>

I assume you are concerned about this because the formula is defined
in one environment and the model fitting with weights occurs in a
separate function.  If that is the case then the model fitting
function can create a new environment, a child of the formula's
environment, add the weights variable to it, and make that the new
environment of the formula.  (This new environment is only an
attribute of the copy of the formula in the model fitting function: it
will not affect the formula outside of that function.)  E.g.,


d <- data.frame(x = 1:3, y = c(1, 2, 1))

lmWithWeightsBad <- function(formula, data, weights) {
    lm(formula, data=data, weights=weights)
}
coef(lmWithWeightsBad(y~x, data=d, weights=c(2,5,1))) # lm finds the
'weights' function in package:stats
#Error in model.frame.default(formula = formula, data = data, weights
= weights,  :
#  invalid type (closure) for variable '(weights)'

lmWithWeightsGood <- function(formula, data, weights) {
    envir <- new.env(parent = environment(formula))
    envir$weights <- weights
    environment(formula) <- envir
    lm(formula, data=data, weights=weights)
}
coef(lmWithWeightsGood(y~x, data=d, weights=c(2,5,1)))
#(Intercept)           x
#  1.2173913   0.2173913

Bill Dunlap
TIBCO Software
wdunlap tibco.com

On Mon, Aug 10, 2020 at 10:43 AM John Mount <jmount at win-vector.com> wrote:
>
> I wish I had started with "I am disappointed that lm() doesn't continue its search for weights into the calling environment" or "the fact that lm() looks only in the formula environment and data frame for weights doesn't seem consistent with how other values are treated."
>
> But I did not. So I do apologize for both that and for negative tone on my part.
>
>
> Simplified example:
>
> d <- data.frame(x = 1:3, y = c(1, 2, 1))
> w <- c(1, 10, 1)
> f <- as.formula(y ~ x)
> lm(f, data = d, weights = w)  # works
>
> # fails
> environment(f) <- baseenv()
> lm(f, data = d, weights = w)
> # Error in eval(extras, data, env) : object 'w' not found
>
>
> > On Aug 9, 2020, at 11:56 AM, Duncan Murdoch <murdoch.duncan at gmail.com> wrote:
> >
> > This is fairly clearly documented in ?lm:
> >
>
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel



[Rd] lm() takes weights from formula environment
William Dunlap