Skip to content

Commit 7404815

Browse files
igerberclaude
andcommitted
Fix remaining DR fallback text, update test comments for Peduzzi convention
Make all fallback warnings and docstrings method-specific: IPW says covariates dropped, DR says propensity model unconditional while outcome regression still uses covariates. Update test comments from old intercept-inclusive arithmetic to predictor-variable counts. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 402b79c commit 7404815

5 files changed

Lines changed: 14 additions & 10 deletions

File tree

diff_diff/staggered.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,8 +205,9 @@ class CallawaySantAnna(
205205
- "error": Raise the exception (default). Ensures the user is
206206
aware of estimation failures.
207207
- "unconditional": Fall back to unconditional propensity
208-
``n_treated / (n_treated + n_control)`` with a warning. This
209-
effectively drops all covariates for the affected cell.
208+
with a warning. For IPW, this drops all covariates. For DR,
209+
the propensity model becomes unconditional but outcome
210+
regression still uses covariates.
210211
When ``rank_deficient_action="error"``, errors are always
211212
re-raised regardless of this setting.
212213

diff_diff/staggered_triple_diff.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1389,7 +1389,8 @@ def _compute_pscore(
13891389
warnings.warn(
13901390
f"Propensity score estimation failed{ctx}. "
13911391
f"Falling back to unconditional propensity "
1392-
f"(all covariates dropped for this cell). "
1392+
f"(propensity model ignores covariates; outcome "
1393+
f"regression still uses them for DR). "
13931394
f"Consider estimation_method='reg' to avoid "
13941395
f"propensity scores entirely.",
13951396
UserWarning,

diff_diff/triple_diff.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,9 @@ class TripleDifference:
398398
Action when propensity score estimation fails:
399399
- "error": Raise the exception (default)
400400
- "unconditional": Fall back to unconditional propensity with
401-
a warning (drops all covariates for the affected comparison)
401+
a warning. For IPW, drops all covariates. For DR, the
402+
propensity model becomes unconditional but outcome regression
403+
still uses covariates.
402404
When ``rank_deficient_action="error"``, errors are always
403405
re-raised regardless of this setting.
404406
@@ -1040,8 +1042,8 @@ def _estimate_ddd_decomposition(
10401042
ps_estimated = False
10411043
warnings.warn(
10421044
f"Propensity score estimation failed for subgroup "
1043-
f"{j} vs 4; dropping covariates and using "
1044-
f"unconditional probability. "
1045+
f"{j} vs 4; using unconditional probability. "
1046+
f"For DR, outcome regression still uses covariates. "
10451047
f"Consider estimation_method='reg' to avoid propensity "
10461048
f"scores entirely.",
10471049
UserWarning,

tests/test_linalg.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1683,7 +1683,7 @@ def test_epv_warning_below_threshold(self):
16831683
from diff_diff.linalg import solve_logit
16841684

16851685
rng = np.random.default_rng(42)
1686-
# 40 events (minority class), 9 params (8 covariates + intercept) → EPV = 4.4
1686+
# 40 events (minority class), 8 predictor variables → EPV = 5.0
16871687
n = 200
16881688
X = rng.standard_normal((n, 8))
16891689
y = np.concatenate([np.ones(40), np.zeros(n - 40)])
@@ -1695,7 +1695,7 @@ def test_epv_no_warning_above_threshold(self):
16951695
from diff_diff.linalg import solve_logit
16961696

16971697
rng = np.random.default_rng(42)
1698-
# 100 events, 3 params (2 covariates + intercept) → EPV = 33.3
1698+
# 100 events, 2 predictor variables → EPV = 50
16991699
n = 200
17001700
X = rng.standard_normal((n, 2))
17011701
y = np.concatenate([np.ones(100), np.zeros(100)])
@@ -1725,7 +1725,7 @@ def test_epv_threshold_configurable(self):
17251725
rng = np.random.default_rng(42)
17261726
n = 200
17271727
X = rng.standard_normal((n, 2))
1728-
# 15 events, 3 params → EPV = 5.0
1728+
# 15 events, 2 predictor variables → EPV = 7.5
17291729
y = np.concatenate([np.ones(15), np.zeros(n - 15)])
17301730

17311731
# Default threshold 10 → should warn (EPV=5)

tests/test_staggered.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3760,7 +3760,7 @@ def test_cs_diagnose_propensity_identifies_critical(self):
37603760
data, outcome="outcome", unit="unit", time="time",
37613761
first_treat="first_treat", covariates=["x1", "x2", "x3"],
37623762
)
3763-
# With 1 treated unit and 3 covariates: EPV = 1/4 = 0.25 → critical
3763+
# With 1 treated unit and 3 predictor variables: EPV = 1/3 ≈ 0.33 → critical
37643764
assert any(df["status"] == "critical")
37653765

37663766
def test_cs_epv_in_summary_output(self):

0 commit comments

Comments
 (0)