Skip to contents

Computes standard errors and p-values for a SDID estimate using one of the procedures of Arkhangelsky et al. (2021) and Clarke et al. (2024): the unit bootstrap (Algorithm 2), the jackknife (Algorithm 3), or the placebo permutation (Algorithm 4), plus, for staggered fits, a global jackknife across every unit of all cohorts.

Usage

sdid_inference(
  fit,
  method = c("placebo", "bootstrap", "jackknife", "jackknife_global"),
  n_boot = 200L,
  level = 0.95,
  alternative = c("two.sided", "greater", "less"),
  seed = NULL,
  ...
)

Arguments

fit

A coresynth object with method = "sdid" (sharp or staggered).

method

Inference method: "placebo" (permutation), "bootstrap" (resamples treated and control units), "jackknife", or "jackknife_global" (staggered only).

n_boot

Number of bootstrap replications (only for method = "bootstrap").

level

Confidence level for the interval (all methods).

alternative

Direction of the alternative hypothesis: "two.sided", "greater", or "less".

seed

Integer seed for reproducibility (only for method = "bootstrap").

...

Not used. Passing cluster raises an error that points to sdid_event_study(); any other argument is reported as unused.

Value

A list with:

  • estimate: The SDID point estimate.

  • se: Standard error (placebo: placebo-distribution SD, Algorithm 4).

  • p_value: Permutation or normal-approximation p-value.

  • ci_lower, ci_upper: Confidence interval bounds.

  • method: The inference method used.

  • n_controls: Number of control units.

  • alternative: The alternative hypothesis direction.

  • placebo_effects: Named vector of LOO placebo effects (placebo only).

  • boot_ests: Bootstrap estimate distribution (bootstrap only).

Details

method = "bootstrap" draws N units with replacement from the whole panel, treated and control alike, redrawing a sample with no treated unit or fewer than two controls, and runs the whole estimator again on it: the covariate partial-out when the fit has covariates, \(\hat\sigma^2\), \(\zeta^2\) (unless fixed in scm_fit()), \(\hat\omega\) and \(\hat\lambda\). A unit drawn twice enters as two units. On a staggered fit the cohorts are rebuilt from the treated units drawn, so their sizes vary across draws.

method = "jackknife" drops one unit at a time, treated or control, and recomputes the weighted difference-in-differences with the fitted \(\hat\omega\) (renormalised over the remaining donors) and \(\hat\lambda\) held fixed; on a staggered fit it does so cohort by cohort and combines the cohort variances by the delta method, while "jackknife_global" drops each unit from the whole panel at once and keeps the covariance between cohorts.

Both resample the treated units, so they need more than one: with a single treated unit its own noise never varies across replicates (the jackknife is not even defined), and the function stops. The jackknife on a staggered fit further needs two treated units in every cohort. Use "placebo" for a single treated unit; it learns the noise level from the controls and so assumes their noise matches the treated units'.

For method = "placebo", the p-value is the permutation p-value, while the standard error is the dispersion of the placebo distribution (Clarke et al. 2024, Algorithm 4) and the confidence interval is the normal approximation around the estimate with that SE. The placebo SE assumes the treated unit's noise is comparable to the control units'; interpret it with caution when the donor pool is small.

sdid_event_study() runs the same bootstrap at the level of clusters of units and reports period-by-period effects alongside the ATT.

See also

sdid_event_study() for period-by-period event-study effects and cluster bootstrap resampling.