diff_diff.SpilloverDiDResults#

class diff_diff.SpilloverDiDResults[source]#

Bases: DiDResults

Results from a ring-indicator spillover-aware DiD estimation (Butts 2021).

Extends DiDResults with per-ring spillover effect estimates and diagnostic counts for the identifying control population.

att#

Total effect on the treated, tau_total (inherited from DiDResults).

Type:

float

spillover_effects#

Per-ring spillover-on-control estimates. Columns: ["coef", "se", "t_stat", "p_value", "ci_low", "ci_high"]. Index: ring label like "[0, 50)"; for event-study output the index is a MultiIndex over (ring_label, event_time).

Type:

pd.DataFrame, optional

ring_breakpoints#

Sorted distance breakpoints used to construct the rings.

Type:

list of float

d_bar#

Far-away cutoff (Butts Assumption 5). Equals max(ring_breakpoints) unless explicitly overridden.

Type:

float

n_units_ever_in_ring#

Counts of UNIQUE units that appear in each ring AT LEAST ONCE across observed periods. Under staggered timing the ring membership is time-varying, so a unit can be counted in multiple rings (one per period it visits). Under non-staggered timing the rings are unit-static, so this is a clean partition (each unit appears in exactly one ring or the far-away group). Includes treated units in Ring_1 by geometric construction even though the (1 - D_it) factor zeros their stage-2 contribution.

Type:

dict[str, int]

n_far_away_obs#

Number of observations with D_it = 0 AND d_it > d_bar; these observations identify the counterfactual trend (Butts Assumption 5(ii)). Under Wave E.3, on the survey path this count is reported on the EFFECTIVE WEIGHTED ESTIMATION SAMPLE (count_mask = survey_finite_mask = finite_mask AND survey_weights > 0), so zero-weight rows from SurveyDesign.subpopulation() are excluded — matches the Wave E.3 n_obs / n_treated / n_control contract. The upstream _validate_far_away_exists gate still fires on the FULL DOMAIN at fit-time (Assumption 5(ii) requires at least one far-away identifying row); this metadata only reports the count on the active sample.

Type:

int

is_staggered#

True if multiple distinct treatment-onset times were detected.

Type:

bool

event_study#

True if per-event-time ring coefficients were emitted (i.e., self.event_study=True was set on the estimator).

Type:

bool

stage1_n_obs#

Number of observations in the stage-1 untreated-and-unexposed subsample (Omega_0_butts).

Type:

int

Methods

__init__(att, se, t_stat, p_value, conf_int, ...)

print_summary([alpha])

Print the summary to stdout.

summary([alpha])

Extended summary with ATT row, per-event-time direct block, and per-(ring, event-time) spillover block.

to_dataframe()

Convert results to a pandas DataFrame.

to_dict()

Override to serialize spillover_effects DataFrame as list-of-dicts.

Attributes

alpha

anticipation

att_dynamic

bootstrap_distribution

cluster_name

coef_var

SE / abs(ATT).

coefficients

conley_lag_cutoff

d_bar

event_study

event_study_effects

fitted_values

horizon_max

inference_method

is_significant

Check if the ATT is statistically significant at the alpha level.

is_staggered

n_bootstrap

n_clusters

n_far_away_obs

n_psu

n_strata

n_units_ever_in_ring

r_squared

reference_period

residuals

ring_breakpoints

significance_stars

Return significance stars based on p-value.

spillover_effects

stage1_n_obs

survey_metadata

vcov

vcov_type

att

se

t_stat

p_value

conf_int

n_obs

n_treated

n_control

__init__(att, se, t_stat, p_value, conf_int, n_obs, n_treated, n_control, alpha=0.05, coefficients=None, vcov=None, residuals=None, fitted_values=None, r_squared=None, inference_method='analytical', n_bootstrap=None, n_clusters=None, bootstrap_distribution=None, survey_metadata=None, vcov_type=None, cluster_name=None, conley_lag_cutoff=None, spillover_effects=None, ring_breakpoints=None, d_bar=None, n_units_ever_in_ring=None, n_far_away_obs=None, is_staggered=None, event_study=None, stage1_n_obs=None, anticipation=None, att_dynamic=None, event_study_effects=None, horizon_max=None, reference_period=None, n_psu=None, n_strata=None)#
Parameters:
Return type:

None

classmethod __new__(*args, **kwargs)#