fwildclusterboot and fixest
Source:vignettes/articles/Multiple-Estimations-with-fixest.Rmd
Multiple-Estimations-with-fixest.Rmd
library(fwildclusterboot)
library(fixest)
set.seed(34345)
dqrng::dqset.seed(123)
data(voters)
boottest()
supports multiple features of the advanced formula syntax of the fixest
package, as e.g. multiple estimations.
Variables created via ‘i()’
feols_fit <- feols(proposition_vote ~ i(treatment, ideology1) ,
data = voters
)
boot1 <- boottest(feols_fit,
B = 9999,
param = "treatment::0:ideology1",
clustid = "group_id1"
)
#> Warning: Please note that the seeding behavior for random number generation for
#> `boottest()` has changed with `fwildclusterboot` version 0.13.
#>
#> It will no longer be possible to exactly reproduce results produced by versions
#> lower than 0.13.
#>
#> If your prior results were produced under sufficiently many bootstrap
#> iterations, none of your conclusions will change. For more details about this
#> change, please read the notes in
#> [news.md](https://cran.r-project.org/web/packages/fwildclusterboot/news/news.html).
#> This warning is displayed once per session.
boot1
#> boottest.fixest(object = feols_fit, param = "treatment::0:ideology1",
#> B = 9999, clustid = "group_id1")
#>
#> p value: 0.0373
#> confidence interval: 0.0037 0.1083
#> test statistic 2.2696
Multiple Estimations
It is possible to loop through different regression specifications. For example, to run boottest()
over a fixest_multi
object created via the sw()
function:
feols_fits <- fixest::feols(
proposition_vote ~ treatment | sw(Q1_immigration, Q2_defense),
data = voters
)
boot2 <- lapply(
feols_fits,
\(x) boottest(
x,
B = 999,
param = "treatment",
clustid = "group_id1")
)
boot2
#> $`fixef: Q1_immigration`
#> boottest.fixest(object = x, param = "treatment", B = 999, clustid = "group_id1")
#>
#> p value: 0
#> confidence interval: 0.0362 0.1138
#> test statistic 3.8804
#>
#> $`fixef: Q2_defense`
#> boottest.fixest(object = x, param = "treatment", B = 999, clustid = "group_id1")
#>
#> p value: 0
#> confidence interval: 0.0437 0.1359
#> test statistic 3.9637
Similarly, it is possible to loop over objects of fixest_multi
created by subset
functionality:
voters$split <- sample(1:2, nrow(voters), TRUE)
feols_fits <- fixest::feols(
proposition_vote ~ treatment,
split = ~split,
data = voters
)
boot3 <- lapply(
feols_fits,
\(x) boottest(
x,
B = 999,
param = "treatment",
clustid = "group_id1"
)
)
boot3
#> $`sample.var: split; sample: 1`
#> boottest.fixest(object = x, param = "treatment", B = 999, clustid = "group_id1")
#>
#> p value: 0.044
#> confidence interval: 0.0037 0.1412
#> test statistic 2.1519
#>
#> $`sample.var: split; sample: 2`
#> boottest.fixest(object = x, param = "treatment", B = 999, clustid = "group_id1")
#>
#> p value: 0.009
#> confidence interval: 0.0286 0.184
#> test statistic 2.8926
And of course it is also possible to combine multiple “syntactic sugar” features of fixest
:
feols_fits <- fixest::feols(
proposition_vote ~ treatment | sw(Q1_immigration, Q2_defense),
split = ~split,
data = voters
)
boot4 <- lapply(
feols_fits,
\(x) boottest(
x,
B = 999,
param = "treatment",
clustid = "group_id1"
)
)
boot4
#> $`sample.var: split; sample: 1; fixef: Q1_immigration`
#> boottest.fixest(object = x, param = "treatment", B = 999, clustid = "group_id1")
#>
#> p value: 0.01
#> confidence interval: 0.0243 0.136
#> test statistic 2.9286
#>
#> $`sample.var: split; sample: 1; fixef: Q2_defense`
#> boottest.fixest(object = x, param = "treatment", B = 999, clustid = "group_id1")
#>
#> p value: 0.028
#> confidence interval: 0.0096 0.151
#> test statistic 2.3848
#>
#> $`sample.var: split; sample: 2; fixef: Q1_immigration`
#> boottest.fixest(object = x, param = "treatment", B = 999, clustid = "group_id1")
#>
#> p value: 0.016
#> confidence interval: 0.0161 0.1459
#> test statistic 2.5125
#>
#> $`sample.var: split; sample: 2; fixef: Q2_defense`
#> boottest.fixest(object = x, param = "treatment", B = 999, clustid = "group_id1")
#>
#> p value: 0.001
#> confidence interval: 0.0443 0.1801
#> test statistic 3.2502
What currently is not supported
As a rule of thumb, every transformation of fixed effects is not supported. This includes interaction via ^
and varying slopes syntax via var1[var2]
. If you try this, you should receive an error message, and if not, please open an issue on github =) .
Fixed effect interactions via ^
lead to an error. Fixing this is on my backlog but currently not highest priortiy. Send me a message if this causes you large headaches!
feols_fit2 <- feols(proposition_vote ~ treatment | Q1_immigration^Q2_defense,
data = voters
)
# leads to an error
boot1 <- boottest(feols_fit2,
B = 9999,
param = "treatment",
clustid = "group_id1"
)
# Error in `check_boottest_args_plus()` at fwildclusterboot/R/boottest_fixest.R:514:2:
# ! Advanced formula notation in fixest / fixest via ^ to interact
# fixed effects is currently not supported in boottest().
Relatedly, varying slopes fixed effects syntax is not supported:
feols_fit3 <- feols(proposition_vote ~ treatment | Q1_immigration[log_income],
data = voters
)
# leads to an error
boot <- boottest(feols_fit3,
B = 9999,
param = "treatment",
clustid = "group_id1"
)
# Error in `check_boottest_args_plus()` at fwildclusterboot/R/boottest_fixest.R:514:2:
# ! Varying slopes in fixest / fixest via [] to interact
# fixed effects is currently not supported in boottest().