diff_diff.SpilloverDiD#

class diff_diff.SpilloverDiD[source]#

Bases: object

Ring-indicator spillover-aware DiD (Butts 2021).

Standalone estimator implementing two-stage Gardner (2022) methodology with ring-indicator covariates that identify the direct effect on treated units (tau_total) alongside per-ring spillover effects on near-control units (delta_j). Supports both panel non-staggered timing and Section 5 staggered timing in a single fit() entry point — non-staggered is the special case where all treated units share an onset time.

Parameters:
  • rings (list of float) – Sorted distance breakpoints with at least 2 elements. K = len(rings) - 1 rings are constructed.

  • d_bar (float, optional) – Far-away cutoff (Butts Assumption 5). Defaults to max(rings); if explicitly set, must equal max(rings). Wave B MVP does not support a d_bar strictly larger than the outermost ring edge (a “dead zone” where units satisfy rings[-1] < d_i <= d_bar but are in neither a ring nor the far-away group has no clean methodological interpretation). To use a smaller spillover bandwidth, shrink the outermost ring edge instead.

  • vcov_type (str, default="hc1") – Variance estimator. Set to "conley" and supply conley_coords/conley_cutoff_km/conley_lag_cutoff to enable Conley spatial-HAC at stage 2 (recommended per paper Section 3.1).

  • conley_coords (tuple of (str, str), optional) – (lat_col, lon_col) column names. Used for ring construction AND for the Conley vcov spatial kernel.

  • conley_metric (str or callable, default="haversine") – Distance metric used for both ring construction and the Conley spatial kernel. See diff_diff.conley for callable contract.

  • conley_cutoff_km (float, optional) – Conley spatial-HAC bandwidth. Required when vcov_type="conley".

  • conley_lag_cutoff (int, optional) – Within-unit Bartlett max lag. Required when vcov_type="conley". Use 0 to suppress the serial-component sandwich.

  • cluster (str, optional) – Column name for cluster-robust variance, or the combined Conley cluster product kernel when paired with vcov_type="conley".

  • alpha (float, default=0.05) – Significance level for confidence intervals.

  • anticipation (int, default=0) – Number of pre-treatment periods where effects may occur. Treatment and ring-membership clocks both shift by -anticipation so the stage-1 untreated-and-unexposed subsample correctly excludes anticipation rows.

  • event_study (bool, default=False) – If True, emit per-event-time × ring coefficients (Butts Table 2 staggered specification). The result’s spillover_effects DataFrame uses a MultiIndex over (ring, event_time).

  • horizon_max (int, optional) – Maximum absolute event-study horizon. Used only when event_study=True. Event-times outside [-horizon_max, +horizon_max] are binned into endpoint pools (k <= -H aggregated into a single pre-bin coefficient; k >= +H into a single post-bin coefficient), so no observations are dropped. This intentionally diverges from diff_diff.two_stage.TwoStageDiD, which filters rows with |K| > horizon_max out of the stage-2 sample. The endpoint-pool semantic honors the library’s no-silent-data-drop policy (feedback_no_silent_failures). When None, the helper auto-detects the bin set from observed K values. If ref_period = -1 - anticipation falls outside [-horizon_max, +horizon_max] the fit raises ValueError.

  • rank_deficient_action ({"warn", "error", "silent"}, default="warn") – Action when the stage-2 design is rank-deficient.

results_#

Populated after fit() completes.

Type:

SpilloverDiDResults

is_fitted_#
Type:

bool

Notes

The implementation uses two-stage Gardner methodology with the time-varying S_it = S_i * 1{t >= t_treat} form (paper page 12, just above Equation 5). Reading the literal unit-static (1 - D_it) * S_i from Equation 5 yields a rank-deficient design under TWFE; Section 5’s Table 2 makes the time-varying form explicit. The diff-diff implementation matches the paper’s identification argument once the S_it notation is read correctly.

For non-staggered timing, Gardner identity → stage-2 point estimates equal a single-stage TWFE with the time-varying spillover regressor.

Methods

__init__(*, rings[, d_bar, vcov_type, ...])

fit(data, *, outcome, unit, time[, ...])

Fit the two-stage Gardner DiD with ring-indicator covariates.

get_params()

set_params(**params)

__init__(*, rings, d_bar=None, vcov_type='hc1', conley_coords=None, conley_metric='haversine', conley_cutoff_km=None, conley_lag_cutoff=None, cluster=None, alpha=0.05, anticipation=0, event_study=False, horizon_max=None, rank_deficient_action='warn')[source]#
Parameters:
  • rings (List[float])

  • d_bar (float | None)

  • vcov_type (str)

  • conley_coords (Tuple[str, str] | None)

  • conley_metric (Literal['haversine', 'euclidean'] | ~typing.Callable[[~numpy.ndarray, ~numpy.ndarray], ~numpy.ndarray])

  • conley_cutoff_km (float | None)

  • conley_lag_cutoff (int | None)

  • cluster (str | None)

  • alpha (float)

  • anticipation (int)

  • event_study (bool)

  • horizon_max (int | None)

  • rank_deficient_action (str)

classmethod __new__(*args, **kwargs)#