expand.model.frame 在 lapply() 和 map() 中:与 fixest::feols 和 lm 的环境混淆

expand.model.frame within lapply() & map(): environment confusion with fixest::feols and lm

在使用 lmfixest::feols() 估计模型后,我正在尝试在 lapply() 中使用 expand.model.frame()

碰巧,我不断 运行 犯 fixest::feols 的错误,可能是因为我对环境感到困惑。

这是一个原型示例:

library(fixest) 
library(lfe)
library(estimatr)

fun <- function(object, clustid){
  
  fml <- object$call$formula
  if(!inherits(clustid, "formula")){
    clustid <- reformulate(clustid)
  }
  
  expand.model.frame(
    model = object, 
    extras = clustid, 
    #envir = environment(terms(object)),
    #envir = .GlobalEnv,
    na.expand = FALSE
  )
  
}

data(mtcars)

tmp_lm <- lapply(list(mtcars, mtcars), function(x){lm(mpg ~ qsec ,data = x)})
lapply(tmp_lm, function(x) fun(x, clustid = "carb"))

tmp_feols <- lapply(list(mtcars, mtcars), function(x){feols(mpg ~ qsec ,data = x)})
lapply(tmp_feols, function(x) fun(x, clustid = ~carb))
# Error in eval(model$call$data, envir) : object 'x' not found

tmp_felm <- lapply(list(mtcars, mtcars), function(x){felm(mpg ~ qsec ,data = x)})
lapply(tmp_felm, function(x) fun(x, clustid = ~carb))

tmp_estimatr <- lapply(list(mtcars, mtcars), function(x){lm_robust(mpg ~ qsec ,data = x)})
lapply(tmp_estimatr, function(x) fun(x, clustid = ~carb))

有人建议我如何调整 fun() 以便我不再 运行 出现以下错误吗?

我可以从您的注释代码中看出您一直在试验 envir 参数。你在这里走在正确的轨道上。 “fixest”class 包含一个名为 call_env 的对象,以确保您可以访问正确的评估环境。这意味着您需要根据传递的对象类型更改代码以获得正确的调用环境:

fun <- function(object, clustid){

  if(!inherits(clustid, "formula")){
    clustid <- reformulate(clustid)
  }
  
  e <- if(class(object) == "fixest") 
    object$call_env else environment(formula(object))
  
  expand.model.frame(
    model = object, 
    extras = clustid, 
    envir = e,
    na.expand = FALSE
  )
  
}

这允许:

data(mtcars)

tmp_feols <- lapply(list(mtcars, mtcars), function(x){feols(mpg ~ qsec ,data = x)})
lapply(tmp_feols, function(x) fun(x, clustid = ~carb))
#> [[1]]
#>                      mpg  qsec carb
#> Mazda RX4           21.0 16.46    4
#> Mazda RX4 Wag       21.0 17.02    4
#> Datsun 710          22.8 18.61    1
#> Hornet 4 Drive      21.4 19.44    1
#> Hornet Sportabout   18.7 17.02    2
#> Valiant             18.1 20.22    1
#> Duster 360          14.3 15.84    4
#> Merc 240D           24.4 20.00    2
#> Merc 230            22.8 22.90    2
#> Merc 280            19.2 18.30    4
#> Merc 280C           17.8 18.90    4
#> Merc 450SE          16.4 17.40    3
#> Merc 450SL          17.3 17.60    3
#> Merc 450SLC         15.2 18.00    3
#> Cadillac Fleetwood  10.4 17.98    4
#> Lincoln Continental 10.4 17.82    4
#> Chrysler Imperial   14.7 17.42    4
#> Fiat 128            32.4 19.47    1
#> Honda Civic         30.4 18.52    2
#> Toyota Corolla      33.9 19.90    1
#> Toyota Corona       21.5 20.01    1
#> Dodge Challenger    15.5 16.87    2
#> AMC Javelin         15.2 17.30    2
#> Camaro Z28          13.3 15.41    4
#> Pontiac Firebird    19.2 17.05    2
#> Fiat X1-9           27.3 18.90    1
#> Porsche 914-2       26.0 16.70    2
#> Lotus Europa        30.4 16.90    2
#> Ford Pantera L      15.8 14.50    4
#> Ferrari Dino        19.7 15.50    6
#> Maserati Bora       15.0 14.60    8
#> Volvo 142E          21.4 18.60    2
#> 
#> [[2]]
#>                      mpg  qsec carb
#> Mazda RX4           21.0 16.46    4
#> Mazda RX4 Wag       21.0 17.02    4
#> Datsun 710          22.8 18.61    1
#> Hornet 4 Drive      21.4 19.44    1
#> Hornet Sportabout   18.7 17.02    2
#> Valiant             18.1 20.22    1
#> Duster 360          14.3 15.84    4
#> Merc 240D           24.4 20.00    2
#> Merc 230            22.8 22.90    2
#> Merc 280            19.2 18.30    4
#> Merc 280C           17.8 18.90    4
#> Merc 450SE          16.4 17.40    3
#> Merc 450SL          17.3 17.60    3
#> Merc 450SLC         15.2 18.00    3
#> Cadillac Fleetwood  10.4 17.98    4
#> Lincoln Continental 10.4 17.82    4
#> Chrysler Imperial   14.7 17.42    4
#> Fiat 128            32.4 19.47    1
#> Honda Civic         30.4 18.52    2
#> Toyota Corolla      33.9 19.90    1
#> Toyota Corona       21.5 20.01    1
#> Dodge Challenger    15.5 16.87    2
#> AMC Javelin         15.2 17.30    2
#> Camaro Z28          13.3 15.41    4
#> Pontiac Firebird    19.2 17.05    2
#> Fiat X1-9           27.3 18.90    1
#> Porsche 914-2       26.0 16.70    2
#> Lotus Europa        30.4 16.90    2
#> Ford Pantera L      15.8 14.50    4
#> Ferrari Dino        19.7 15.50    6
#> Maserati Bora       15.0 14.60    8
#> Volvo 142E          21.4 18.60    2

但仍适用于 lm 版本。

当然,一种更复杂的方法是创建一个新的根据 class 调度的通用函数,而不是在一个大函数中处理 classes。

reprex package (v2.0.1)

于 2022-05-28 创建