Skip to content

Commit 55d7a27

Browse files
igerberclaude
andcommitted
Fix docs/choosing_estimator.rst HAD snippet (block7) for CI
The HeterogeneousAdoptionDiD example snippet in choosing_estimator.rst failed the Pure Python Fallback CI job (test_doc_snippets.py ::test_doc_snippet[choosing_estimator:block7]) due to three latent drift bugs from PR igerber#389 (docs-rtd-audit): 1. Missing aggregate='event_study' on both did_had_pretest_workflow and HAD.fit calls — default aggregate='overall' requires exactly 2 periods, but the doc-snippet test framework's namespace `data` (built via generate_staggered_data) has 10 periods. 2. Used the namespace's generic `data` variable, which has nonzero dose in every period (rng.choice from {0.0, 0.5, 1.0, 2.0}). HAD requires D=0 for all units in at least one pre-period. 3. `print(f"Estimate: {results.att:.3f}")` formatted att as a scalar, but under aggregate='event_study' results.att is a numpy array. Fix: rewrite the snippet to construct its own HAD-shape panel inline (mirrors how block6 handles ContinuousDiD with its own data generator); thread aggregate='event_study' through both calls; iterate the per-horizon att array for output. Pre-existing on origin/main; surfaced on this PR's CI re-run after the rebase. Other failing snippets (troubleshooting:block18, :block20, r_comparison:block6, :block7) are also pre-existing on main but are out of scope for this PR. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent fc436a5 commit 55d7a27

1 file changed

Lines changed: 25 additions & 6 deletions

File tree

docs/choosing_estimator.rst

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -392,17 +392,36 @@ before estimation; see :doc:`api/had` for the full API and SE-regime contract.
392392

393393
.. code-block:: python
394394
395+
import numpy as np
396+
import pandas as pd
395397
from diff_diff import HeterogeneousAdoptionDiD, did_had_pretest_workflow
396398
397-
pretests = did_had_pretest_workflow(data, outcome_col='y', unit_col='unit',
398-
time_col='period', dose_col='dose')
399+
# Build a HAD-shape panel: D=0 in pre-periods (t < F), D > 0 only at F+.
400+
rng = np.random.default_rng(42)
401+
G, F, T = 200, 4, 5
402+
doses = rng.beta(0.5, 1.0, size=G)
403+
rows = []
404+
for g in range(G):
405+
for t in range(1, T + 1):
406+
y = (rng.normal()
407+
+ (doses[g] + doses[g] ** 2) * (t >= F)
408+
+ rng.normal(0, 0.5))
409+
d = doses[g] if t >= F else 0.0
410+
rows.append({'unit': g, 'period': t, 'y': y, 'dose': d})
411+
had_data = pd.DataFrame(rows)
412+
413+
pretests = did_had_pretest_workflow(had_data, outcome_col='y', unit_col='unit',
414+
time_col='period', dose_col='dose',
415+
aggregate='event_study')
399416
400417
est = HeterogeneousAdoptionDiD()
401-
results = est.fit(data, outcome_col='y', unit_col='unit',
402-
time_col='period', dose_col='dose')
418+
results = est.fit(had_data, outcome_col='y', unit_col='unit',
419+
time_col='period', dose_col='dose',
420+
aggregate='event_study')
403421
404-
print(f"Resolved estimand: {results.target_parameter}")
405-
print(f"Estimate: {results.att:.3f}")
422+
# Event-study results: per-horizon WAS at each event time
423+
for e, att in zip(results.event_times, results.att):
424+
print(f" e={e}: {att:.3f}")
406425
407426
Efficient DiD
408427
~~~~~~~~~~~~~

0 commit comments

Comments
 (0)