Skip to content

Commit e73a6c4

Browse files
committed
PR #457 R1 polish: qualify docstring parity claim + refresh skip message
R1 verdict was Looks good with 2 P3 informational items. Both addressed: 1. P3 (Documentation/Tests): `bacon_decompose()` docstring example said "matches R bacondecomp::bacon() at atol=1e-6" without mentioning the documented always-treated convention exception. Qualified the example to spell out the aggregate-vs-per-component split: aggregate parity holds for all panels at atol=1e-6, per-component parity holds when first_treat is bounded below by min(time) (no always-treated), and the divergence on always-treated panels is by convention (Python remap-to-U vs R's `Later vs Always Treated`). Cross-references the REGISTRY note for the full contract. 2. P3 (Documentation/Tests): `TestBaconParityR`'s skip message still said the goldens were "deferred until R is provisioned (see TODO.md)" but the TODO row was removed in this PR. Updated to describe the intended skip case (partial-checkout / packaging scenarios where the committed JSON is unavailable) and dropped the TODO reference. Tests unchanged: 33/33 pass in test_methodology_bacon.py.
1 parent 7beef1a commit e73a6c4

2 files changed

Lines changed: 13 additions & 5 deletions

File tree

diff_diff/bacon.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1302,8 +1302,15 @@ def bacon_decompose(
13021302
>>> from diff_diff import bacon_decompose
13031303
>>>
13041304
>>> # Default: paper-faithful Goodman-Bacon (2021) Theorem 1 weights
1305-
>>> # (weights="exact"); matches R bacondecomp::bacon() at atol=1e-6
1306-
>>> # (validated via tests/test_methodology_bacon.py::TestBaconParityR).
1305+
>>> # (weights="exact"); matches R bacondecomp::bacon() at atol=1e-6 on
1306+
>>> # the aggregate (TWFE coefficient + weights-sum) across all panels,
1307+
>>> # and on the per-component breakdown when first_treat is bounded
1308+
>>> # below by min(time) (no always-treated). For panels with
1309+
>>> # always-treated units, the per-component breakdown diverges by
1310+
>>> # convention (Python remaps to U per paper footnote 11; R emits
1311+
>>> # `Later vs Always Treated`); see REGISTRY note on R parity
1312+
>>> # convention divergence. Validated via
1313+
>>> # tests/test_methodology_bacon.py::TestBaconParityR.
13071314
>>> results = bacon_decompose(
13081315
... data=panel_df,
13091316
... outcome='earnings',

tests/test_methodology_bacon.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -301,11 +301,12 @@ def test_eq_9_later_vs_earlier_variance(self) -> None:
301301
def _load_r_golden() -> dict:
302302
if not _R_GOLDEN_PATH.exists():
303303
pytest.skip(
304-
f"R parity goldens missing at {_R_GOLDEN_PATH}. To generate, "
304+
f"R parity goldens missing at {_R_GOLDEN_PATH}. To regenerate, "
305305
"install R + `install.packages('bacondecomp')` + "
306306
"`install.packages('jsonlite')` then `cd benchmarks/R && "
307-
"Rscript generate_bacon_golden.R`. The R goldens are deferred "
308-
"until R is provisioned (see TODO.md)."
307+
"Rscript generate_bacon_golden.R`. The goldens are committed "
308+
"to the repo by default; this skip path covers partial-checkout "
309+
"or packaging scenarios where the JSON file is unavailable."
309310
)
310311
return json.loads(_R_GOLDEN_PATH.read_text())
311312

0 commit comments

Comments
 (0)