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