The two most widely used R
packages for difference-in-differences with staggered adoptions are did
(Callaway and Sant’Anna 2021) and etwfe
(Wooldridge 2021; implemented by Grant McDermott). If your panel is
already set up for either, fetwfe ships one-line
converters, so you can try the fused estimator without re-shaping your
data:
attgtToFetwfeDf() — for a panel formatted for
did::att_gt(),etwfeToFetwfeDf() — for a panel formatted for
etwfe::etwfe().Both take a long panel plus the column names you already use; each
returns a data frame with the time_var /
unit_var / treatment / response
columns that fetwfe() expects (building the absorbing-state
treatment indicator, dropping any units already treated in the first
period, and renaming the columns for you).
(The runnable examples below use the did package’s
mpdta dataset; install did to reproduce
them.)
diddid::att_gt() identifies a panel by outcome
(yname), time (tname), unit
(idname), and the first-treated cohort
(gname, 0 for never-treated units). The
canonical example is mpdta — county-level teen employment
and the minimum wage:
library(did)
data(mpdta)
head(mpdta[, c("countyreal", "year", "first.treat", "lemp")])
#> countyreal year first.treat lemp
#> 866 8001 2003 2007 8.461469
#> 841 8001 2004 2007 8.336870
#> 842 8001 2005 2007 8.340217
#> 819 8001 2006 2007 8.378161
#> 827 8001 2007 2007 8.487352
#> 937 8019 2003 2007 4.997212One line converts it, and then you fit fetwfe() as
usual:
library(fetwfe)
fdf <- attgtToFetwfeDf(
mpdta,
yname = "lemp",
tname = "year",
idname = "countyreal",
gname = "first.treat"
)
res <- fetwfe(
pdata = as.data.frame(fdf),
time_var = "time_var",
unit_var = "unit_var",
treatment = "treatment",
response = "response"
)
round(c(ATT = res$att_hat, SE = res$att_se), 4)
#> ATT SE
#> -0.0387 0.0123etwfeetwfe::etwfe() uses the same long-panel shape,
identified by yvar / tvar / idvar
/ gvar — where gvar is again the first-treated
period (0 for never-treated).
etwfeToFetwfeDf() is the parallel converter. Since
mpdta is already in that shape (first.treat is
the cohort variable), it converts identically:
fetwfe addsdid and etwfe both return the full set of
cohort-by-time (group-time) treatment effects. FETWFE starts from that
same saturated extended-two-way-fixed-effects model, and
then:
cohortStudy(), eventStudy()) and family-wise
simultaneous confidence bands (simultaneousCIs()).So the converters let you keep your existing data pipeline and add
the fused estimate alongside your did / etwfe
results. For the full workflow see the introductory vignette
(vignette("fetwfe")), and for the choice of fusion geometry
see “Choosing a fusion structure: cohort vs. event-study
penalties”
(vignette("fusion_structure_vignette")).