Skip to content

Commit 987bdcd

Browse files
igerberclaude
andcommitted
Address PR #389 R3 P2: split staggered-event-study failure modes
The HAD "Panel-only event-study restriction" subsection in `docs/troubleshooting.rst` overstated when staggered multi-cohort event-study inputs raise. Per `had.py:1230-1366` and `had.py:1470-1499` (also documented in `docs/methodology/REGISTRY.md:2408, 2533`): - Common-adoption panel (single first-treat period): `first_treat_col` optional; the period is auto-inferred from the dose invariant. - Staggered panel WITH `first_treat_col`: estimator auto-filters to the last-treatment cohort + never-treated and emits a UserWarning. - Staggered panel WITHOUT `first_treat_col`: estimator raises (the only actual failure mode for this restriction). Rewrote the cause to spell out the dispatch and made `first_treat_col` the primary remedy; kept manual cohort subsetting as an equivalent that skips the UserWarning. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent f63f40b commit 987bdcd

1 file changed

Lines changed: 17 additions & 12 deletions

File tree

docs/troubleshooting.rst

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -570,28 +570,33 @@ fits. See :doc:`api/had` for the full SE-regime contract.
570570
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
571571

572572
**Problem:** ``HeterogeneousAdoptionDiD.fit(..., aggregate="event_study")``
573-
raises because the panel is not balanced or the staggered-timing structure
574-
violates the last-treatment-cohort restriction.
573+
raises on a staggered panel.
575574

576-
**Cause:** The Appendix B.2 event-study extension requires staggered-timing
577-
panels restricted to the last-treatment cohort (which retains never-treated
578-
units as comparisons). Unbalanced panels or earlier-treated cohorts are not
579-
supported in the current release.
575+
**Cause:** The Appendix B.2 event-study extension requires either a
576+
common-adoption panel (single first-treat period; ``first_treat_col`` is
577+
then optional and the period is inferred from the dose invariant) or a
578+
staggered panel with ``first_treat_col`` provided so the estimator can
579+
auto-filter to the last-treatment cohort plus never-treated units (with
580+
a ``UserWarning``). The fit raises only when the panel is staggered
581+
**and** ``first_treat_col`` is missing.
580582

581583
**Solutions:**
582584

583585
.. code-block:: python
584586
585-
# Verify panel balance
586-
periods_per_unit = data.groupby('unit')['period'].nunique()
587-
assert periods_per_unit.nunique() == 1, "Panel is unbalanced"
587+
# Primary remedy: pass `first_treat_col` so the estimator auto-filters
588+
# to the last-treatment cohort + never-treated and emits a UserWarning.
589+
est = HeterogeneousAdoptionDiD()
590+
results = est.fit(data, outcome_col='y', unit_col='unit',
591+
time_col='period', dose_col='dose',
592+
first_treat_col='first_treat',
593+
aggregate='event_study')
588594
589-
# Restrict to the last-treatment cohort manually if needed
595+
# Equivalent: subset to the last-treatment cohort + never-treated
596+
# before fitting (skips the UserWarning).
590597
last_cohort = data['first_treat'].max()
591598
subset = data[(data['first_treat'] == last_cohort) |
592599
(data['first_treat'] == 0)]
593-
594-
est = HeterogeneousAdoptionDiD()
595600
results = est.fit(subset, outcome_col='y', unit_col='unit',
596601
time_col='period', dose_col='dose',
597602
aggregate='event_study')

0 commit comments

Comments
 (0)