Hi and thank you for this!
I hacked into your code to create one example that applies all estimators on the same dataset, creating the dataset only once.
This can be super-useful!
/* Install*/
if 1==1{
ssc install ftools, replace
ssc install reghdfe, replace
ssc install event_plot, replace
/* 0: TWFE */
xtreg Y D t, fe /* */
xtreg Y D i.t, fe /* */
reghdfe Y D, absorb(id t) /* */
reg Y D i.t i.id /* */
/* 0: bacondecomp */
ssc install bacondecomp
bacondecomp Y D, ddetail
ereturn list
display e(dd_avg_e)*e(wt_sum_e) + e(dd_avg_l)*e(wt_sum_l) + e(dd_avg_u)*e(wt_sum_u)
/* 1: did_multiplegt */
ssc install did_multiplegt, replace
help did_multiplegt
did_multiplegt Y G T D
/* 2: csdid */
ssc install csdid, replace
ssc install drdid, replace
help csdid
csdid Y [ind vars], [ivar(varname)] time(varname) gvar(varname) [options]
csdid Y, ivar(id) time(t) gvar(gvar) notyet
estat event, window(-10 10) estore(cs)
event_plot cs, default_look graph_opt(xtitle("t") ytitle("ATT") ///
title("csdid") xlabel(-10(1)10)) stub_lag(Tp#) stub_lead(Tm#) together
/* 3: did_imputation */
ssc install did_imputation, replace
help did_imputation
did_imputation Y i t first_treat
/* 4: eventstudyinteract (Sun and Abraham 2020) */
*ssc install eventstudyinteract, replace
net install github, from("https://haghish.github.io/github/")
github install lsun20/eventstudyinteract
ssc install eventstudyweights , replace
help eventstudyinteract
eventstudyinteract Y *lags* *leads*, vce(cluster *var*) absorb(*i* *t*) cohort(first_treat) control_cohort(*variable*)
/* 5: stackedev (Cengiz, Dube, Lindner, Zipperer 2019) */
ssc install stackedev, replace
help stackedev
stackedev Y F* L* , cohort(first_treat) time(t) never_treat(no_treat) unit_fe(i) clust_unit(i)
/* 6: did2s (Gardner 2021) */
ssc install did2s, replace
help did2s
did2s Y, first_stage(i t) second_stage(*leads* *lags*) treat_var(*D*) cluster(*var*)
}
/* MAKE DATA: id t Y D cohort effect first_treat rel_time */
if 1==1{
clear
local units = 30
local start = 1
local end = 60
local time = `end' - `start' + 1
local obsv = `units' * `time'
set obs `obsv'
egen id = seq(), b(`time')
egen t = seq(), f(`start') t(`end')
sort id t
xtset id t
set seed 20211222
gen Y = 0 // outcome variable
gen D = 0 // intervention variable
gen cohort = . // treatment cohort
gen effect = . // treatment effect size
gen first_treat = . // when the treatment happens for each cohort
gen rel_time = . // time - first_treat
levelsof id, local(lvls)
foreach x of local lvls {
local chrt = runiformint(0,5)
replace cohort = `chrt' if id==`x'
}
levelsof cohort , local(lvls)
foreach x of local lvls {
local eff = runiformint(2,10)
replace effect = `eff' if cohort==`x'
local timing = runiformint(`start',`end' + 20) //
replace first_treat = `timing' if cohort==`x'
replace first_treat = . if first_treat > `end'
replace D = 1 if cohort==`x' & t>= `timing'
}
replace rel_time = t - first_treat
replace Y = id + t + cond(D==1, effect * rel_time, 0) + rnormal()
}
xtline Y, overlay legend(off)
/* TWFE */
if 1==1{
xtreg Y D t, fe /* 73.11 (3.9 */
xtreg Y D i.t, fe /* 77.59 (3.7) */
reghdfe Y D, absorb(id t) /* 77.59 (3.7) */
reg Y D i.t i.id /* 77.59 (3.7) */
}
/* GB: bacondecomp */
if 1==1{
bacondecomp Y D, ddetail
Diff-in-diff estimate: 77.591
DD Comparison Weight Avg DD Est
-------------------------------------------------
Earlier T vs. Later C 0.333 88.197
Later T vs. Earlier C 0.150 -93.692
T vs. Never treated 0.517 120.411
-------------------------------------------------
}
/* CD: did_multiplegt */
if 1==1{
did_multiplegt Y id t D, robust_dynamic cluster(id) breps(20)
| Estimate SE LB CI UB CI N Switchers
-------------+------------------------------------------------------------------
Effect_0 | -.0608394 .3547955 -.7562387 .6345598 78 23
did_multiplegt Y id t D, robust_dynamic dynamic(10) placebo(10) breps(20) cluster(id)
| Estimate SE LB CI UB CI N Switchers
-------------+------------------------------------------------------------------
Effect_0 | -.0608394 .353078 -.7528723 .6311935 78 23
Effect_1 | 8.49767 .4331132 7.648768 9.346572 78 23
Effect_2 | 17.64773 .4398626 16.7856 18.50986 78 23
Effect_3 | 25.9377 .7664737 24.43541 27.43998 78 23
Effect_4 | 34.62362 1.190048 32.29113 36.95611 75 23
Effect_5 | 42.85682 1.51316 39.89103 45.82262 64 19
Effect_6 | 51.93103 1.832343 48.33964 55.52242 64 19
Effect_7 | 60.13327 2.396984 55.43518 64.83136 64 19
Effect_8 | 68.82446 2.625587 63.67831 73.97061 64 19
Effect_9 | 77.30792 2.857373 71.70747 82.90837 64 19
Effect_10 | 85.78878 3.330466 79.26107 92.31649 55 19
Placebo_1 | -.1308918 .4742009 -1.060326 .798542 78 23
Placebo_2 | .1944381 .3786051 -.5476278 .936504 78 23
Placebo_3 | .0639963 .4074087 -.7345248 .8625173 78 23
Placebo_4 | .2572878 .4032822 -.5331453 1.047721 78 23
Placebo_5 | .0679468 .3813181 -.6794366 .8153302 78 23
Placebo_6 | -.082143 .3154546 -.700434 .5361479 78 23
Placebo_7 | -.271289 .3794009 -1.014915 .4723367 78 23
Placebo_8 | .0338621 .3864144 -.7235101 .7912343 78 23
Placebo_9 | -.1010115 .3029614 -.6948159 .4927929 78 23
Placebo_10 | .3842823 .3259317 -.2545438 1.023108 78 23
event_plot e(estimates)#e(variances), default_look ///
graph_opt(xtitle("Periods since the event") ytitle("Average causal effect") ///
title("did_multiplegt") xlabel(-10(1)10)) stub_lag(Effect_#) stub_lead(Placebo_#) together
}
/* CS: csdid: gvar=first_treat value for treated, =0 for not treated*/
if 1==1{
gen gvar = first_treat
recode gvar (. = 0)
csdid Y, ivar(id) time(t) gvar(gvar) notyet
/*Giant output of ATTs for each treated group*/
estat event, window(-10 10) estore(cs) /* Event study w/ 10-leads/10-lags*/
ATT by Periods Before and After treatment
Event Study:Dynamic effects
------------------------------------------------------------------------------
| Coef. Std. Err. z P>|z| [95% Conf. Interval]
-------------+----------------------------------------------------------------
Pre_avg | .0416478 .0426553 0.98 0.329 -.041955 .1252506
Post_avg | 43.04438 1.193983 36.05 0.000 40.70422 45.38454
Tm10 | .3842823 .3615112 1.06 0.288 -.3242667 1.092831
Tm9 | -.1010115 .308461 -0.33 0.743 -.7055839 .5035609
Tm8 | .0338621 .3130682 0.11 0.914 -.5797404 .6474646
Tm7 | -.271289 .3434149 -0.79 0.430 -.9443698 .4017918
Tm6 | -.082143 .3231954 -0.25 0.799 -.7155943 .5513083
Tm5 | .0679468 .3355773 0.20 0.840 -.5897727 .7256663
Tm4 | .2572878 .3222909 0.80 0.425 -.3743907 .8889663
Tm3 | .0639963 .4214074 0.15 0.879 -.7619471 .8899396
Tm2 | .1944381 .3707239 0.52 0.600 -.5321673 .9210435
Tm1 | -.1308918 .4307277 -0.30 0.761 -.9751027 .713319
Tp0 | -.0608394 .3220462 -0.19 0.850 -.6920383 .5703595
Tp1 | 8.49767 .3964781 21.43 0.000 7.720587 9.274753
Tp2 | 17.64773 .4650298 37.95 0.000 16.73629 18.55917
Tp3 | 25.9377 .5978201 43.39 0.000 24.76599 27.1094
Tp4 | 34.62362 .9250424 37.43 0.000 32.81057 36.43667
Tp5 | 42.85682 1.223002 35.04 0.000 40.45978 45.25386
Tp6 | 51.93103 1.529193 33.96 0.000 48.93387 54.92819
Tp7 | 60.13327 1.804358 33.33 0.000 56.59679 63.66975
Tp8 | 68.82446 1.982765 34.71 0.000 64.93831 72.71061
Tp9 | 77.30792 2.264938 34.13 0.000 72.86872 81.74712
Tp10 | 85.78878 2.61102 32.86 0.000 80.67128 90.90629
------------------------------------------------------------------------------
event_plot cs, default_look graph_opt(xtitle("Periods since the event") ytitle("Average effect") ///
title("csdid") xlabel(-10(1)10)) stub_lag(Tp#) stub_lead(Tm#) together
}
/* BJS: did_imputation */
if 1==1{
did_imputation Y i t first_treat, horizons(0/10) pretrend(10)
did_imputation Y i t first_treat, horizons(0/10) pretrend(10) minn(0) /* correct*/
Number of obs = 1,438
------------------------------------------------------------------------------
Y | Coef. Std. Err. z P>|z| [95% Conf. Interval]
-------------+----------------------------------------------------------------
tau0 | .0787163 .2677837 0.29 0.769 -.44613 .6035626
tau1 | 8.637227 .2815466 30.68 0.000 8.085406 9.189048
tau2 | 17.78728 .2329168 76.37 0.000 17.33078 18.24379
tau3 | 26.07725 .2293303 113.71 0.000 25.62777 26.52673
tau4 | 34.76562 .2815757 123.47 0.000 34.21374 35.3175
tau5 | 42.93274 .2848896 150.70 0.000 42.37437 43.49111
tau6 | 52.00695 .2787334 186.58 0.000 51.46064 52.55326
tau7 | 60.20919 .2526519 238.31 0.000 59.714 60.70438
tau8 | 68.90038 .2317813 297.26 0.000 68.4461 69.35466
tau9 | 77.38383 .2652313 291.76 0.000 76.86399 77.90368
tau10 | 85.83142 .309541 277.29 0.000 85.22473 86.43811
pre1 | .1206052 .2867599 0.42 0.674 -.4414338 .6826443
pre2 | .2116369 .3322261 0.64 0.524 -.4395143 .8627881
pre3 | .0601094 .28101 0.21 0.831 -.49066 .6108789
pre4 | .0568874 .2810549 0.20 0.840 -.4939701 .6077449
pre5 | -.2050823 .2643479 -0.78 0.438 -.7231945 .31303
pre6 | -.3225205 .2344532 -1.38 0.169 -.7820403 .1369993
pre7 | -.2239894 .2512797 -0.89 0.373 -.7164885 .2685097
pre8 | .052194 .2244509 0.23 0.816 -.3877217 .4921096
pre9 | .0285485 .2359939 0.12 0.904 -.433991 .4910879
pre10 | .0962904 .2315309 0.42 0.677 -.3575018 .5500827
------------------------------------------------------------------------------
event_plot cs, default_look graph_opt(xtitle("Periods since the event") ytitle("Average effect") ///
title("csdid") xlabel(-10(1)10)) stub_lag(Tp#) stub_lead(Tm#) together
}
/* eventstudyinteract (Sun and Abraham 2020) */
/*PROBLEM eventstudyinteract: 10 leads/lags & drop 1st lead:*/
if 1==1{
// leads
cap drop F_*
forval x = 2/10 { // drop the first lead
gen F_`x' = rel_time == -`x'
}
//lags
cap drop L_*
forval x = 0/10 {
gen L_`x' = rel_time == `x'
}
gen never_treat = first_treat==.
sum first_treat
gen last_cohort = first_treat==r(max) // dummy for the latest- or never-treated cohort
eventstudyinteract Y L_* F_*, vce(cluster id) absorb(id t) cohort(first_treat) control_cohort(never_treat)
Y | Coef. Std. Err. t P>|t| [95% Conf. Interval]
-------------+----------------------------------------------------------------
L_0 | -82.83641 9.395219 -8.82 0.000 -102.0518 -63.62103
L_1 | -72.09706 9.606305 -7.51 0.000 -91.74416 -52.44996
L_2 | -66.28563 9.387735 -7.06 0.000 -85.4857 -47.08555
L_3 | -59.53088 9.654911 -6.17 0.000 -79.27739 -39.78437
L_4 | -57.36642 9.575378 -5.99 0.000 -76.95027 -37.78257
L_5 | -39.75675 9.060562 -4.39 0.000 -58.28768 -21.22581
L_6 | -33.14397 8.537269 -3.88 0.001 -50.60465 -15.6833
L_7 | -27.89437 7.86436 -3.55 0.001 -43.9788 -11.80995
L_8 | -23.26935 7.097292 -3.28 0.003 -37.78494 -8.753756
L_9 | -9.696573 5.205239 -1.86 0.073 -20.34248 .9493362
L_10 | -11.75181 7.008037 -1.68 0.104 -26.08486 2.581231
F_2 | -74.56978 7.895172 -9.44 0.000 -90.71722 -58.42234
F_3 | -73.05913 7.860883 -9.29 0.000 -89.13645 -56.98182
F_4 | -73.13007 7.492343 -9.76 0.000 -88.45363 -57.8065
F_5 | -69.47478 8.197212 -8.48 0.000 -86.23996 -52.7096
F_6 | -71.25639 7.298475 -9.76 0.000 -86.18344 -56.32933
F_7 | -67.85099 7.697344 -8.81 0.000 -83.59383 -52.10815
F_8 | -66.67338 7.647583 -8.72 0.000 -82.31445 -51.03232
F_9 | -65.677 7.560869 -8.69 0.000 -81.14071 -50.21328
F_10 | -64.7154 7.532503 -8.59 0.000 -80.1211 -49.3097
event_plot e(b_iw)#e(V_iw), default_look graph_opt(xtitle("Periods since the event") ytitle("Average effect") xlabel(-10(1)10) ///
title("eventstudyinteract")) stub_lag(L_#) stub_lead(F_#) together
sum first_treat if last_cohort==1
eventstudyinteract Y L_* F_* if t<`r(max)' & first_treat!=., vce(cluster id) absorb(id t) cohort(first_treat) control_cohort(last_cohort)
event_plot e(b_iw)#e(V_iw), default_look graph_opt(xtitle("Periods since the event") ytitle("Average effect") xlabel(-10(1)10) ///
title("eventstudyinteract")) stub_lag(L_#) stub_lead(F_#) together
}
/* stackedev (Cengiz, Dube, Lindner, Zipperer 2019) */
/* PROBLEM stackedev: generate 10 leads and lags & no_treat var*/
if 1==1{
gen no_treat = first_treat==.
// leads
cap drop F_*
forval x = 1/10 { // drop the first lead
gen F_`x' = rel_time == -`x'
replace F_`x' = 0 if no_treat==1
}
//lags
cap drop L_*
forval x = 0/10 {
gen L_`x' = rel_time == `x'
replace L_`x' = 0 if no_treat==1
}
ren F_1 ref // reference year
stackedev Y F_* L_* ref, cohort(first_treat) time(t) never_treat(no_treat) unit_fe(id) clust_unit(id)
event_plot, default_look graph_opt(xtitle("Periods since the event") ytitle("Average effect") xlabel(-10(1)10) ///
title("stackedev")) stub_lag(L_#) stub_lead(F_#) together
}
/* did2s (Gardner 2021) */
/*did2s: 10 leads/lags & drop 1st lead:*/
if 1==1{
// leads
cap drop F_*
forval x = 2/10 { // drop the first lead
gen F_`x' = rel_time == -`x'
}
//lags
cap drop L_*
forval x = 0/10 {
gen L_`x' = rel_time == `x'
}
did2s Y, first_stage(id t) second_stage(F_* L_*) treatment(D) cluster(id)
event_plot, default_look graph_opt(xtitle("Periods since the event") ytitle("Average effect") xlabel(-10(1)10) ///
title("did2s")) stub_lag(L_#) stub_lead(F_#) together
}