Home > Mobile >  Use lapply with formula to estimate lm with different weights
Use lapply with formula to estimate lm with different weights

Time:12-24

Related but slightly different to How to use lapply with a formula? and Calling update within a lapply within a function, why isn't it working?:

I am trying to estimate models with replicate weights. For correct standard errors, I need to estimate the same regression model with each version of the replicate weights. Since I need to estimate many different models and do not want to always write a seperate loop, I tried writing a function where I specify both data for the regression, regression formula and the data with the replicate weights. While the function works fine when specifying the formula explicitly inside the lapply() command in the function and not as a function input (function tryout below), as soon as I specify the regression formula as a function input (function tryout2 below), it breaks.

Here is a reproducible example:

library(tidyverse)
set.seed(123)
lm.dat <- data.frame(id=1:500,
                     x1=sample(1:100, replace=T, size=500),
                     x2=runif(n=500, min=0, max=20)) %>%
  mutate(y=0.2*x1 1.5*x2 rnorm(n=500, mean=0, sd=5))
repweights <- data.frame(id=1:500)
set.seed(123)
for (i in 1:200) {
  repweights[,i 1] <- runif(n=500, min=0, max=10)
  names(repweights)[i 1] <- paste0("hrwgt", i)
}

The two functions are defined as follows:

trythis <- function(data, weightsdata, weightsN){
  rep <- as.list(1:weightsN)
  res <- lapply(rep, function(x) lm(data=data, formula=y~x1 x2, weights=weightsdata[,x]))
  return(res)
}
results1 <- trythis(data=lm.dat, weightsdata=repweights[-1], weightsN=200)

trythis2 <- function(LMformula, data, weightsdata, weightsN){
  rep <- as.list(1:weightsN)
  res <- lapply(rep, function(x) lm(data=data, formula=LMformula, weights=weightsdata[,x]))
  return(res)
}

While the first function works, applying the second one results in an error:

trythis2(LMformula = y~x1 x2, data=lm.dat, weightsN=200, weightsdata = repweights[-1])
 Error in eval(extras, data, env) : object 'weightsdata' not found

CodePudding user response:

Formulas have an associated environment in which the referenced variables can be found. In your case, the formula you are passing has the environment of the calling frame. To access the variables within the function, you need to assign the formula to the local frame so it can find the correct variables:

trythis3 <- function(LMformula, data, weightsdata, weightsN){
  rep <- as.list(1:weightsN)
  res <- lapply(rep, function(x) {
    environment(LMformula) <- sys.frames()[[length(sys.frames())]]
    lm(data = data, formula = LMformula, weights = weightsdata[,x])
  })
  return(res)
}

trythis3(LMformula = y~x1 x2, data = lm.dat, weightsN = 200, 
         weightsdata = repweights[-1])

Which results in

#> [[1]]
#> 
#> Call:
#> lm(formula = LMformula, data = data, weights = weightsdata[, 
#>     x])
#> 
#> Coefficients:
#> (Intercept)           x1           x2  
#>      1.2932       0.1874       1.4308  
#> 
#> 
#> [[2]]
#> 
#> Call:
#> lm(formula = LMformula, data = data, weights = weightsdata[, 
#>     x])
#> 
#> Coefficients:
#> (Intercept)           x1           x2  
#>      1.2932       0.1874       1.4308  
#> 
#> 
#> [[3]]
#> 
#> Call:
#> lm(formula = LMformula, data = data, weights = weightsdata[, 
#>     x])
#> 
#> Coefficients:
#> (Intercept)           x1           x2  
#>      1.2932       0.1874       1.4308  

...etc
  • Related