diff_diff.TwoWayFixedEffects#
- class diff_diff.TwoWayFixedEffects[source]#
Bases:
DifferenceInDifferencesTwo-Way Fixed Effects (TWFE) estimator for panel DiD.
Extends DifferenceInDifferences to handle panel data with unit and time fixed effects.
- Parameters:
robust (bool, default=True) – Whether to use heteroskedasticity-robust standard errors.
cluster (str, optional) –
Column name for cluster-robust standard errors. If None, automatically clusters at the unit level (the unit parameter passed to fit()). This differs from DifferenceInDifferences where cluster=None means no clustering.
Exception: when
vcov_type="classical"andinference="analytical", the unit auto-cluster is dropped because the classical family is by construction one-way only and the validator rejectscluster_ids + classical. The user’s explicit choice of the classical family wins over the TWFE default in that narrow analytical-inference case. Underinference="wild_bootstrap"the auto-cluster is preserved (the bootstrap uses the cluster structure to resample residuals).alpha (float, default=0.05) – Significance level for confidence intervals.
Notes
This estimator uses the regression:
Y_it = α_i + γ_t + β*(D_i × Post_t) + X_it’δ + ε_it
where α_i are unit fixed effects and γ_t are time fixed effects.
HC2 / Bell-McCaffrey are not available on TWFE. Because TWFE uses within-transformation (demeaning) to absorb the fixed effects, the reduced design’s hat matrix is not the full FE projection; HC2 leverage and CR2 Bell-McCaffrey corrections on the demeaned design would produce silently-wrong small-sample SEs (FWL preserves coefficients, not the hat matrix).
vcov_type in {"hc2","hc2_bm"}therefore raisesNotImplementedErrorwith workarounds: usevcov_type="hc1"(HC1/ CR1 survive FWL), or switch toDifferenceInDifferences(fixed_effects= [...])where the dummies appear in the full design. Tracked inTODO.mdunder Methodology/Correctness; also documented indocs/methodology/REGISTRY.md.Conley spatial-HAC (``vcov_type=”conley”``) is supported via the block-decomposed panel sandwich (matches R ``conleyreg`` with ``lag_cutoff > 0``). Pass
conley_coords=(lat_col, lon_col),conley_cutoff_km=<float>, andconley_lag_cutoff=<int>on the constructor; thetime/unitarrays are auto-derived from the estimator’stimeandunitcolumn-name arguments 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. FWL composability: the within-transformed scoresS = X_demeaned * residuals_demeanedform the same meat as the full-dummy-expansion design. The temporal kernel is hardcoded Bartlett regardless ofconley_kernel(matchesconleyreg::time_dist). Explicitcluster=<col>+ Conley enables the combined spatial + cluster product kernelK_total[i, j] = K_space(d_ij/h) · 1{cluster_i = cluster_j}; cluster membership must be constant within each unit across periods (validator-enforced on the panel block-decomposed path). Whencluster=is unset, TWFE’s default auto-cluster at the unit level is silently dropped on the Conley path — Conley spatial HAC alone is applied, not the combined kernel. Restrictions:inference="wild_bootstrap"+ Conley raises (incompatible inference modes);survey_design=+ Conley raises (Phase 5 follow-up).Warning: TWFE can be biased with staggered treatment timing and heterogeneous treatment effects. Consider using more robust estimators (e.g., Callaway-Sant’Anna) for staggered designs.
Methods
__init__([robust, cluster, vcov_type, ...])decompose(data, outcome, unit, time, first_treat)Perform Goodman-Bacon decomposition of TWFE estimate.
fit(data, outcome, treatment, time, unit[, ...])Fit Two-Way Fixed Effects 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)#