Commit 1d64724
Bundles two adjacent extensions to ChaisemartinDHaultfoeuille.by_path:
1. Non-binary integer treatment (Wave 3 #8): replace the
`NotImplementedError` gate at chaisemartin_dhaultfoeuille.py:1870
with a `ValueError` for continuous D (e.g. 1.5) per the no-silent-
failures contract; integer-coded D in Z (e.g. ordinal {0, 1, 2})
is now supported and produces integer-state path tuples
(e.g. (0, 2, 2, 2)). Validated against R `did_multiplegt_dyn(...,
by_path)` for D in {0, 1, 2} via the new
`multi_path_reversible_by_path_non_binary` golden-value scenario:
per-path point estimates match R bit-exactly (rtol ~1e-9 events,
rtol+atol envelope for placebo near-zero values), per-path SE
inherits the documented cross-path cohort-sharing deviation
(~5% rtol; SE_RTOL=0.15 envelope).
2. paths_of_interest kwarg (Wave 3 #9): new estimator parameter
accepting a list of int tuples for explicit user-specified path
selection. Mutually exclusive with by_path=k (raises ValueError
at __init__ and set_params time). Each tuple length validated at
__init__ for uniformity, vs L_max+1 at fit-time. Bool / np.bool_
rejected; np.integer accepted and canonicalized to Python int.
Duplicates emit a UserWarning and dedupe; unobserved paths emit
a UserWarning and are omitted from path_effects. Composes with
non-binary D and all downstream by_path surfaces (bootstrap,
placebos, sup-t bands, controls, trends_linear, trends_nonparam).
Python-only API (R has no list-based selection in by_path).
Threading: paths_of_interest added to 6 path-enumeration helper
signatures (`_enumerate_treatment_paths`, `_compute_path_effects`,
`_compute_path_cumulated_event_study`, `_collect_path_bootstrap_inputs`,
`_compute_path_placebos`, `_collect_path_placebo_bootstrap_inputs`).
The `:1118` preconditions gate (drop_larger_lower / L_max / mutex
with heterogeneity / design2 / honest_did / survey_design) and the
11 `self.by_path is not None` activation branches in fit() rerouted
to fire under either selector.
For D >= 10, R's `did_multiplegt_by_path` derives the per-path
baseline via `substr(path_index$path, 1, 1)` which captures only
the first character of the comma-separated path string (e.g.
captures "1" instead of "12" for path = "12,12,..."), mis-allocating
R's per-path control-pool subset. Python's tuple-key matching is
correct; the parity scenario stays in D in {0, 1, 2} to avoid the R
bug.
Adds:
- `_validate_paths_of_interest` module-level helper for canonicalization
- `TestByPathNonBinary` (10 tests, 3 slow)
- `TestPathsOfInterest` (27 tests, 7 slow)
- `TestDCDHDynRParityByPathNonBinary` (1 parity test)
- R script Scenario 19 + regenerated dcdh_dynr_golden_values.json
- REGISTRY.md sub-paragraphs for non-binary + paths_of_interest
- CHANGELOG.md Unreleased > Added entry
- llms-full.txt kwarg listing for paths_of_interest
Removes: the now-stale `test_forbids_non_binary_treatment` gate-
firing test from TestByPathCoverageFitGates.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 33afb6a commit 1d64724
8 files changed
Lines changed: 1365 additions & 106 deletions
File tree
- benchmarks
- R
- data
- diff_diff
- guides
- docs/methodology
- tests
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
8 | 14 | | |
9 | 15 | | |
10 | 16 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
927 | 927 | | |
928 | 928 | | |
929 | 929 | | |
| 930 | + | |
| 931 | + | |
| 932 | + | |
| 933 | + | |
| 934 | + | |
| 935 | + | |
| 936 | + | |
| 937 | + | |
| 938 | + | |
| 939 | + | |
| 940 | + | |
| 941 | + | |
| 942 | + | |
| 943 | + | |
| 944 | + | |
| 945 | + | |
| 946 | + | |
| 947 | + | |
| 948 | + | |
| 949 | + | |
| 950 | + | |
| 951 | + | |
| 952 | + | |
| 953 | + | |
| 954 | + | |
| 955 | + | |
| 956 | + | |
| 957 | + | |
| 958 | + | |
| 959 | + | |
| 960 | + | |
| 961 | + | |
| 962 | + | |
| 963 | + | |
| 964 | + | |
| 965 | + | |
| 966 | + | |
| 967 | + | |
| 968 | + | |
| 969 | + | |
| 970 | + | |
| 971 | + | |
| 972 | + | |
| 973 | + | |
| 974 | + | |
| 975 | + | |
| 976 | + | |
| 977 | + | |
| 978 | + | |
| 979 | + | |
| 980 | + | |
| 981 | + | |
| 982 | + | |
| 983 | + | |
| 984 | + | |
| 985 | + | |
| 986 | + | |
| 987 | + | |
| 988 | + | |
| 989 | + | |
| 990 | + | |
| 991 | + | |
| 992 | + | |
| 993 | + | |
| 994 | + | |
| 995 | + | |
| 996 | + | |
| 997 | + | |
| 998 | + | |
| 999 | + | |
| 1000 | + | |
| 1001 | + | |
| 1002 | + | |
| 1003 | + | |
| 1004 | + | |
| 1005 | + | |
| 1006 | + | |
| 1007 | + | |
| 1008 | + | |
| 1009 | + | |
| 1010 | + | |
| 1011 | + | |
| 1012 | + | |
| 1013 | + | |
| 1014 | + | |
| 1015 | + | |
| 1016 | + | |
| 1017 | + | |
| 1018 | + | |
| 1019 | + | |
| 1020 | + | |
930 | 1021 | | |
931 | 1022 | | |
932 | 1023 | | |
| |||
0 commit comments