You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
P1 (Methodology): `_compute_conley_vcov` previously used raw `time` values
in `abs(t_i - t_j)`, which meant `conley_lag_cutoff` semantics depended on
label encoding rather than panel-period order. On non-dense encodings
(YYYYMM like 202012/202101, datetime64, or binary `post`-style 0/1 panels)
the raw difference does not equal the count of panel periods, so valid
serial pairs could be silently dropped or misweighted.
The fix normalizes `time` to dense panel-period codes `0..T-1` via
`np.unique(return_inverse=True)` before the lag computation, so
`conley_lag_cutoff` always counts panel periods regardless of how `time`
is encoded (int year, YYYYMM, datetime64, pd.Period, strings). The
spatial within-period loop also uses the same dense codes for consistency.
On dense integer labels (the parity-test convention) this is a no-op and
R conleyreg parity holds at 1e-14; on non-dense encodings diff-diff is
the more robust default vs R's literal label-difference convention.
P3 (Maintainability): `_format_vcov_label` in results.py gains a "conley"
branch and surfaces "Conley spatial HAC (1999)" in DiD/MPD/TWFE result
summaries (was previously omitting the label because Conley used to be
unreachable on the panel surface).
Doc surfaces:
- REGISTRY § ConleySpatialHAC: new "Note (deviation from R conleyreg
literal: time-label normalization)" documenting the dense-code
convention and the R-divergence on non-dense encodings.
- llms-full.txt: fixed the misleading `time="post", conley_lag_cutoff=2`
example (now uses `time="period"`), added a "Note on
`conley_lag_cutoff` semantics" paragraph.
Regression tests:
- `TestConleyPanelHelper::test_time_label_normalization_non_unit_spaced_int`:
year-like (2020, 2021, 2022) and YYYYMM (202011, 202012, 202101) labels
produce the same vcov as dense codes (1, 2, 3).
- `TestConleyPanelHelper::test_time_label_normalization_datetime64`:
irregularly-spaced datetime64 labels normalize correctly.
- `TestConleyTWFE::test_twfe_conley_binary_post_label_normalization`:
TWFE with binary `post` (the exact example the codex reviewer flagged)
produces finite SE.
- `TestConleyTWFE::test_twfe_conley_summary_emits_conley_label`:
summary contains "Conley spatial HAC" for panel Conley fits.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: docs/methodology/REGISTRY.md
+13Lines changed: 13 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2988,6 +2988,19 @@ through). diff-diff matches this asymmetry exactly for R parity. Independent
2988
2988
temporal kernel choice would be a follow-up API extension if user demand
2989
2989
emerges.
2990
2990
2991
+
**Note (deviation from R conleyreg literal: time-label normalization):**
2992
+
R `conleyreg` uses raw `time` values directly in the lag computation
2993
+
(`time_dist.cpp`'s `t_diff = abs(times - times[i])`). On non-dense time
2994
+
encodings (e.g., `time = 202012, 202101` for monthly panels), the raw
2995
+
difference is 89, so a `lag_cutoff=1` request silently drops valid lag-1
2996
+
serial pairs in R. diff-diff normalizes `time` to dense panel-period codes
2997
+
`0..T-1` via `np.unique(return_inverse=True)` before the lag computation,
2998
+
so `conley_lag_cutoff` always counts panel periods regardless of label
2999
+
encoding (int year, YYYYMM, datetime64, `pd.Period`, strings). On dense
3000
+
integer labels (the parity-test convention), the two paths produce
3001
+
bit-identical results. For non-dense encodings, diff-diff is the more
3002
+
robust default; pass `time` as a dense integer index for bit-exact R parity.
3003
+
2991
3004
**Kernel functions:**
2992
3005
-`conley_kernel="bartlett"` (default): `K(u) = max(0, 1 - |u|)` evaluated on the pairwise distance `d_ij/h`. The radial 1-D form on pairwise distance, matching R `conleyreg`, Stata `acreg` (Colella et al. 2019), and Hsiang (2010).
2993
3006
-`conley_kernel="uniform"`: `K(u) = 1{|u| ≤ 1}`. Conley 1999 page 11; spectral window negative in regions (footnote 11).
0 commit comments