expand.model.frame 在 lapply() 和 map() 中:与 fixest::feols 和 lm 的环境混淆
expand.model.frame within lapply() & map(): environment confusion with fixest::feols and lm
在使用 lm
和 fixest::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 创建
在使用 lm
和 fixest::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 创建