Skip to content

Commit ae7f687

Browse files
igerberclaude
andcommitted
Relax Bacon survey validation to exact-only and document fweight exclusions from PR #226 review (round 19)
- BaconDecomposition: move _validate_unit_constant_survey behind weights="exact" — approximate path uses obs-level means and doesn't need within-unit-constant survey columns - REGISTRY.md: document StackedDiD fweight rejection and Bacon exact-only unit-constancy requirement - survey-roadmap.md: update StackedDiD support to "Full (pweight/aweight)" Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 5bdbcce commit ae7f687

3 files changed

Lines changed: 8 additions & 5 deletions

File tree

diff_diff/bacon.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -478,8 +478,11 @@ def fit(
478478
_resolve_survey_for_fit(survey_design, data, "analytical")
479479
)
480480

481-
# Validate within-unit constancy for panel survey designs
482-
if resolved_survey is not None:
481+
# Validate within-unit constancy for exact survey weights only.
482+
# The exact-weight path collapses to per-unit weights via groupby().first(),
483+
# which requires constant survey columns within units. The approximate path
484+
# uses observation-level weighted means and does not need this constraint.
485+
if resolved_survey is not None and self.weights == "exact":
483486
from diff_diff.survey import _validate_unit_constant_survey
484487

485488
_validate_unit_constant_survey(data, unit, survey_design)

docs/methodology/REGISTRY.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1021,7 +1021,7 @@ The paper text states a stricter bound (T_min + 1) but the R code by the co-auth
10211021
- [x] Anticipation parameter support
10221022
- [x] Never-treated encoding (0 and inf)
10231023
- [x] Survey design support (Phase 3): Q-weights compose multiplicatively with survey weights; TSL vcov on composed weights; survey design columns propagated through sub-experiments
1024-
- **Note:** Survey weights compose multiplicatively with Q-weights for StackedDiD
1024+
- **Note:** Survey weights compose multiplicatively with Q-weights for StackedDiD; `weight_type="fweight"` is rejected because Q-weight composition produces non-integer composed weights that break frequency-weight semantics
10251025

10261026
---
10271027

@@ -1576,7 +1576,7 @@ Weights depend on group sizes and variance in treatment timing.
15761576
- [ ] TWFE coefficient ≈ weighted sum of 2×2 estimates
15771577
- [ ] Visualization shows weight vs. estimate by comparison type
15781578
- [x] Survey design support (Phase 3): weighted cell means, weighted within-transform, weighted group shares
1579-
- **Note:** Bacon decomposition with survey weights is diagnostic; exact-sum guarantee is approximate
1579+
- **Note:** Bacon decomposition with survey weights is diagnostic; exact-sum guarantee is approximate; `weights="exact"` requires within-unit-constant survey columns (approximate path accepts time-varying weights)
15801580

15811581
---
15821582

docs/survey-roadmap.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Phases 1-3 are implemented. Phases 4-5 are deferred for future PRs.
1818

1919
| Estimator | File | Survey Support | Notes |
2020
|-----------|------|----------------|-------|
21-
| StackedDiD | `stacked_did.py` | Full | Q-weights compose multiplicatively with survey weights; TSL vcov on composed weights |
21+
| StackedDiD | `stacked_did.py` | Full (pweight/aweight) | Q-weights compose multiplicatively with survey weights; TSL vcov on composed weights; fweight rejected (non-integer composition) |
2222
| SunAbraham | `sun_abraham.py` | Full | Survey weights in LinearRegression + weighted within-transform; bootstrap+survey deferred |
2323
| BaconDecomposition | `bacon.py` | Diagnostic | Weighted cell means, weighted within-transform, weighted group shares; no inference (diagnostic only) |
2424
| TripleDifference | `triple_diff.py` | Reg only | Regression method with weighted OLS + TSL on influence functions; IPW/DR deferred (needs weighted `solve_logit()`) |

0 commit comments

Comments
 (0)