diff_diff.HeterogeneousAdoptionDiDResults#

class diff_diff.HeterogeneousAdoptionDiDResults[source]#

Bases: object

Estimator output for HeterogeneousAdoptionDiD.

NaN-safe inference: the three downstream fields t_stat, p_value, and conf_int are routed through diff_diff.utils.safe_inference(), which returns NaN on all three whenever se is non-finite, zero, or negative. att and se themselves are RAW estimator outputs from the chosen fit path and are NOT gated by safe_inference:

  • On the degenerate fit configurations (constant outcome on the continuous paths, all-units-at-d_lower / no-dose-variation on the mass-point path), the fit path explicitly returns (att=nan, se=nan), which combined with the safe-inference gate yields all five fields NaN together.

  • On the degenerate CR1 cluster configuration (mass-point path with a single cluster), _fit_mass_point_2sls returns (att=beta_hat, se=nan) - att stays finite because the Wald-IV ratio is well defined, but the cluster-robust SE is not, so se is NaN and the downstream triple becomes NaN via the safe-inference gate.

So the guaranteed NaN coupling is on the downstream triple (t_stat, p_value, conf_int), not on att. The assert_nan_inference fixture in tests/conftest.py checks the downstream triple against the gate contract and does not assume att is NaN.

att#

Point estimate of the WAS parameter on the beta-scale.

  • Design 1’ (paper Theorem 1 / Equation 3 identification; Equation 7 sample estimator): att = (mean(ΔY) - tau_bc) / D_bar where tau_bc is the bias-corrected local-linear estimate of lim_{d v 0} E[ΔY | D_2 <= d] and D_bar = (1/G) * sum(D_{g,2}).

  • Design 1 continuous-near-d_lower (paper Theorem 3 / Equation 11, WAS_{d_lower} under Assumption 6): att = (mean(ΔY) - tau_bc) / mean(D_2 - d_lower) where tau_bc is the bias-corrected local-linear estimate of lim_{d v d_lower} E[ΔY | D_2 <= d].

  • Mass-point (paper Section 3.2.4): the Wald-IV / 2SLS coefficient directly - (Ybar_{Z=1} - Ybar_{Z=0}) / (Dbar_{Z=1} - Dbar_{Z=0}).

Type:

float

se#

Standard error on the beta-scale. For continuous designs:

  • Unweighted or weights=<array>: CCT-2014 weighted-robust SE from Phase 1c divided by |den| (den = raw or weighted denominator depending on fit path).

  • survey=SurveyDesign(...): Binder (1983) Taylor-series linearization of the per-unit IF (bias-corrected scale, aligned with tau_bc) routed through compute_survey_if_variance() for PSU-aggregated, FPC/strata-adjusted variance, divided by |den|.

In both cases the higher-order variance from mean(ΔY) is dominated by the nonparametric boundary estimate in large samples and is not included in the leading-order formula. For mass-point, the 2SLS structural-residual sandwich SE.

Type:

float

t_stat, p_value, conf_int

Routed through safe_inference; NaN when SE is non-finite.

Type:

inference fields

alpha#

CI level used at fit time (0.05 for a 95% CI).

Type:

float

design#

Resolved design mode: "continuous_at_zero", "continuous_near_d_lower", or "mass_point". "auto" is resolved to one of the three concrete modes before storing.

Type:

str

target_parameter#

Estimand label: "WAS" for Design 1’, "WAS_d_lower" for the other two. Pins the estimand semantically even when two designs share the same divisor.

Type:

str

d_lower#

Support infimum d_lower. 0.0 for Design 1’; float(d.min()) for the other two.

Type:

float

dose_mean#

D_bar = (1/G) * sum(D_{g,2}).

Type:

float

n_obs#

Number of units contributing to the estimator (post panel aggregation to unit-level first differences).

Type:

int

n_treated#

Number of units with D_{g,2} > d_lower.

Type:

int

n_control#

Number of units at or below d_lower (the “not-treated” subset).

Type:

int

n_mass_point#

Mass-point path only: number of units with D_{g,2} == d_lower. None on continuous paths.

Type:

int or None

n_above_d_lower#

Mass-point path only: number of units with D_{g,2} > d_lower. None on continuous paths.

Type:

int or None

inference_method#

"analytical_nonparametric" (continuous designs) or "analytical_2sls" (mass-point).

Type:

str

vcov_type#

Effective variance-covariance family used. None on continuous paths (they use the CCT-2014 robust SE from Phase 1c, not the library’s vcov_type enum). Mass-point: "classical" or "hc1" when cluster is not supplied, and "cr1" whenever cluster is supplied (cluster-robust CR1 is computed regardless of the requested vcov_type because classical/hc1 + cluster collapses to the same CR1 sandwich). Downstream consumers reading result.to_dict() can inspect this field directly to determine the effective SE family.

Type:

str or None

cluster_name#

Column name of the cluster variable on the mass-point path when cluster-robust SE is requested. None otherwise.

Type:

str or None

survey_metadata#

Repo-standard survey metadata dataclass from diff_diff.survey.SurveyMetadata. None when fit() was called without survey= or weights=; populated on the continuous-dose weighted paths via diff_diff.survey.compute_survey_metadata(). Exposes weight_type, effective_n, design_effect, sum_weights, n_strata, n_psu, weight_range, and df_survey for downstream reporting consumers (BusinessReport, DiagnosticReport) that read these fields via attribute access. HAD-specific inference-method info (pweight vs Binder-TSL) is carried on inference_method and variance_formula.

Type:

SurveyMetadata or None

bandwidth_diagnostics#

Full Phase 1b MSE-DPI selector output on the continuous paths (when bandwidths were auto-selected). None on the mass-point path (parametric, no bandwidth).

Type:

BandwidthResult or None

bias_corrected_fit#

Full Phase 1c bias-corrected local-linear fit on the continuous paths. None on the mass-point path.

Type:

BiasCorrectedFit or None

Methods

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

print_summary()

Print the summary to stdout.

summary()

Formatted summary table.

to_dataframe()

Return a one-row DataFrame of the result dict.

to_dict()

Return results as a dict of scalars + weighted-path surfaces.

Attributes

effective_dose_mean

Weighted denominator used by the beta-scale rescaling, populated on weighted fits across all designs: sum(w_g · D_g) / sum(w_g) on continuous_at_zero, sum(w_g · (D_g - d_lower)) / sum(w_g) on continuous_near_d_lower, and the weighted Wald-IV dose gap mean(D | Z=1, w) - mean(D | Z=0, w) on mass_point (where Z = 1{D > d_lower}).

variance_formula

HAD-specific label for the SE formula on weighted fits, populated on BOTH continuous and mass-point designs (Phase 4.5 A / B): "pweight" (continuous, weighted-robust CCT 2014 under the weights= shortcut), "survey_binder_tsl" (continuous, Binder 1983 TSL with PSU/strata/FPC under survey_design=SurveyDesign(...)), "pweight_2sls" (mass-point + weights=; label applied uniformly across vcov families — classical / HC1 / CR1 — on the weighted 2SLS path, with the actual sandwich resolved via vcov_type), or "survey_binder_tsl_2sls" (mass-point, Binder 1983 TSL under survey_design=).

att

se

t_stat

p_value

conf_int

alpha

design

target_parameter

d_lower

dose_mean

n_obs

n_treated

n_control

n_mass_point

n_above_d_lower

inference_method

vcov_type

cluster_name

survey_metadata

bandwidth_diagnostics

bias_corrected_fit

__init__(att, se, t_stat, p_value, conf_int, alpha, design, target_parameter, d_lower, dose_mean, n_obs, n_treated, n_control, n_mass_point, n_above_d_lower, inference_method, vcov_type, cluster_name, survey_metadata, bandwidth_diagnostics, bias_corrected_fit, variance_formula=None, effective_dose_mean=None)#
Parameters:
Return type:

None

classmethod __new__(*args, **kwargs)#