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
Address CI AI review: NaN first_treat + StaggeredTripleDifference coverage
Two new P1 findings from CI AI re-review:
1. ContinuousDiD.fit() still accepted NaN `first_treat` values. NaN
survives preprocessing but satisfies neither the treated (g > 0)
nor never-treated (g == 0) mask, so affected units were silently
excluded from both pools — same silent-failure shape as the
already-rejected `first_treat < 0`. Reject NaN explicitly with
ValueError + row count.
2. `StaggeredTripleDifference.fit()` silently recoded
`first_treat=np.inf -> 0` via `.replace([np.inf, float("inf")], 0)`.
Its sibling `staggered.py:1508-1519` already surfaces this with a
UserWarning; this PR mirrors that contract so the estimator no
longer shifts units between treated and never-treated pools
without signaling. REGISTRY gets a matching **Note:** under the
StaggeredTripleDifference section.
Regression tests:
- test_nan_first_treat_raises_with_row_count (ContinuousDiD) on a
4-unit x 3-period panel with 3 NaN rows.
- test_inf_first_treat_works (StaggeredTripleDifference) upgraded
from silent-success to `pytest.warns(UserWarning, match=row-count)`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Covariates `X_i`: time-invariant (first observation per unit used)
1695
+
-**Note:**`first_treat=inf` (R-style never-enabled marker) is accepted and normalized to `0` internally. The recoding now emits a `UserWarning` reporting the affected row count so the reclassification is not silent (axis-E silent coercion under the Phase 2 audit, mirroring the StaggeredDiD behavior). Pass `first_treat=0` directly to avoid the warning.
1695
1696
1696
1697
*Estimator equation (Equation 4.1 in paper, as implemented):*
0 commit comments