Skip to content

Commit 7bf9c8f

Browse files
igerberclaude
andcommitted
Add P3 regression tests: SunAbraham survey-df and DoseResponseCurve p-values from PR #226 review (round 8)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 918b876 commit 7bf9c8f

1 file changed

Lines changed: 50 additions & 0 deletions

File tree

tests/test_survey_phase3.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -835,3 +835,53 @@ def test_within_unit_varying_strata_rejected(self):
835835
"first_treat",
836836
survey_design=sd,
837837
)
838+
839+
def test_sun_abraham_survey_df_regression(self, staggered_survey_data):
840+
"""SunAbraham survey inference should use survey df, not normal approx."""
841+
from diff_diff import SunAbraham
842+
843+
sd = SurveyDesign(weights="weight", strata="stratum", psu="psu", fpc="fpc", nest=True)
844+
result = SunAbraham().fit(
845+
staggered_survey_data,
846+
"outcome",
847+
"unit",
848+
"time",
849+
"first_treat",
850+
survey_design=sd,
851+
)
852+
sm = result.survey_metadata
853+
assert sm is not None
854+
assert sm.df_survey is not None
855+
# Overall p-value should use t-distribution (survey df), not normal
856+
# Recompute with normal approx and verify they differ
857+
from diff_diff.utils import safe_inference
858+
859+
_, p_normal, _ = safe_inference(result.overall_att, result.overall_se, alpha=0.05, df=None)
860+
_, p_survey, _ = safe_inference(
861+
result.overall_att, result.overall_se, alpha=0.05, df=sm.df_survey
862+
)
863+
# With small survey df, t-dist p-value > normal p-value
864+
if np.isfinite(result.overall_p_value) and np.isfinite(p_normal):
865+
assert result.overall_p_value == pytest.approx(p_survey, rel=1e-10)
866+
867+
def test_continuous_did_dose_response_survey_pvalue(self, continuous_survey_data):
868+
"""DoseResponseCurve.to_dataframe() p-values should use survey df."""
869+
from diff_diff import ContinuousDiD
870+
871+
sd = SurveyDesign(weights="weight", strata="stratum")
872+
result = ContinuousDiD(n_bootstrap=0).fit(
873+
continuous_survey_data,
874+
"outcome",
875+
"unit",
876+
"time",
877+
"first_treat",
878+
"dose",
879+
survey_design=sd,
880+
)
881+
sm = result.survey_metadata
882+
assert sm is not None
883+
# Check that dose-response curve p-values are finite
884+
att_df = result.dose_response_att.to_dataframe()
885+
assert "p_value" in att_df.columns
886+
finite_p = att_df["p_value"].dropna()
887+
assert len(finite_p) > 0

0 commit comments

Comments
 (0)