margins
margins copied to clipboard
Feature request: fixest support
The fixest package is a new-ish package for estimating OLS and GLM models with fixed effects. It would be lovely if margins supported it. There are already predict and vcov methods, which should make things easier for anyone who wants to take this up.
Ref: https://github.com/leeper/margins/issues/101, https://github.com/sgaure/lfe/issues/13 CC @grantmcdermott
Please specify whether your issue is about:
- [ ] a possible bug
- [ ] a question about package functionality
- [x] a suggested code or documentation change, improvement to the code, or feature request
Put your code here:
library(margins)
library(fixest)
x <- fixest::feols(mpg ~ hp * wt | cyl, data = mtcars)
margins(x)
#> Error in terms.default(model): no terms component nor attribute
head(predict(x))
#> [1] 22.47196 21.28068 25.94454 19.69230 17.08487 18.65003
vcov(x)
#> hp wt hp:wt
#> hp 1.641964e-04 0.0042546536 -2.454378e-05
#> wt 4.254654e-03 0.1706445284 -8.152661e-04
#> hp:wt -2.454378e-05 -0.0008152661 4.200967e-06
#> attr(,"type")
#> [1] "Clustered (cyl)"
Created on by the reprex package (v0.3.0)
Note that by default, fixest clusters by the fixed effects, and different clustering can be specified as arguments to summary or vcov. I'm not sure what approach margins wants to take here.
Ha, I was just tweeting about this package yesterday. It looks fantastic. I didn't realise it had a predict method, though. Even more good news.
Thanks, I'll look into this.
It looks reasonably easy to add support in the prediction package, though the fixest predict method does not appear to support an argument like se.fit (as in predict.lm for example).
See my branch of the prediction package below.
The other challenge is that the default find_terms method doesn't work on these objects. I'm sure there's a relatively easy workaround.
Do you all think there is serious interest in this package? Is it worth the time?
remotes::install_github('vincentarelbundock/prediction@fixest')
library(fixest)
library(margins)
library(prediction)
mod <- feols(mpg ~ hp * wt | cyl, data = mtcars)
head(prediction(mod))
#> mpg cyl disp hp drat wt qsec vs am gear carb fitted se.fitted
#> 1 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4 22.47196 NA
#> 2 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4 21.28068 NA
#> 3 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1 25.94454 NA
#> 4 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1 19.69230 NA
#> 5 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2 17.08487 NA
#> 6 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1 18.65003 NA
Created on 2020-05-29 by the reprex package (v0.3.0)
Nice @vincentarelbundock.
Do you all think there is serious interest in this package? Is it worth the time?
I can't speak to the effort involved, especially since I personally don't have time atm to commit to this. But I will say that fixest is fantastic IMO. Very flexible and insanely fast. It's honestly one of my favourite modeling packages.
FWIW a number of margin's already-supported model classes don't provide se.fit arguments. This was also something we discussed at equivalent lfe issue (referenced in @karldw's original post above). Getting predictive SEs for fixed-effect estimators like these is likely impossible without bootstrapping everything.
PS — I'm sure everyone on this thread knows this, but for interactions containing a minimum of one categorical variable we can at least use the x1 / x2 specification trick to obtain the full marginal effects directly in the model object (see here).
I looked into this a bit, @karldw, and it looks pretty easy to add fixest support. I saved a proof of concept to this Gist:
https://gist.github.com/vincentarelbundock/868556e242af647b1e6e74998a1c6364
I've only tried it with a simple linear model with one interaction, but it seems to work. You can play with it by running this code:
library(fixest)
library(margins)
library(prediction)
# Load new methods to add support for `fixest` objects
url <- 'https://gist.githubusercontent.com/vincentarelbundock/868556e242af647b1e6e74998a1c6364/raw/004296df1d7f9a4d314b416cc46796d764a09b71/margins.fixest.R'
source(url)
# Download data and fit model
url <- 'https://vincentarelbundock.github.io/Rdatasets/csv/plm/EmplUK.csv'
dat <- read.csv(url)
dat$capital <- as.logical(dat$capital < median(dat$capital))
mod <- feols(wage ~ emp * capital | firm + year, dat)
# strategy 1: margins
mfx <- margins(mod, at = list('capital' = c(TRUE, FALSE)))
mfx <- data.frame(summary(mfx))
mfx[mfx$factor == 'emp',]
#> factor capital AME SE z p lower upper
#> 3 emp FALSE -0.04627018 NA NA NA NA NA
#> 4 emp TRUE 0.14303633 NA NA NA NA NA
# strategy 2: grant's trick
tmp <- feols(wage ~ capital / emp | firm + year, dat)
coef(tmp)[2:3]
#> capitalFALSE:emp capitalTRUE:emp
#> -0.04627018 0.14303633
Created on 2020-05-30 by the reprex package (v0.3.0)
If @leeper is interested, I can push this the last mile by making separate PRs for the prediction and the margins packages.
@grantmcdermott I wasn't aware of that neat trick with / in the formula. Very cool. Thanks for posting the blog! FYI, I opened a PR to add glance and tidy methods to fixest. Those are already on modelsummary's latest Github, so you can make tables that will automatically detect and display which fixed effects are included. Example here: https://github.com/lrberge/fixest/issues/21
Still interested in this in 2021
Still interested in this in 2021
Still interested in 2022
Embarrassing, but my email puts github straight into spam so I didn't see this last year. Yes, I am!
From: Mike @.> Sent: Tuesday, October 25, 2022 10:47 PM To: leeper/margins @.> Cc: Isadora Borges Monroy @.>; Comment @.> Subject: Re: [leeper/margins] Feature request: fixest support (#128)
Still interested in this in 2021
Still interested in 2022
— Reply to this email directly, view it on GitHubhttps://can01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fleeper%2Fmargins%2Fissues%2F128%23issuecomment-1291424138&data=05%7C01%7Cisadora.borgesmonroy%40mail.mcgill.ca%7Cba0fba30142d4e483e5708dab6fc7c6d%7Ccd31967152e74a68afa9fcf8f89f09ea%7C0%7C0%7C638023492773787020%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=NyJpz%2FVcnAyLYmy4yOCMvFJooI%2BKiUO%2BTmSewuCzmEA%3D&reserved=0, or unsubscribehttps://can01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FAGNA6CMCJ3R3V47Y4AHR7WTWFCLVXANCNFSM4JKSVKMA&data=05%7C01%7Cisadora.borgesmonroy%40mail.mcgill.ca%7Cba0fba30142d4e483e5708dab6fc7c6d%7Ccd31967152e74a68afa9fcf8f89f09ea%7C0%7C0%7C638023492773787020%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=nM4Elje9DoVNNCU39rm%2Fm0bVBlhNhnkx4Bt1CGTK0UI%3D&reserved=0. You are receiving this because you commented.Message ID: @.***>
This package has been supplanted by the marginaleffects package. https://vincentarelbundock.github.io/marginaleffects/
Among other improvements (faster,. more features) it supports fixest objects.
@karldw I think we can close, since this package appears to be in stasis and there's a good, alternative solution.