Skip to content

Commit d45df25

Browse files
igerberclaude
andcommitted
Add replicate-weight aggregation regression test for DR+survey path
Exercises the compute_replicate_if_variance dispatch in _aggregate_overall and _aggregate_event_study with covariates + replicate-weight survey design, guarding against future regressions to the wrong variance helper. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 42d3dff commit d45df25

1 file changed

Lines changed: 52 additions & 0 deletions

File tree

tests/test_survey_phase3.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1120,6 +1120,58 @@ def test_zero_weight_never_treated_raises(self, cov_survey_data):
11201120
survey_design=sd,
11211121
)
11221122

1123+
def test_replicate_weight_aggregation(self):
1124+
"""Replicate-weight aggregation SEs use compute_replicate_if_variance."""
1125+
from diff_diff import EfficientDiD
1126+
1127+
# Reuse the fixture from test_survey_phase6
1128+
np.random.seed(42)
1129+
n_units, n_periods, n_rep = 60, 6, 15
1130+
# Generate per-unit replicate weights (constant within unit across time)
1131+
unit_repwts = {}
1132+
for unit in range(n_units):
1133+
wt = 1.0 + 0.3 * (unit % 5)
1134+
unit_repwts[unit] = {
1135+
f"repwt_{r}": wt * (0.5 + np.random.random())
1136+
for r in range(n_rep)
1137+
}
1138+
rows = []
1139+
for unit in range(n_units):
1140+
ft = 3 if unit < 20 else (5 if unit < 40 else 0)
1141+
wt = 1.0 + 0.3 * (unit % 5)
1142+
x1 = np.random.randn()
1143+
for t in range(1, n_periods + 1):
1144+
y = 10.0 + unit * 0.05 + t * 0.2 + 0.5 * x1
1145+
if ft > 0 and t >= ft:
1146+
y += 2.0
1147+
y += np.random.normal(0, 0.5)
1148+
row = {"unit": unit, "time": t, "first_treat": ft,
1149+
"outcome": y, "weight": wt, "x1": x1}
1150+
row.update(unit_repwts[unit])
1151+
rows.append(row)
1152+
import pandas as pd
1153+
data = pd.DataFrame(rows)
1154+
rep_cols = [f"repwt_{r}" for r in range(n_rep)]
1155+
1156+
sd = SurveyDesign(
1157+
weights="weight", replicate_weights=rep_cols,
1158+
replicate_method="JK1",
1159+
)
1160+
result = EfficientDiD(n_bootstrap=0).fit(
1161+
data, "outcome", "unit", "time", "first_treat",
1162+
covariates=["x1"],
1163+
aggregate="event_study",
1164+
survey_design=sd,
1165+
)
1166+
assert np.isfinite(result.overall_att)
1167+
assert np.isfinite(result.overall_se)
1168+
assert result.overall_se > 0
1169+
assert result.event_study_effects is not None
1170+
for _, eff in result.event_study_effects.items():
1171+
assert np.isfinite(eff["effect"])
1172+
assert np.isfinite(eff["se"])
1173+
assert eff["se"] > 0
1174+
11231175

11241176
# =============================================================================
11251177
# Scale Invariance (applies to all estimators)

0 commit comments

Comments
 (0)