Skip to content

Commit 0e537b0

Browse files
committed
Merge branch 'main' into feature/dcdh-survey-variance-extensions
Absorbs #312 (sdid scale fix), #313 (roadmap refresh + dCDH docstring rewrite), and #314 (within_transform convergence warnings) from main. Conflicts resolved in: - diff_diff/chaisemartin_dhaultfoeuille.py: took main's comprehensive Phase 1-3 feature list in the class docstring but merged in the PR #311 group-vs-PSU bootstrap-clustering framing and the replicate-weight survey-support line. Kept the PR #311 'user-specified cluster= not supported + automatic PSU-level under survey_design' wording for the cluster= parameter docstring (strictly more accurate than main's 'always clusters at the group level' text). - diff_diff/guides/llms-full.txt: kept main's more detailed placebo SE contract paragraph (which already distinguishes single-period NaN from multi-horizon analytical/bootstrap) and appended the sup-t / shared-weights / cross-horizon coverage details from the PR #311 update. Kept the PR #311 survey_design signature comment that mentions TSL + replicate + PSU bootstrap. Full regression across touched areas: 336 + 324 passing.
2 parents 9368ae6 + 44e7522 commit 0e537b0

22 files changed

Lines changed: 819 additions & 425 deletions

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Changed
11+
- Refresh `ROADMAP.md` to drop top-level phase numbering and reflect shipped state through v3.1.1. Absorbs dCDH into the Current State estimator list; adds Recently Shipped summary; reorganizes open work as Shipping Next / Under Consideration / AI-Agent Track / Long-term. Updates `docs/business-strategy.md`, `docs/survey-roadmap.md`, `docs/practitioner_decision_tree.rst`, `docs/choosing_estimator.rst`, `docs/api/chaisemartin_dhaultfoeuille.rst`, `README.md`, and `diff_diff/guides/llms-full.txt` to remove stale phase-deferral language now that the deferred items have shipped.
12+
1013
## [3.1.1] - 2026-04-16
1114

1215
### Added

README.md

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,7 +1113,7 @@ results = stacked_did(
11131113

11141114
### Efficient DiD (Chen, Sant'Anna & Xie 2025)
11151115

1116-
Efficient DiD achieves the semiparametric efficiency bound for ATT estimation in staggered adoption designs. It optimally weights across all valid comparison groups and baselines via the inverse covariance matrix Omega*, producing tighter confidence intervals than standard estimators like Callaway-Sant'Anna when the stronger PT-All assumption holds.
1116+
Efficient DiD achieves the semiparametric efficiency bound for ATT estimation in staggered adoption designs along the **no-covariate path**, producing tighter confidence intervals than standard estimators when the stronger PT-All assumption holds. It optimally weights across all valid comparison groups and baselines via the inverse covariance matrix Omega*. A doubly-robust covariate path is also available: it is consistent if either the outcome regression or the sieve propensity ratio is correctly specified, but the linear OLS outcome regression does not generically attain the efficiency bound unless the conditional mean is linear in the covariates.
11171117

11181118
```python
11191119
from diff_diff import EfficientDiD, generate_staggered_data
@@ -1148,24 +1148,29 @@ EfficientDiD(
11481148
)
11491149
```
11501150

1151-
> **Note:** Phase 1 supports the no-covariates path only. Use CallawaySantAnna with
1152-
> `estimation_method='dr'` if you need covariate adjustment.
1151+
> **Note:** EfficientDiD supports covariate adjustment via a doubly-robust path
1152+
> (sieve-based propensity score ratios and a linear OLS outcome regression).
1153+
> The DR property gives consistency if either the OR or the PS is correctly
1154+
> specified, but the OLS working model for the outcome regression does not
1155+
> generically attain the semiparametric efficiency bound. The unqualified
1156+
> efficiency-bound claim applies to the no-covariate path only. See the
1157+
> `covariates` parameter on `fit()` and `docs/methodology/REGISTRY.md`.
11531158
11541159
**When to use Efficient DiD vs Callaway-Sant'Anna:**
11551160

11561161
| Aspect | Efficient DiD | Callaway-Sant'Anna |
11571162
|--------|--------------|-------------------|
11581163
| Approach | Optimal EIF-based weighting | Separate 2x2 DiD aggregation |
11591164
| PT assumption | PT-All (stronger) or PT-Post | Conditional PT |
1160-
| Efficiency | Achieves semiparametric bound | Not efficient |
1161-
| Covariates | Not yet (Phase 2) | Supported (OR, IPW, DR) |
1165+
| Efficiency | Achieves semiparametric bound on the no-covariate path; DR covariate path is consistent but does not generically attain the bound under a linear OLS outcome regression | Not efficient |
1166+
| Covariates | Supported (doubly robust, sieve-based PS + linear OLS OR) | Supported (OR, IPW, DR) |
11621167
| When to choose | Maximum efficiency, PT-All credible | Covariates needed, weaker PT |
11631168

11641169
### de Chaisemartin-D'Haultfœuille (dCDH) for Reversible Treatments
11651170

11661171
`ChaisemartinDHaultfoeuille` (alias `DCDH`) is the only library estimator that handles **non-absorbing (reversible) treatments** — treatment can switch on AND off over time. This is the natural fit for marketing campaigns, seasonal promotions, on/off policy cycles.
11671172

1168-
Ships `DID_M` (= `DID_1` at horizon `l = 1`) plus the full multi-horizon event study `DID_l` for `l = 1..L_max` via the `L_max` parameter. Phase 3 will add covariate adjustment.
1173+
Ships `DID_M` (= `DID_1` at horizon `l = 1`), the full multi-horizon event study `DID_l` for `l = 1..L_max` via the `L_max` parameter, residualization-style covariate adjustment (`controls`), group-specific linear trends (`trends_linear`), state-set-specific trends (`trends_nonparam`), heterogeneity testing, non-binary treatment, HonestDiD sensitivity integration on placebos, and survey support via Taylor-series linearization.
11691174

11701175
```python
11711176
from diff_diff import ChaisemartinDHaultfoeuille
@@ -1221,7 +1226,7 @@ ChaisemartinDHaultfoeuille(
12211226
| `n_groups_dropped_crossers`, `n_groups_dropped_singleton_baseline` | Filter counts (multi-switch groups dropped before estimation; singleton-baseline groups excluded from variance) |
12221227
| `n_groups_dropped_never_switching` | Backwards-compatibility metadata. Never-switching groups participate in the variance via stable-control roles; this field is no longer a filter count. |
12231228

1224-
**Multi-horizon event study** (Phase 2 - pass `L_max` to `fit()`):
1229+
**Multi-horizon event study** (pass `L_max` to `fit()`):
12251230

12261231
```python
12271232
results = est.fit(data, outcome="outcome", group="group",
@@ -1260,13 +1265,13 @@ print(f"Fraction of negative weights: {diagnostic.fraction_negative:.3f}")
12601265
print(f"sigma_fe (sign-flipping threshold): {diagnostic.sigma_fe:.3f}")
12611266
```
12621267

1263-
> **Note:** Placebo SE is `NaN` for both the single-lag `DID_M^pl` and the dynamic placebos `DID^{pl}_l`. The point estimates are meaningful for visual pre-trends inspection; formal placebo inference (influence-function derivation) is deferred to a follow-up. See `REGISTRY.md` for the full contract.
1268+
> **Note:** Placebo SE is `NaN` for the single-period `DID_M^pl` (`L_max=None`) because the per-period aggregation path has no influence-function derivation; the point estimate is meaningful for visual pre-trends inspection. Multi-horizon dynamic placebos `DID^{pl}_l` (`L_max >= 1`) have valid analytical SE via the same cohort-recentered plug-in variance as the positive horizons, with bootstrap SE available when `n_bootstrap > 0`. See `docs/methodology/REGISTRY.md` for the full contract.
12641269
12651270
> **Note:** By default (`drop_larger_lower=True`), the estimator drops groups whose treatment switches more than once before estimation. This matches R `DIDmultiplegtDYN`'s default and is required for the analytical variance formula to be consistent with the point estimate. Each drop emits an explicit warning.
12661271
1267-
> **Note:** Phase 1 requires panels with a **balanced baseline** (every group observed at the first global period) and **no interior period gaps**. Late-entry groups (missing the baseline) raise `ValueError`; interior-gap groups are dropped with a warning; terminally-missing groups (early exit / right-censoring) are retained and contribute from their observed periods only. This is a documented deviation from R `DIDmultiplegtDYN`, which supports unbalanced panels see [`docs/methodology/REGISTRY.md`](docs/methodology/REGISTRY.md) for the rationale, the defensive guards that make terminal missingness safe, and workarounds for unbalanced inputs.
1272+
> **Note:** The estimator requires panels with a **balanced baseline** (every group observed at the first global period) and **no interior period gaps**. Late-entry groups (missing the baseline) raise `ValueError`; interior-gap groups are dropped with a warning; terminally-missing groups (early exit / right-censoring) are retained and contribute from their observed periods only. This is a documented deviation from R `DIDmultiplegtDYN`, which supports unbalanced panels - see [`docs/methodology/REGISTRY.md`](docs/methodology/REGISTRY.md) for the rationale, the defensive guards that make terminal missingness safe, and workarounds for unbalanced inputs.
12681273
1269-
> **Note:** Survey design (`survey_design`), covariate adjustment (`controls`), group-specific linear trends (`trends_linear`), and HonestDiD integration (`honest_did`) are not yet supported. They raise `NotImplementedError` with phase pointers - see [`ROADMAP.md`](ROADMAP.md) for the Phase 3 rollout.
1274+
> **Note:** Survey design is supported via Taylor-series linearization on `pweight` with strata / PSU / FPC. Replicate-weight variance and PSU-level bootstrap for dCDH are a planned extension. The `aggregate` parameter still raises `NotImplementedError`.
12701275
12711276
### Triple Difference (DDD)
12721277

0 commit comments

Comments
 (0)