Skip to content

Commit 7c6693f

Browse files
igerberclaude
andcommitted
Address PR #372 R7 review (1 P1, 2 P3): HAD methodology accuracy + toctree
P1 - HAD descriptions disagreed with REGISTRY.md and shipped code - Reviewer caught factual errors I introduced when drafting HAD copy: - "Strictly positive heterogeneous dose" excludes Design 1' (the QUG case where d̲ = 0 is allowed; mass-point fraction at d̲ matters for the support-plausibility heuristic but `d.min() == 0` is the canonical Design 1' invariant per REGISTRY L2504-2508). - "HC2 / Bell-McCaffrey small-sample SEs" is wrong for HAD: the mass-point path only exposes `classical` / `hc1` (HC2 / HC2_BM raise NotImplementedError pending 2SLS-specific leverage); the continuous paths use the CCT-2014 weighted-robust SE from the in-house lprobust port. - "Per-horizon WAS effects with correlated standard errors and sup-t bands" is wrong: per-horizon CIs are pointwise by default and have NO cross-horizon covariance (deferred to TODO follow-up). Sup-t is available ONLY on the weighted event-study path via `cband=True`. - "Multi-period event-study extension" silent on staggered handling: the estimator auto-filters staggered-timing panels to the last-treatment cohort (which retains never-treated units as comparisons) per paper Appendix B.2 prescription. - Rewrite docs/api/had.rst, README.md catalog one-liner, and diff_diff/guides/llms.txt catalog one-liner to match REGISTRY exactly: Design 1' (d̲=0 / QUG) and Design 1 (d̲>0) both supported; three SE regimes documented (unweighted CCT-2014; `weights=` shortcut with classical/hc1 mass-point; `survey=` with Binder TSL); pointwise CIs per horizon; sup-t restricted to weighted event-study + cband=True; last-treatment-cohort restriction noted explicitly. P3 - docs/api/had.rst cited Calonico/Cattaneo/Titiunik (2014) but it was not in docs/references.rst (CONTRIBUTING.md now treats references.rst as the bibliography source of truth) - Drop the CCT 2014 inline citation from had.rst; the bias-correction primitive is an implementation detail tracked in REGISTRY.md and not needed at the user-facing API page level. The CCF 2018/2019 nprobust port reference is preserved as "ported from the nprobust machinery" without a specific citation, also matching how other API pages handle underlying numerical-method machinery. P3 - had.rst was added to docs/api/index.rst autosummary but missed the Module Documentation > Estimators toctree at the same file - Add `had` between `continuous_did` and `efficient_did` in the Estimators toctree so the new page is navigable from the RTD API landing page. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 578460e commit 7c6693f

4 files changed

Lines changed: 40 additions & 17 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ Full guide: `diff_diff.get_llm_guide("practitioner")`.
110110
- [SyntheticDiD](https://diff-diff.readthedocs.io/en/stable/api/estimators.html) - Synthetic DiD combining standard DiD and synthetic control for few treated units
111111
- [TripleDifference](https://diff-diff.readthedocs.io/en/stable/api/triple_diff.html) - triple difference (DDD) estimator for designs requiring two criteria for treatment eligibility
112112
- [ContinuousDiD](https://diff-diff.readthedocs.io/en/stable/api/continuous_did.html) - Callaway, Goodman-Bacon & Sant'Anna (2024) continuous treatment DiD with dose-response curves
113-
- [HeterogeneousAdoptionDiD](https://diff-diff.readthedocs.io/en/stable/api/had.html) - de Chaisemartin, Ciccia, D'Haultfœuille & Knau (2026) for **no-untreated-unit panels** where every unit receives a strictly positive heterogeneous dose; local-linear estimator targeting the Weighted Average Slope (WAS) at the support boundary, with multi-period event-study extension. Alias `HAD`.
113+
- [HeterogeneousAdoptionDiD](https://diff-diff.readthedocs.io/en/stable/api/had.html) - de Chaisemartin, Ciccia, D'Haultfœuille & Knau (2026) for designs where **no unit remains untreated**; local-linear estimator targeting the Weighted Average Slope (WAS) at the dose support boundary (Design 1' with `d̲ = 0` and Design 1 with `d̲ > 0`), with a multi-period event-study extension (last-treatment cohort, pointwise CIs). Alias `HAD`.
114114
- [StackedDiD](https://diff-diff.readthedocs.io/en/stable/api/stacked_did.html) - Wing, Freedman & Hollingsworth (2024) stacked DiD with Q-weights and sub-experiments
115115
- [EfficientDiD](https://diff-diff.readthedocs.io/en/stable/api/efficient_did.html) - Chen, Sant'Anna & Xie (2025) efficient DiD with optimal weighting for tighter SEs
116116
- [TROP](https://diff-diff.readthedocs.io/en/stable/api/trop.html) - Triply Robust Panel estimator (Athey et al. 2025) with nuclear norm factor adjustment

diff_diff/guides/llms.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ Full practitioner guide: call `diff_diff.get_llm_guide("practitioner")`
6161
- [SyntheticDiD](https://diff-diff.readthedocs.io/en/stable/api/estimators.html): Synthetic DiD combining standard DiD and synthetic control methods for few treated units
6262
- [TripleDifference](https://diff-diff.readthedocs.io/en/stable/api/triple_diff.html): Triple difference (DDD) estimator for designs requiring two criteria for treatment eligibility
6363
- [ContinuousDiD](https://diff-diff.readthedocs.io/en/stable/api/continuous_did.html): Callaway, Goodman-Bacon & Sant'Anna (2024) continuous treatment DiD with dose-response curves
64-
- [HeterogeneousAdoptionDiD](https://diff-diff.readthedocs.io/en/stable/api/had.html): de Chaisemartin, Ciccia, D'Haultfœuille & Knau (2026) for designs where **no unit remains untreated** (heterogeneous adoption / HAD); local-linear estimator targeting Weighted Average Slope (WAS) at the support boundary, with multi-period event-study extension. Alias `HAD`.
64+
- [HeterogeneousAdoptionDiD](https://diff-diff.readthedocs.io/en/stable/api/had.html): de Chaisemartin, Ciccia, D'Haultfœuille & Knau (2026) for designs where **no unit remains untreated**; local-linear estimator targeting Weighted Average Slope (WAS) at the dose support boundary (Design 1' with `d̲=0` and Design 1 with `d̲>0`), with multi-period event-study extension (last-treatment cohort, pointwise CIs). Alias `HAD`.
6565
- [StackedDiD](https://diff-diff.readthedocs.io/en/stable/api/stacked_did.html): Wing, Freedman & Hollingsworth (2024) stacked DiD with Q-weights and sub-experiments
6666
- [EfficientDiD](https://diff-diff.readthedocs.io/en/stable/api/efficient_did.html): Chen, Sant'Anna & Xie (2025) efficient DiD with optimal weighting for tighter SEs
6767
- [TROP](https://diff-diff.readthedocs.io/en/stable/api/trop.html): Triply Robust Panel estimator (Athey et al. 2025) with nuclear norm factor adjustment

docs/api/had.rst

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,55 @@
11
Heterogeneous Adoption Difference-in-Differences
22
================================================
33

4-
Estimator for designs where **no unit remains untreated** at the post period
5-
- every unit `g` receives a strictly positive heterogeneous dose `D_{g,2} > 0`,
6-
and there is no genuinely untreated control group to anchor a standard DiD
7-
contrast.
4+
Estimator for designs where **no unit remains untreated** at the post period.
5+
Every unit `g` is exposed to treatment at the same single date but adoption
6+
intensity (dose) varies across units; there is no genuinely untreated control
7+
group to anchor a standard DiD contrast.
88

99
This module implements the methodology from de Chaisemartin, Ciccia,
1010
D'Haultfœuille & Knau (2026), "Difference-in-Differences Estimators When No
1111
Unit Remains Untreated" (arXiv:2405.04465v6), which:
1212

1313
1. **Targets the Weighted Average Slope (WAS)** as the identified parameter
1414
when no untreated comparison group exists (paper Equation 2).
15-
2. **Uses local-linear regression at the support boundary** to estimate the
16-
slope of the dose-outcome relationship at the lowest observed dose.
17-
3. **Provides bias-corrected confidence intervals** (Calonico, Cattaneo & Titiunik
18-
2014 / `nprobust`-style) and HC2 / Bell-McCaffrey small-sample SEs.
15+
2. **Estimates WAS via local-linear regression at the dose support boundary**
16+
for both Design 1' (the QUG / Quasi-Untreated-Group case where the support
17+
infimum ``d̲ = 0``) and Design 1 (no QUG, ``d̲ > 0``).
18+
3. **Provides bias-corrected confidence intervals** ported from the
19+
``nprobust`` machinery for the continuous-dose paths, and a
20+
structural-residual 2SLS sandwich for the mass-point path.
1921
4. **Extends to multi-period event-study settings** (paper Appendix B.2),
20-
producing per-horizon WAS effects with correlated standard errors and
21-
sup-t bands.
22+
restricting staggered-timing panels to the last-treatment cohort (which
23+
retains never-treated units as comparisons) with pointwise per-horizon CIs.
2224

2325
.. note::
2426

2527
**When to use HAD.** Use ``HeterogeneousAdoptionDiD`` when your panel has
26-
no untreated unit at any treatment period (e.g. universal-rollout policies,
27-
industry-wide tariff changes) but treatment intensity varies across units.
28-
For panels with a never-treated control group and continuous treatment,
29-
use :class:`~diff_diff.ContinuousDiD` instead. For binary reversible
30-
treatments, use :class:`~diff_diff.ChaisemartinDHaultfoeuille`.
28+
no untreated unit at the post period (e.g. universal-rollout policies,
29+
industry-wide tariff changes) but treatment intensity varies across
30+
units. For panels with a never-treated control group and continuous
31+
treatment, use :class:`~diff_diff.ContinuousDiD` instead. For binary
32+
reversible treatments, use :class:`~diff_diff.ChaisemartinDHaultfoeuille`.
33+
34+
.. note::
35+
36+
**Inference contract.** Per-horizon CIs are always pointwise. There are
37+
three SE regimes selected by call site:
38+
39+
- **Unweighted** - continuous paths use the CCT-2014 weighted-robust SE
40+
from the in-house ``lprobust`` port; the mass-point path uses a
41+
structural-residual 2SLS sandwich. No cross-horizon covariance.
42+
- **``weights=`` shortcut** - continuous paths reuse the CCT-2014 SE;
43+
the mass-point path uses an analytical weighted 2SLS sandwich
44+
(``classical`` / ``hc1`` only - ``hc2`` / ``hc2_bm`` raise
45+
``NotImplementedError`` pending a 2SLS-specific leverage derivation).
46+
- **``survey=``** - both paths compose Binder (1983) Taylor-series
47+
linearization with ``df_survey`` threaded into ``safe_inference``.
48+
49+
A simultaneous confidence band (sup-t) is available only on the
50+
**weighted event-study path** via ``cband=True``. Joint cross-horizon
51+
analytical covariance is not computed in this release; tracked in
52+
``TODO.md``.
3153

3254
HeterogeneousAdoptionDiD
3355
------------------------

docs/api/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ Estimators
240240
triple_diff
241241
trop
242242
continuous_did
243+
had
243244
efficient_did
244245
two_stage
245246
wooldridge_etwfe

0 commit comments

Comments
 (0)