Skip to content

Commit 419d872

Browse files
igerberclaude
andcommitted
Fix CI review R4: persist target_label on HonestDiDResults, render dynamically
- Add target_label field to HonestDiDResults (default: equal-weight avg) - HonestDiD.fit() detects common l_vec patterns and sets human-readable label (on-impact, equal-weight, or custom with vector) - Summary renders hd.target_label instead of hard-coded string - Add test_honest_did_custom_l_vec_summary_label: attaches custom-target results and asserts summary shows "on-impact" not "Equal-weight" Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent a351e2e commit 419d872

File tree

3 files changed

+33
-2
lines changed

3 files changed

+33
-2
lines changed

diff_diff/chaisemartin_dhaultfoeuille_results.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -987,7 +987,7 @@ def _render_honest_did_section(
987987
"HonestDiD Sensitivity (Rambachan-Roth 2023)".center(width),
988988
thin,
989989
f"{'Method:':<35} {method_label} (M={_fmt_float(m_val)})",
990-
f"{'Target:':<35} {'Equal-weight avg over post horizons'}",
990+
f"{'Target:':<35} {hd.target_label}",
991991
f"{'Original estimate:':<35} {_fmt_float(hd.original_estimate):>10}",
992992
f"{'Identified set:':<35} "
993993
f"[{_fmt_float(hd.lb)}, {_fmt_float(hd.ub)}]",

diff_diff/honest_did.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ class HonestDiDResults:
191191
original_se: float
192192
alpha: float = 0.05
193193
ci_method: str = "FLCI"
194+
target_label: str = "Equal-weight avg over post horizons"
194195
original_results: Optional[Any] = field(default=None, repr=False)
195196
# Event study bounds (optional)
196197
event_study_bounds: Optional[Dict[Any, Dict[str, float]]] = field(default=None, repr=False)
@@ -2252,13 +2253,23 @@ def fit(
22522253
"coefficient to compute bounds."
22532254
)
22542255

2255-
# Set up weighting vector
2256+
# Set up weighting vector and target label
22562257
if self.l_vec is None:
22572258
l_vec = np.ones(num_post) / num_post # Uniform weights
2259+
target_label = "Equal-weight avg over post horizons"
22582260
else:
22592261
l_vec = np.asarray(self.l_vec)
22602262
if len(l_vec) != num_post:
22612263
raise ValueError(f"l_vec must have length {num_post}, got {len(l_vec)}")
2264+
# Detect common patterns for a human-readable label
2265+
basis = np.zeros(num_post)
2266+
basis[0] = 1.0
2267+
if np.allclose(l_vec, basis):
2268+
target_label = "First post-treatment effect (on-impact)"
2269+
elif np.allclose(l_vec, np.ones(num_post) / num_post):
2270+
target_label = "Equal-weight avg over post horizons"
2271+
else:
2272+
target_label = f"Custom l_vec ({l_vec.tolist()})"
22622273

22632274
# Compute original estimate and SE
22642275
original_estimate = np.dot(l_vec, beta_post)
@@ -2318,6 +2329,7 @@ def fit(
23182329
original_se=original_se,
23192330
alpha=self.alpha,
23202331
ci_method=ci_method,
2332+
target_label=target_label,
23212333
original_results=results,
23222334
survey_metadata=survey_metadata,
23232335
df_survey=df_survey,

tests/test_chaisemartin_dhaultfoeuille.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3404,6 +3404,25 @@ def test_honest_did_custom_l_vec_on_impact(self):
34043404
rtol=1e-10,
34053405
)
34063406

3407+
def test_honest_did_custom_l_vec_summary_label(self):
3408+
"""summary() renders custom target label when l_vec is overridden."""
3409+
from diff_diff.honest_did import compute_honest_did
3410+
3411+
df = self._make_data()
3412+
with warnings.catch_warnings():
3413+
warnings.simplefilter("ignore")
3414+
r = ChaisemartinDHaultfoeuille(seed=1).fit(
3415+
df, "outcome", "group", "period", "treatment",
3416+
L_max=2,
3417+
)
3418+
# Attach custom-target HonestDiD to results
3419+
r.honest_did_results = compute_honest_did(
3420+
r, l_vec=np.array([1.0, 0.0])
3421+
)
3422+
text = r.summary()
3423+
assert "on-impact" in text.lower()
3424+
assert "Equal-weight" not in text
3425+
34073426
def test_honest_did_with_trends_nonparam(self):
34083427
"""End-to-end trends_nonparam + honest_did=True."""
34093428
rng = np.random.RandomState(42)

0 commit comments

Comments
 (0)