Skip to contents

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().