Hi,
Section 4.4 of Clarke et al (2023) shows how to generate event study style plots with the synthetic difference-in-differences procedure developed by Arkhangelsky et al (2021). Specifically, Clarke et al provide the Stata code for generating this type of plot with confidence intervals generated following a block bootstrapping procedure. However, they note that this type of plot could also be generated following a placebo permutation procedure. I would like to know how to generate such a plot.
I've tried to write my own code to do this based on the author's existing code for the event study plot with bootstraping + the .ado code for generating placebo/permutation-based standard errors. Could someone review my code and check that it is properly generating placebo-based confidence intervals?
Section 4.4 of Clarke et al (2023) shows how to generate event study style plots with the synthetic difference-in-differences procedure developed by Arkhangelsky et al (2021). Specifically, Clarke et al provide the Stata code for generating this type of plot with confidence intervals generated following a block bootstrapping procedure. However, they note that this type of plot could also be generated following a placebo permutation procedure. I would like to know how to generate such a plot.
I've tried to write my own code to do this based on the author's existing code for the event study plot with bootstraping + the .ado code for generating placebo/permutation-based standard errors. Could someone review my code and check that it is properly generating placebo-based confidence intervals?
Code:
/*======================================================================= Prepare data ========================================================================*/ webuse set www.damianclarke.net/stata/ webuse quota_example.dta, clear egen m=min(year) if quota==1, by(country) //indicator for the year of adoption egen mm=mean(m), by(country) keep if mm==2002 | mm==. //keep only one time of adoption drop if lngdp==. //keep if covariates observed /*======================================================================= Create vector of values from Equation (8) ========================================================================*/ qui sdid womparl country year quota, vce(noinference) graph g2_opt(ylab(-5(5)20) ytitle("Women in Parliament") scheme(sj)) graph_export(groups, .pdf) covariates(lngdp, projected) matrix lambda = e(lambda)[1..12,1] //save lambda weight matrix yco = e(series)[1..12,2] //control baseline matrix ytr = e(series)[1..12,3] //treated baseline matrix aux = lambda'*(ytr - yco) //calculate the pre-treatment mean scalar meanpre_o = aux[1,1] matrix difference = e(difference)[1..26,1..2] // Store Ytr-Yco svmat difference ren (difference1 difference2) (time d) replace d = d - meanpre_o // Calculate vector in (8) /*======================================================================= Do permutation procedure to generate confidence intervals ========================================================================*/ * Generate locals related to treatment status tempvar treated ty tyear n qui gen `ty' = year if quota == 1 qui bys country: egen `treated' = max(quota) qui by country: egen `tyear' = min(`ty') * Generate local for number of control units local co = 106 * Set replication counter and number of reps local b = 1 local B = 100 * Loop over all permutation replications while `b'<=`B' { * Preserve data preserve * Drop treated units qui drop if `tyear' !=. * Generate numeric order by random uniform variable tempvar r rand id sort year country qui gen `r' = runiform() in 1/`co' bysort country: egen `rand' = sum(`r') egen `id' = group(`rand') * Assign placebo treatment local i=1 forvalues y=1/`co' { qui replace `tyear' = tryears[`i',1] if `id' == `y' local ++i } qui replace quota = 1 if year >= `tyear' * Run SDiD qui: sdid womparl country year quota, vce(noinference) graph * Collect bootstrapped versions of the quantities you stored above to calculate the second term in Equation 8 matrix lambda_b = e(lambda)[1..12,1] matrix yco_b = e(series)[1..12,2] matrix ytr_b = e(series)[1..12,3] matrix aux_b = lambda_b'*(ytr_b - yco_b) matrix meanpre_b = J(26,1,aux_b[1,1]) * Collect this replication's Equation 8 values (and store in a matrix) matrix d`b'=e(difference)[1..26,2] - meanpre_b * Update loop counter local ++b * Restore dataset restore } *** Calculate standard deviation of each estimate from (8) based on the bootstrap resamples * Keep original estimate of (8) preserve keep time d keep if time!=. * Import vector of resampled estimates forval b=1/`B' { svmat d`b' } * Calculate standard deviation of estimates across each time period egen rsd = rowsd(d11 - d`B'1) * Generate confidence intervals gen LCI = d + invnormal(0.025)*rsd gen UCI = d + invnormal(0.975)*rsd /*======================================================================= Generate plot ========================================================================*/ tw rarea UCI LCI time, color(gray%40) || scatter d time, color(blue) m(d) xtitle("") ytitle("Women in Parliament") xlab(1990(1)2015, angle(45)) legend(order(2 "Point Estimate" 1 "95% CI") pos(12) col(2)) xline(2002, lc(black) lp(solid)) yline(0, lc(red) lp(shortdash)) scheme(sj) restore
Comment