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
-------------------------------------------------
}
/* 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
}
Thanks @azev77! I randomly checked this space and found your post. I still plan to add more stuff to each package and combine them together in a separate post so this will be very useful.
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!