*! rdstagger_pretest v1.0.0 Subir Hait 2026 *! Pre-treatment parallel trends falsification tests for rdstagger *! Stata 14 compatible program define rdstagger_pretest, eclass version 14 syntax [, /// method(string) /// joint/individual/both ] if "`e(cmd)'" != "rdstagger" { di as error "Must run rdstagger before rdstagger_pretest" exit 198 } if "`method'" == "" local method "both" if !inlist("`method'", "joint", "individual", "both") { di as error "method() must be joint, individual, or both" exit 198 } tempname ATTGT matrix `ATTGT' = e(attgt) local nrows = rowsof(`ATTGT') * Collect pre-treatment cells (prepost == 0) local pre_atts "" local pre_ses "" local pre_cohort "" local pre_period "" local npre = 0 forvalues r = 1/`nrows' { if `ATTGT'[`r',3] < . & `ATTGT'[`r',10] == 0 { local ++npre local pre_atts "`pre_atts' `=`ATTGT'[`r',3]'" local pre_ses "`pre_ses' `=`ATTGT'[`r',4]'" local pre_cohort "`pre_cohort' `=`ATTGT'[`r',1]'" local pre_period "`pre_period' `=`ATTGT'[`r',2]'" } } if `npre' == 0 { di as txt "No pre-treatment ATT(g,t) cells found." di as txt "Ensure your data has periods before treatment adoption." exit } di _newline as txt "rdstagger Pre-Treatment Falsification Test" di as txt "{hline 60}" di as txt "Pre-treatment ATT(g,t) cells: `npre'" di as txt "{hline 60}" * --- Joint Wald test --- if inlist("`method'", "joint", "both") { local chi2 = 0 local k = 0 forvalues i = 1/`npre' { local att_i : word `i' of `pre_atts' local se_i : word `i' of `pre_ses' if `se_i' > 0 { local chi2 = `chi2' + (`att_i'/`se_i')^2 local ++k } } local pval_joint = chi2tail(`k', `chi2') di _newline as txt "Joint Wald Test (H0: all pre-treatment ATT = 0)" di as txt " Chi-squared(`k') = " %8.4f `chi2' di as txt " p-value = " %8.4f `pval_joint' if `pval_joint' > 0.05 { di as txt " Result: " as res "PASS" as txt /// " -- no evidence of pre-treatment trends (p > 0.05)" } else { di as txt " Result: " as error "FAIL" as txt /// " -- evidence of pre-treatment trends (p <= 0.05)" } ereturn scalar pretest_chi2 = `chi2' ereturn scalar pretest_df = `k' ereturn scalar pretest_pval = `pval_joint' } * --- Individual cell tests --- if inlist("`method'", "individual", "both") { di _newline as txt "Individual Cell Tests:" di as txt "{hline 65}" di as txt %8s "Cohort" %8s "Period" %11s "ATT" /// %11s "SE" %10s "t-stat" %10s "p-val" %8s "Sig?" di as txt "{hline 65}" local nsig = 0 forvalues i = 1/`npre' { local att_i : word `i' of `pre_atts' local se_i : word `i' of `pre_ses' local cohort_i : word `i' of `pre_cohort' local period_i : word `i' of `pre_period' local tstat = `att_i' / max(`se_i', 1e-10) local pval = 2 * normal(-abs(`tstat')) local sig = cond(abs(`tstat') > invnormal(0.975), "*", " ") if "`sig'" == "*" local ++nsig di as res %8.0f `cohort_i' /// %8.0f `period_i' /// %11.4f `att_i' /// %11.4f `se_i' /// %10.4f `tstat' /// %10.4f `pval' /// %8s "`sig'" } di as txt "{hline 65}" di as txt "* significant at 5% level" di as txt "`nsig' of `npre' pre-treatment cells significant at 5%" } end