diff_diff.MultiPeriodDiD#
- class diff_diff.MultiPeriodDiD[source]#
Bases:
DifferenceInDifferencesMulti-Period Difference-in-Differences estimator.
Extends the standard DiD to handle multiple pre-treatment and post-treatment time periods, providing period-specific treatment effects as well as an aggregate average treatment effect.
- Parameters:
robust (bool, default=True) – Legacy alias for
vcov_type.robust=Truemaps tovcov_type="hc1";robust=Falsemaps tovcov_type="classical". Explicitvcov_typeoverridesrobustunless the pair is contradictory (e.g.robust=False, vcov_type="hc2"raises).cluster (str, optional) – Column name for cluster-robust standard errors. With
vcov_type="hc1"dispatches to CR1 (Liang-Zeger). Withvcov_type="hc2_bm"dispatches to CR2 cluster-robust SEs with Bell-McCaffrey Satterthwaite DOF on both per-period coefficients and the post-period-average ATT contrast (the latter via the new_compute_cr2_bm_contrast_dofhelper inlinalg.py; matches clubSandwich’sWald_test(test="HTZ")$df_denomat atol=1e-10). Weighted CR2-BM (survey_design=) is a separate, still-gated path.vcov_type ({"classical", "hc1", "hc2", "hc2_bm", "conley"}, optional) –
Variance-covariance family. Defaults to the
robustalias."classical": non-robust OLS SEs,sigma_hat^2 * (X'X)^{-1}."hc1": heteroskedasticity-robust HC1 withn/(n-k)adjustment (library default). Withcluster=, uses CR1 (Liang-Zeger)."hc2": leverage-corrected meat (one-way only). Errors withcluster=; use"hc2_bm"without cluster for Bell-McCaffrey."hc2_bm": one-way HC2 + Imbens-Kolesar (2016) Satterthwaite DOF per coefficient plus a contrast-aware DOF for the post-period-average ATT. Withcluster=, dispatches to Pustejovsky-Tipton (2018) CR2 cluster-robust with a Bell-McCaffrey Satterthwaite contrast DOF on the post-period average (seeclusterabove for parity details). Weighted CR2-BM (survey_design=) is still gated."conley": Conley 1999 spatial-HAC sandwich via the panel block-decomposed form (matches Rconleyregwithlag_cutoff > 0). Passconley_coords=(lat_col, lon_col),conley_cutoff_km=<float>, andconley_lag_cutoff=<int>on the constructor;unit=must be supplied at fit-time. The sandwich sums within-period spatial pairs plus within-unit Bartlett serial pairs (lag=0 excluded to avoid double-counting); this is NOT a multiplicative product kernel.conley_timeis auto-derived from thetimecolumn at fit-time and normalized to dense panel-period codes0..T-1soconley_lag_cutoffalways counts panel periods (works for int / datetime64 /pd.Period/ string encodings). Explicitcluster=<col>enables the combined spatial + cluster product kernel (Wave A #119; cluster must be constant within each unit across periods). Restrictions:survey_design=andinference="wild_bootstrap"raise on this path (Phase 5 / follow-up).
alpha (float, default=0.05) – Significance level for confidence intervals.
conley_coords – Constructor kwargs that take effect when
vcov_type="conley".conley_coordsis a(lat_col, lon_col)tuple of column names ondata.conley_lag_cutoffis the within-unit Bartlett lag (non-negative int; 0 means within-period spatial only, no serial component).conley_cutoff_km – Constructor kwargs that take effect when
vcov_type="conley".conley_coordsis a(lat_col, lon_col)tuple of column names ondata.conley_lag_cutoffis the within-unit Bartlett lag (non-negative int; 0 means within-period spatial only, no serial component).conley_metric – Constructor kwargs that take effect when
vcov_type="conley".conley_coordsis a(lat_col, lon_col)tuple of column names ondata.conley_lag_cutoffis the within-unit Bartlett lag (non-negative int; 0 means within-period spatial only, no serial component).conley_kernel – Constructor kwargs that take effect when
vcov_type="conley".conley_coordsis a(lat_col, lon_col)tuple of column names ondata.conley_lag_cutoffis the within-unit Bartlett lag (non-negative int; 0 means within-period spatial only, no serial component).conley_lag_cutoff – Constructor kwargs that take effect when
vcov_type="conley".conley_coordsis a(lat_col, lon_col)tuple of column names ondata.conley_lag_cutoffis the within-unit Bartlett lag (non-negative int; 0 means within-period spatial only, no serial component).
- results_#
Estimation results after calling fit().
- Type:
Examples
Basic usage with multiple time periods:
>>> import pandas as pd >>> from diff_diff import MultiPeriodDiD >>> >>> # Create sample panel data with 6 time periods >>> # Periods 0-2 are pre-treatment, periods 3-5 are post-treatment >>> data = create_panel_data() # Your data >>> >>> # Fit the model >>> did = MultiPeriodDiD() >>> results = did.fit( ... data, ... outcome='sales', ... treatment='treated', ... time='period', ... post_periods=[3, 4, 5] # Specify which periods are post-treatment ... ) >>> >>> # View period-specific effects >>> for period, effect in results.period_effects.items(): ... print(f"Period {period}: {effect.effect:.3f} (SE: {effect.se:.3f})") >>> >>> # View average treatment effect >>> print(f"Average ATT: {results.avg_att:.3f}")
Notes
The model estimates:
Y_it = α + β*D_i + Σ_t γ_t*Period_t + Σ_{t≠ref} δ_t*(D_i × 1{t}) + ε_it
Where: - D_i is the treatment indicator - Period_t are time period dummies (all non-reference periods) - D_i × 1{t} are treatment-by-period interactions (all non-reference) - δ_t are the period-specific treatment effects - The reference period (default: last pre-period) has δ_ref = 0 by construction
Pre-treatment δ_t test the parallel trends assumption (should be ≈ 0). Post-treatment δ_t estimate dynamic treatment effects. The average ATT is computed from post-treatment δ_t only.
Methods
__init__([robust, cluster, vcov_type, ...])fit(data, outcome, treatment, time[, ...])Fit the Multi-Period Difference-in-Differences model.
get_params()Get estimator parameters (sklearn-compatible).
predict(data)Predict outcomes using fitted model.
print_summary()Print summary to stdout.
set_params(**params)Set estimator parameters (sklearn-compatible).
summary()Get summary of estimation results.
- __init__(robust=True, cluster=None, vcov_type=None, alpha=0.05, inference='analytical', n_bootstrap=999, bootstrap_weights='rademacher', seed=None, rank_deficient_action='warn', conley_coords=None, conley_cutoff_km=None, conley_metric='haversine', conley_kernel='bartlett', conley_lag_cutoff=None)#
- classmethod __new__(*args, **kwargs)#