Skip to content

Add WooldridgeDiD (ETWFE) estimator#265

Closed
igerber wants to merge 2 commits intomainfrom
wooldridge
Closed

Add WooldridgeDiD (ETWFE) estimator#265
igerber wants to merge 2 commits intomainfrom
wooldridge

Conversation

@igerber
Copy link
Copy Markdown
Owner

@igerber igerber commented Apr 4, 2026

Summary

  • Rebase and forge third-party contribution (PR Feature/wooldridge did #216, @wenddymacro) implementing Wooldridge (2025, 2023) Extended Two-Way Fixed Effects estimator
  • OLS, logit, and Poisson QMLE paths with ASF-based ATT and delta-method SEs
  • Four aggregation types (simple, group, calendar, event) following Stata jwdid_estat
  • Fixed QMLE sandwich to use weight_type="aweight" for correct unweighted scores
  • Fixed control_group="never_treated" to correctly exclude pre-treatment observations from treated units (P0 from AI review)
  • Fixed nonlinear rank-deficiency handling, bootstrap_weights validation, n_control_units metadata
  • Added solve_poisson IRLS solver to linalg.py
  • 63 tests covering all paths, edge cases, control group distinction, and methodology checks

Methodology references (required if estimator / math changes)

  • Method name(s): WooldridgeDiD / Extended Two-Way Fixed Effects (ETWFE)
  • Paper / source link(s):
  • Any intentional deviations from the source (and why):
    • Cell-level aggregation weights (n_{g,t}) instead of W2025 Eqs. 7.2-7.4 cohort-share weights — matches Stata jwdid_estat (documented in REGISTRY.md)
    • QMLE cluster-robust small-sample adjustment uses (G/(G-1))*(n-1)/(n-k) vs Stata's G/(G-1) only — conservative, inflates SEs slightly (documented in REGISTRY.md and TODO.md)
    • R's etwfe uses fixest for nonlinear paths; this uses direct QMLE via compute_robust_vcov (documented in REGISTRY.md)

Validation

  • Tests added/updated: tests/test_wooldridge.py (63 tests), tests/test_linalg.py (4 solve_poisson tests)
  • Backtest / simulation / notebook evidence (if applicable): docs/tutorials/16_wooldridge_etwfe.ipynb
  • Paper review: docs/methodology/papers/wooldridge-etwfe-review.md

Security / privacy

  • Confirm no secrets/PII in this PR: Yes

Generated with Claude Code

igerber and others added 2 commits April 4, 2026 10:05
Rebase and forge third-party contribution (wenddymacro) implementing
Wooldridge (2025, 2023) Extended Two-Way Fixed Effects estimator.

- OLS, logit, and Poisson QMLE paths with ASF-based ATT
- Delta-method SEs for nonlinear models, cluster-robust sandwich
- Four aggregation types (simple, group, calendar, event)
- Fixed QMLE sandwich to use weight_type="aweight" for correct
  unweighted scores in bread computation
- Added solve_poisson IRLS solver to linalg.py
- Complete documentation: REGISTRY, README, CHANGELOG, tutorial
- 60 tests covering all paths, edge cases, and methodology checks

Co-Authored-By: wenddymacro <50739376+wenddymacro@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… P2s

P0: Fix _filter_sample so control_group="never_treated" excludes
pre-treatment observations from treated units. Previously both
settings produced identical samples (treated_mask=cohort>0 kept
all treated-unit obs regardless). Now never_treated restricts to
post-treatment obs from treated units + all never-treated obs.

P1: Add NaN checks in logit/Poisson ASF loops to skip cells whose
interaction coefficients were dropped due to rank deficiency.
Zero out NaN entries in beta before vcov computation.

P2a: Validate bootstrap_weights in __init__ — invalid values now
raise ValueError instead of silently falling through to Mammen.

P2b: Fix n_control_units metadata to count not-yet-treated units
when control_group="not_yet_treated" (was counting only cohort==0).

P3a: Change bootstrap loop to return_vcov=False (only coefs used).

P3b: Soften "matches Stata exactly" claims in tutorial to
"follows the jwdid specification" with registry deviation note.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@igerber
Copy link
Copy Markdown
Owner Author

igerber commented Apr 4, 2026

Moving these changes to PR #216 (original contributor's PR) so @wenddymacro gets proper credit.

@igerber igerber closed this Apr 4, 2026
@igerber
Copy link
Copy Markdown
Owner Author

igerber commented Apr 4, 2026

/ai-review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant