Commit b37cc98
committed
feat(v4): TWFE event-study mode absorbs MultiPeriodDiD - M-010/M-060/M-082 (phase 3(a))
TwoWayFixedEffects.fit(..., event_study=True, time=<calendar>,
spec="within"|"pooled", reference_period=None, post_periods=[...])
estimates per-period treatment effects and returns the unified
EventStudyResults surface natively. spec="pooled" is the MultiPeriodDiD
design verbatim (shared estimation core - bit-exact under matched
cluster settings, unconditional in the unit-less repeated-cross-sections
form); spec="within" (default) absorbs the unit FE and omits the
spanned treatment main effect. MultiPeriodDiD (+ the EventStudy alias)
is deprecated with a construction FutureWarning naming the successor;
static fit(time=) is renamed to post= behind the M-030-style shim
(time= survives as the ES calendar column; 4.0 enforcement is M-083).
Core mechanics:
- DifferenceInDifferences._fit_event_study_core is the relocated
MPD.fit body, parameterized (include_treatment_main,
warn_legacy_reference_default, cluster_override, estimator_name,
_frame_offset) - MPD numerics, messages, and warning attribution are
bit-identical pre/post extraction (attribution pins included).
- The mode carries TWFE's inference stack from day one: unit
auto-cluster with the static carve-outs mirrored lane-for-lane
(dropped on Conley - no implicit spatial x unit product kernel; never
injected as a survey PSU; dropped for explicit one-way analytical
families), a day-one wild-bootstrap ValueError, and no legacy
reference-period warning.
- post_periods= is REQUIRED (non-empty, duplicate-free) in ES mode: the
treatment boundary is not observable from the documented
time-invariant ever-treated indicator, so the MPD midpoint default
would silently guess the reference/partition; MPD itself keeps its
documented default through 3.9. ES calls pass time=/unit= as keywords
(slot 4 stays post= through the M-082 window).
- EventStudyResults gains two provenance fields (M-092 amendment #5):
the authoritative post_periods calendar partition (content-validated,
threaded by _from_mpd) and estimation_spec ({within,pooled}, TWFE
producer only); both serialize through to_dict().
Consumer ports:
- HonestDiD and PreTrendsPower gain calendar container routes with
native-route parity: the partition provenance reconstructs exactly
the inputs the native MPD branches read, including the
reference-anchored Roth gamma-unit plumbing (string-label degradation
reproduced, not bypassed). HonestDiD is geometry-scoped to
chronological partitions (suffix post set, last-pre reference) per
the Rambachan-Roth positional restriction system; the pre-existing
native-route permissiveness is documented (REGISTRY Note) and
deferred (DEFERRED.md row). Both calendar routes share the hardened
container-vcov contract (duplicate/incomplete vcov_index fail loud,
_validate_vcov_subblock, HonestDiD with allow_singular=False, warned
diagonal fallback only when no matrix is stored), require finite
effects alongside finite positive SEs where their native conventions
do, guard empty pre AND post retained sets (the post guard added to
the native HonestDiD sibling too), fail closed on invalid explicit
pre_periods= selections in calendar chronology, and warn on string
calendar labels (chronology unverifiable; sorted() order assumed,
matching the fit's own rule).
- plot_event_study derives the pre/post split from the partition
provenance with per-contiguous-run pre-shading on both renderers.
- DiagnosticReport and BusinessReport explicitly reject
EventStudyResults (previously a silent empty-applicability report /
all-null headline); admission is a tracked backlog row.
Sweeps and hygiene:
- ~140 static TWFE/DiD time= keyword callers migrated to post= across
tests, docs, guides, and benchmarks (receiver-resolved per site;
legitimate time= params on CiC/QDiD/TripleDiff/MPD/placebo surfaces
untouched; deliberate shim-test usage retained).
- MPD deprecation shim: forwarding __init__ + import-time __signature__
mirror keeps BaseEstimator introspection working; pyproject
filterwarnings ignore for the suite-noise window; naming-guard
_FORWARDING_INIT_SHIMS registry keeps MPD in DiD's init-sharing
group.
- ES within + hc2/hc2_bm gains the static path's dense full-dummy
memory preflight (column-presence guarded).
- REGISTRY: TWFE "Event-study mode (3.9)" subsection (designs,
estimate-shift, auto-cluster + carve-outs, wild raise, explicit
partition, staggered-adoption detection limit, string-label
chronology); the pre-existing singleton edge-case overclaim corrected
to the RETAINED behavior with a Deviation-from-R Note (reghdfe drops,
fixest retains; execution-verified on both paths); MPD deprecation
Note; HonestDiD positional-geometry Notes.
- v4-deprecations ledger: M-010 shimmed/phase 5, M-082 shimmed, M-060
planned/phase 5 (warning rides the parent), M-092 amendment #5, M-093
admission amendment, M-011/M-080 cross-notes; v4-design section 4.1
keyword + required-partition amendments (dated, same-diff).
- tests/test_v4_merge_mpd.py (72 tests): the section 4.1 gate triple +
the within numerical gate, mode/rename validation, wild-raise
precedence, auto-cluster carve-out behavioral pins, deprecation
choreography, surface contract (incl. replicate-survey numerical
lane), inference integrity (rank-deficiency NaN tuple, attribution
baselines, singleton class-consistency), and consumer lanes
(parity, geometry/provenance/vcov-integrity rejections, string-label
warning, explicit-selection validation, plot geometry on both
renderers). Parity assertions are mask-first (_eq_with_nans /
_close_with_nans) so NaN-vs-zero regressions cannot be equated.
- Teaching surfaces migrated off MultiPeriodDiD / static time=:
quickstart, choosing_estimator, troubleshooting, homepage estimator
table, api pages (executed examples), practitioner decision tree,
README catalog line, and all four bundled guides; docs build -W green
with all post-build HTML guards.1 parent e891f25 commit b37cc98
65 files changed
Lines changed: 3558 additions & 544 deletions
File tree
- benchmarks
- python
- speed_review
- diff_diff
- guides
- visualization
- docs
- api
- _autosummary
- methodology
- tests
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
10 | 52 | | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
11 | 69 | | |
12 | 70 | | |
13 | 71 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
174 | 174 | | |
175 | 175 | | |
176 | 176 | | |
177 | | - | |
178 | | - | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
179 | 181 | | |
180 | 182 | | |
181 | 183 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
| 23 | + | |
23 | 24 | | |
24 | 25 | | |
25 | 26 | | |
| |||
104 | 105 | | |
105 | 106 | | |
106 | 107 | | |
107 | | - | |
| 108 | + | |
108 | 109 | | |
109 | 110 | | |
110 | 111 | | |
| |||
126 | 127 | | |
127 | 128 | | |
128 | 129 | | |
| 130 | + | |
129 | 131 | | |
130 | 132 | | |
131 | 133 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
90 | 90 | | |
91 | 91 | | |
92 | 92 | | |
93 | | - | |
| 93 | + | |
94 | 94 | | |
95 | 95 | | |
96 | 96 | | |
| |||
100 | 100 | | |
101 | 101 | | |
102 | 102 | | |
103 | | - | |
| 103 | + | |
104 | 104 | | |
105 | 105 | | |
106 | 106 | | |
| |||
0 commit comments