diff-diff 3.7.0__tar.gz → 3.9.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. {diff_diff-3.7.0 → diff_diff-3.9.0}/PKG-INFO +16 -11
  2. {diff_diff-3.7.0 → diff_diff-3.9.0}/README.md +11 -7
  3. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/__init__.py +209 -123
  4. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/_backend.py +59 -12
  5. diff_diff-3.9.0/diff_diff/_base.py +169 -0
  6. diff_diff-3.9.0/diff_diff/_deprecation.py +164 -0
  7. diff_diff-3.9.0/diff_diff/_rdrobust_port.py +1913 -0
  8. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/_reporting_helpers.py +46 -17
  9. diff_diff-3.9.0/diff_diff/_staggered_triple_diff_engine.py +1699 -0
  10. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/agent_workflow.py +4 -3
  11. diff_diff-3.9.0/diff_diff/aggregation.py +624 -0
  12. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/bacon.py +51 -17
  13. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/bootstrap_chunking.py +18 -3
  14. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/bootstrap_utils.py +9 -6
  15. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/business_report.py +63 -30
  16. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/chaisemartin_dhaultfoeuille.py +192 -96
  17. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/chaisemartin_dhaultfoeuille_bootstrap.py +8 -8
  18. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/chaisemartin_dhaultfoeuille_results.py +172 -9
  19. diff_diff-3.9.0/diff_diff/changes_in_changes.py +1461 -0
  20. diff_diff-3.9.0/diff_diff/changes_in_changes_results.py +270 -0
  21. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/conformal.py +163 -19
  22. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/continuous_did.py +238 -207
  23. diff_diff-3.9.0/diff_diff/continuous_did_aggregation.py +213 -0
  24. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/continuous_did_results.py +260 -3
  25. diff_diff-3.9.0/diff_diff/datasets.py +1863 -0
  26. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/diagnostic_report.py +227 -59
  27. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/diagnostics.py +38 -20
  28. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/efficient_did.py +189 -500
  29. diff_diff-3.9.0/diff_diff/efficient_did_aggregation.py +521 -0
  30. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/efficient_did_bootstrap.py +7 -2
  31. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/efficient_did_covariates.py +2 -0
  32. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/efficient_did_results.py +261 -3
  33. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/estimators.py +796 -379
  34. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/guides/llms-autonomous.txt +54 -23
  35. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/guides/llms-full.txt +575 -140
  36. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/guides/llms-practitioner.txt +91 -56
  37. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/guides/llms.txt +25 -13
  38. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/had.py +321 -162
  39. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/had_pretests.py +298 -108
  40. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/honest_did.py +770 -68
  41. diff_diff-3.9.0/diff_diff/imputation.py +1476 -0
  42. diff_diff-3.7.0/diff_diff/imputation.py → diff_diff-3.9.0/diff_diff/imputation_aggregation.py +406 -1338
  43. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/imputation_bootstrap.py +1 -33
  44. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/imputation_results.py +297 -4
  45. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/linalg.py +1060 -151
  46. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/local_linear.py +3 -10
  47. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/lpdid.py +128 -38
  48. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/lpdid_results.py +51 -3
  49. diff_diff-3.9.0/diff_diff/mmm.py +653 -0
  50. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/power.py +128 -35
  51. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/practitioner.py +949 -99
  52. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/prep.py +19 -3
  53. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/prep_dgp.py +14 -14
  54. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/pretrends.py +634 -42
  55. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/profile.py +4 -4
  56. diff_diff-3.9.0/diff_diff/rdd.py +1252 -0
  57. diff_diff-3.9.0/diff_diff/rdplot.py +1141 -0
  58. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/results.py +40 -3
  59. diff_diff-3.9.0/diff_diff/results_base.py +1363 -0
  60. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/spillover.py +94 -70
  61. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/stacked_did.py +329 -136
  62. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/stacked_did_results.py +204 -7
  63. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/staggered.py +264 -73
  64. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/staggered_aggregation.py +201 -31
  65. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/staggered_bootstrap.py +31 -6
  66. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/staggered_results.py +259 -4
  67. diff_diff-3.9.0/diff_diff/staggered_triple_diff.py +267 -0
  68. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/staggered_triple_diff_results.py +2 -1
  69. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/sun_abraham.py +335 -59
  70. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/survey.py +69 -23
  71. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/synthetic_control.py +14 -39
  72. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/synthetic_control_results.py +205 -4
  73. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/synthetic_did.py +34 -107
  74. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/triple_diff.py +437 -88
  75. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/trop.py +15 -30
  76. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/trop_local.py +0 -1
  77. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/trop_results.py +2 -1
  78. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/twfe.py +477 -32
  79. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/two_stage.py +335 -1323
  80. diff_diff-3.9.0/diff_diff/two_stage_aggregation.py +1564 -0
  81. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/two_stage_bootstrap.py +86 -124
  82. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/two_stage_results.py +298 -4
  83. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/utils.py +549 -18
  84. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/visualization/_diagnostic.py +10 -8
  85. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/visualization/_event_study.py +410 -55
  86. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/visualization/_power.py +5 -4
  87. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/wooldridge.py +1268 -209
  88. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/wooldridge_results.py +242 -46
  89. {diff_diff-3.7.0 → diff_diff-3.9.0}/pyproject.toml +72 -5
  90. {diff_diff-3.7.0 → diff_diff-3.9.0}/rust/Cargo.lock +80 -69
  91. {diff_diff-3.7.0 → diff_diff-3.9.0}/rust/Cargo.toml +1 -1
  92. {diff_diff-3.7.0 → diff_diff-3.9.0}/rust/src/lib.rs +1 -0
  93. {diff_diff-3.7.0 → diff_diff-3.9.0}/rust/src/linalg.rs +561 -7
  94. diff_diff-3.7.0/diff_diff/datasets.py +0 -815
  95. diff_diff-3.7.0/diff_diff/staggered_triple_diff.py +0 -1670
  96. {diff_diff-3.7.0 → diff_diff-3.9.0}/LICENSE +0 -0
  97. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/_guides_api.py +0 -0
  98. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/_nprobust_port.py +0 -0
  99. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/balancing.py +0 -0
  100. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/conley.py +0 -0
  101. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/continuous_did_bspline.py +0 -0
  102. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/efficient_did_weights.py +0 -0
  103. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/guides/__init__.py +0 -0
  104. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/trop_global.py +0 -0
  105. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/visualization/__init__.py +0 -0
  106. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/visualization/_common.py +0 -0
  107. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/visualization/_continuous.py +0 -0
  108. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/visualization/_staggered.py +0 -0
  109. {diff_diff-3.7.0 → diff_diff-3.9.0}/diff_diff/visualization/_synthetic.py +0 -0
  110. {diff_diff-3.7.0 → diff_diff-3.9.0}/rust/build.rs +0 -0
  111. {diff_diff-3.7.0 → diff_diff-3.9.0}/rust/src/alloc_profile.rs +0 -0
  112. {diff_diff-3.7.0 → diff_diff-3.9.0}/rust/src/batched_solve.rs +0 -0
  113. {diff_diff-3.7.0 → diff_diff-3.9.0}/rust/src/bootstrap.rs +0 -0
  114. {diff_diff-3.7.0 → diff_diff-3.9.0}/rust/src/demean.rs +0 -0
  115. {diff_diff-3.7.0 → diff_diff-3.9.0}/rust/src/trop.rs +0 -0
  116. {diff_diff-3.7.0 → diff_diff-3.9.0}/rust/src/weights.rs +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: diff-diff
3
- Version: 3.7.0
3
+ Version: 3.9.0
4
4
  Classifier: Development Status :: 5 - Production/Stable
5
5
  Classifier: Intended Audience :: Science/Research
6
6
  Classifier: Operating System :: OS Independent
@@ -20,9 +20,9 @@ Requires-Dist: scipy>=1.10
20
20
  Requires-Dist: pytest>=7.0 ; extra == 'dev'
21
21
  Requires-Dist: pytest-xdist>=3.0 ; extra == 'dev'
22
22
  Requires-Dist: pytest-cov>=4.0 ; extra == 'dev'
23
- Requires-Dist: black>=23.0 ; extra == 'dev'
24
- Requires-Dist: ruff>=0.1.0 ; extra == 'dev'
25
- Requires-Dist: mypy>=1.0 ; extra == 'dev'
23
+ Requires-Dist: black==26.5.1 ; extra == 'dev'
24
+ Requires-Dist: ruff==0.16.0 ; extra == 'dev'
25
+ Requires-Dist: mypy==2.3.0 ; extra == 'dev'
26
26
  Requires-Dist: maturin>=1.4,<2.0 ; extra == 'dev'
27
27
  Requires-Dist: matplotlib>=3.5 ; extra == 'dev'
28
28
  Requires-Dist: nbmake>=1.5 ; extra == 'dev'
@@ -33,6 +33,7 @@ Requires-Dist: sphinxext-opengraph>=0.9 ; extra == 'docs'
33
33
  Requires-Dist: sphinx-sitemap>=2.5 ; extra == 'docs'
34
34
  Requires-Dist: nbsphinx>=0.9 ; extra == 'docs'
35
35
  Requires-Dist: myst-parser>=2.0 ; extra == 'docs'
36
+ Requires-Dist: sphinx-design>=0.6.1 ; extra == 'docs'
36
37
  Requires-Dist: matplotlib>=3.5 ; extra == 'docs'
37
38
  Requires-Dist: ipython>=8.0 ; extra == 'docs'
38
39
  Requires-Dist: plotly>=5.0 ; extra == 'plotly'
@@ -95,7 +96,7 @@ data = pd.DataFrame({
95
96
  })
96
97
 
97
98
  did = DifferenceInDifferences()
98
- results = did.fit(data, outcome='outcome', treatment='treated', time='post')
99
+ results = did.fit(data, outcome='outcome', treatment='treated', post='post')
99
100
  print(results) # DiDResults(ATT=3.0000, SE=1.7321, p=0.1583)
100
101
  results.print_summary() # full statsmodels-style table
101
102
  ```
@@ -143,9 +144,9 @@ For rigorous DiD analysis, follow these 8 steps. Skipping diagnostic steps produ
143
144
  2. **State identification assumptions** - which parallel trends variant (unconditional, conditional, PT-GT-Nev, PT-GT-NYT), no-anticipation, overlap.
144
145
  3. **Test parallel trends** - simple 2x2: `check_parallel_trends()`, `equivalence_test_trends()`; staggered: inspect CS event-study pre-period coefficients (generic PT tests are invalid for staggered designs). Insignificant pre-trends do NOT prove PT holds.
145
146
  4. **Choose estimator** - staggered adoption -> CS/SA/BJS (NOT plain TWFE); few treated units -> SDiD; factor confounding -> TROP; simple 2x2 -> DiD. Run `BaconDecomposition` to diagnose TWFE bias.
146
- 5. **Estimate** - `estimator.fit(data, ...)`. Always print the cluster count first and choose inference method based on the result (cluster-robust if >= 50 clusters, wild bootstrap if fewer).
147
- 6. **Sensitivity analysis** - `compute_honest_did(results)` for bounds under PT violations (MultiPeriodDiD, CS, or dCDH), `run_all_placebo_tests()` for 2x2 falsification, specification comparisons for staggered designs.
148
- 7. **Heterogeneity** - CS: `aggregate='group'`/`'event_study'`; SA: `results.event_study_effects` / `to_dataframe(level='cohort')`; subgroup re-estimation.
147
+ 5. **Estimate** - `estimator.fit(data, ...)`. Always print the cluster count first and choose inference method based on the result (cluster-robust if >= 50 clusters, wild bootstrap if fewer - for DifferenceInDifferences pass `cluster=`; TwoWayFixedEffects auto-clusters at unit level).
148
+ 6. **Sensitivity analysis** - `compute_honest_did(results)` for bounds under PT violations (MultiPeriodDiD, CS, or dCDH natively; the TwoWayFixedEffects `event_study=True` surface and a StackedDiD `results.aggregate('event_study')` container also admit - Stacked needs `kappa_pre >= 2`), `run_all_placebo_tests()` for 2x2 falsification, specification comparisons for staggered designs.
149
+ 7. **Heterogeneity** - CS: `results.aggregate('group')`/`'event_study'` (post-fit, no refit); SA: `results.event_study_effects` / `to_dataframe(level='cohort')`; Stacked: `results.aggregate('event_study')`/`'simple'` post-fit views (surface always computed since 3.9); EDiD: `results.aggregate(...)` post-fit from retained EIFs (3.9); ImputationDiD/TwoStageDiD: `results.aggregate(...)` post-fit from panel-backed kits (3.9); ContinuousDiD: `results.aggregate('dose'/'simple'/'event_study')` post-fit (3.9; dose/simple are views, event_study recomputes); subgroup re-estimation.
149
150
  8. **Robustness** - compare 2-3 estimators (CS vs SA vs BJS), report with and without covariates (shows whether conditioning drives identification), present pre-trends and sensitivity bounds.
150
151
 
151
152
  Full guide: `diff_diff.get_llm_guide("practitioner")`.
@@ -154,7 +155,7 @@ Full guide: `diff_diff.get_llm_guide("practitioner")`.
154
155
 
155
156
  - [DifferenceInDifferences](https://diff-diff.readthedocs.io/en/stable/api/estimators.html) - basic 2x2 DiD with robust/cluster-robust SEs, wild bootstrap, formula interface, and fixed effects
156
157
  - [TwoWayFixedEffects](https://diff-diff.readthedocs.io/en/stable/api/estimators.html) - panel data DiD with unit and time fixed effects via within-transformation or dummies
157
- - [MultiPeriodDiD](https://diff-diff.readthedocs.io/en/stable/api/estimators.html) - event study design with period-specific treatment effects for dynamic analysis
158
+ - [MultiPeriodDiD](https://diff-diff.readthedocs.io/en/stable/api/estimators.html) - event study design with period-specific treatment effects for dynamic analysis (deprecated 3.9 - use TwoWayFixedEffects `event_study=True`)
158
159
  - [CallawaySantAnna](https://diff-diff.readthedocs.io/en/stable/api/staggered.html) - Callaway & Sant'Anna (2021) group-time ATT estimator for staggered adoption
159
160
  - [ChaisemartinDHaultfoeuille](https://diff-diff.readthedocs.io/en/stable/api/chaisemartin_dhaultfoeuille.html) - de Chaisemartin & D'Haultfœuille (2020/2022) for **reversible (non-absorbing) treatments** with multi-horizon event study, normalized effects, cost-benefit delta, sup-t bands, and dynamic placebos. The most general option for treatments that switch on AND off (see also `LPDiD`/`TROP` `non_absorbing`). Alias `DCDH`.
160
161
  - [SunAbraham](https://diff-diff.readthedocs.io/en/stable/api/staggered.html) - Sun & Abraham (2021) interaction-weighted estimator for heterogeneity-robust event studies
@@ -163,24 +164,28 @@ Full guide: `diff_diff.get_llm_guide("practitioner")`.
163
164
  - [SpilloverDiD](https://diff-diff.readthedocs.io/en/stable/api/spillover.html) - Butts (2021) ring-indicator spillover-aware DiD identifying direct effect on treated + per-ring spillover on near-control units; handles non-staggered and staggered timing; supports survey-design variance under `survey_design=` for HC1 / CR1 (Wave E.1 Binder TSL) and Conley (Wave E.2 panel-aware stratified-Conley sandwich on per-period PSU totals; extended in Wave E.2 follow-up to `conley_lag_cutoff > 0` via panel-block composition with within-PSU serial Bartlett HAC — `lag>0` requires an effective PSU via explicit `survey_design.psu` or injected `cluster=<col>`); `SurveyDesign.subpopulation()` preserves full-design `n_psu` / `df_survey` via zero-padded scores (Wave E.3, R `svyrecvar(subset())` form)
164
165
  - [SyntheticDiD](https://diff-diff.readthedocs.io/en/stable/api/estimators.html) - Synthetic DiD combining standard DiD and synthetic control for few treated units
165
166
  - [SyntheticControl](https://diff-diff.readthedocs.io/en/stable/api/synthetic_control.html) - Abadie, Diamond & Hainmueller (2010) classic synthetic control for a single treated unit (donor-weight counterfactual, nested/cv/inverse-variance/custom V; in-space placebo permutation inference via `in_space_placebo()`, plus ADH-2015 `leave_one_out()` + `in_time_placebo()` robustness, Firpo-Possebom (2018) test-inversion confidence sets, and Chernozhukov-Wüthrich-Zhu (2021) conformal inference)
166
- - [TripleDifference](https://diff-diff.readthedocs.io/en/stable/api/triple_diff.html) - triple difference (DDD) estimator for designs requiring two criteria for treatment eligibility
167
+ - [TripleDifference](https://diff-diff.readthedocs.io/en/stable/api/triple_diff.html) - triple difference (DDD) estimator for designs requiring two criteria for treatment eligibility; serves both the 2x2x2 and the staggered-adoption design from one signature (`fit(..., first_treat=)` selects the staggered engine)
167
168
  - [ContinuousDiD](https://diff-diff.readthedocs.io/en/stable/api/continuous_did.html) - Callaway, Goodman-Bacon & Sant'Anna (2024) continuous treatment DiD with dose-response curves
168
169
  - [HeterogeneousAdoptionDiD](https://diff-diff.readthedocs.io/en/stable/api/had.html) - de Chaisemartin, Ciccia, D'Haultfœuille & Knau (2026) for designs where **no unit remains untreated**; local-linear estimator at the dose support boundary returning Weighted Average Slope (WAS) on Design 1' (`d̲ = 0` / QUG) or `WAS_{d̲}` on Design 1 (`d̲ > 0`, continuous-near-d̲ or mass-point), with a multi-period event-study extension (last-treatment cohort, pointwise CIs). **Panel-only** in this release - repeated cross-sections rejected by the validator. Alias `HAD`.
170
+ - [RegressionDiscontinuity](https://diff-diff.readthedocs.io/en/stable/api/regression_discontinuity.html) - Calonico, Cattaneo & Titiunik (2014) sharp, fuzzy, AND covariate-adjusted regression discontinuity with robust bias-corrected inference and rdrobust-parity bandwidth selection (all 10 selectors, mass-point handling; fuzzy via `takeup=` with a first-stage block and weak-identification warning; covariates via `covariates=` - CCFT 2019, same estimand, covariate-aware bandwidths). Canonical `att` is the bias-corrected estimate with a coherent robust CI (rdrobust's printed headline is `att_conventional`). Alias `RDD`.
169
171
  - [StackedDiD](https://diff-diff.readthedocs.io/en/stable/api/stacked_did.html) - Wing, Freedman & Hollingsworth (2024) stacked DiD with Q-weights and sub-experiments; optional covariate balancing (Ustyuzhanin 2026)
170
172
  - [EfficientDiD](https://diff-diff.readthedocs.io/en/stable/api/efficient_did.html) - Chen, Sant'Anna & Xie (2025) efficient DiD with optimal weighting for tighter SEs
171
173
  - [TROP](https://diff-diff.readthedocs.io/en/stable/api/trop.html) - Triply Robust Panel estimator (Athey et al. 2025) with nuclear norm factor adjustment
172
- - [StaggeredTripleDifference](https://diff-diff.readthedocs.io/en/stable/api/staggered.html#staggeredtripledifference) - Ortiz-Villavicencio & Sant'Anna (2025) staggered DDD with group-time ATT
174
+ - [StaggeredTripleDifference](https://diff-diff.readthedocs.io/en/stable/api/staggered.html#staggeredtripledifference) - Ortiz-Villavicencio & Sant'Anna (2025) staggered DDD with group-time ATT (deprecated 3.9 - use `TripleDifference` with `first_treat=`)
173
175
  - [WooldridgeDiD](https://diff-diff.readthedocs.io/en/stable/api/wooldridge_etwfe.html) - Wooldridge (2023, 2025) ETWFE: saturated OLS, logit/Poisson QMLE (ASF-based ATT). Alias `ETWFE`.
174
176
  - [LPDiD](https://diff-diff.readthedocs.io/en/stable/api/lpdid.html) - Dube, Girardi, Jorda & Taylor (2025) Local Projections DiD: per-horizon long-difference event study on clean controls (no negative weighting), variance- or equally-weighted ATT, for absorbing or non-absorbing (reversible) treatment
177
+ - [ChangesInChanges](https://diff-diff.readthedocs.io/en/stable/api/changes_in_changes.html) - Athey & Imbens (2006) nonlinear/distributional DiD for the 2x2 design: full counterfactual distribution and quantile treatment effects via CDF transformation, plus the QDiD comparison estimator via `method="qdid"`; bootstrap inference; R qte parity. Alias `CiC`
175
178
  - [BaconDecomposition](https://diff-diff.readthedocs.io/en/stable/api/bacon.html) - Goodman-Bacon (2021) decomposition for diagnosing TWFE bias in staggered settings
176
179
 
177
180
  ## Diagnostics & Sensitivity
178
181
 
182
+ - [RD Plots](https://diff-diff.readthedocs.io/en/stable/api/regression_discontinuity.html) - Calonico, Cattaneo & Titiunik (2015) optimal data-driven RD plots (`RDPlot`): all 8 rdrobust `binselect` bin selectors, implied-scale/WIMSE-weight reporting, optional matplotlib rendering
179
183
  - [Parallel Trends Testing](https://diff-diff.readthedocs.io/en/stable/api/diagnostics.html) - simple and Wasserstein-robust parallel trends tests, equivalence testing (TOST)
180
184
  - [Placebo Tests](https://diff-diff.readthedocs.io/en/stable/api/diagnostics.html) - placebo timing, group, permutation, leave-one-out
181
185
  - [Honest DiD](https://diff-diff.readthedocs.io/en/stable/api/honest_did.html) - Rambachan & Roth (2023) sensitivity analysis: robust CI under PT violations, breakdown values
182
186
  - [Pre-Trends Power Analysis](https://diff-diff.readthedocs.io/en/stable/api/pretrends.html) - Roth (2022) minimum detectable violation and power curves
183
187
  - [Power Analysis](https://diff-diff.readthedocs.io/en/stable/api/power.html) - analytical and simulation-based MDE, sample size, power curves for study design
188
+ - [MMM Calibration Export](https://diff-diff.readthedocs.io/en/stable/api/mmm.html) - convert experiment results into MMM calibration inputs: PyMC-Marketing lift-test frames and Google Meridian lognormal ROI priors
184
189
  - Conley spatial HAC SE (`vcov_type="conley"`) on cross-sectional `LinearRegression` / `compute_robust_vcov` plus panel `DifferenceInDifferences` / `MultiPeriodDiD` / `TwoWayFixedEffects` (with `conley_lag_cutoff` for within-unit Bartlett temporal HAC) - Conley (1999) spatial-correlation-aware SEs with parity vs R `conleyreg` on cross-sectional + panel fixtures, optional combined spatial + cluster product kernel via explicit `cluster=`, auto-activating sparse k-d-tree fast path for `n > 5_000`
185
190
 
186
191
  ## Survey Support
@@ -41,7 +41,7 @@ data = pd.DataFrame({
41
41
  })
42
42
 
43
43
  did = DifferenceInDifferences()
44
- results = did.fit(data, outcome='outcome', treatment='treated', time='post')
44
+ results = did.fit(data, outcome='outcome', treatment='treated', post='post')
45
45
  print(results) # DiDResults(ATT=3.0000, SE=1.7321, p=0.1583)
46
46
  results.print_summary() # full statsmodels-style table
47
47
  ```
@@ -89,9 +89,9 @@ For rigorous DiD analysis, follow these 8 steps. Skipping diagnostic steps produ
89
89
  2. **State identification assumptions** - which parallel trends variant (unconditional, conditional, PT-GT-Nev, PT-GT-NYT), no-anticipation, overlap.
90
90
  3. **Test parallel trends** - simple 2x2: `check_parallel_trends()`, `equivalence_test_trends()`; staggered: inspect CS event-study pre-period coefficients (generic PT tests are invalid for staggered designs). Insignificant pre-trends do NOT prove PT holds.
91
91
  4. **Choose estimator** - staggered adoption -> CS/SA/BJS (NOT plain TWFE); few treated units -> SDiD; factor confounding -> TROP; simple 2x2 -> DiD. Run `BaconDecomposition` to diagnose TWFE bias.
92
- 5. **Estimate** - `estimator.fit(data, ...)`. Always print the cluster count first and choose inference method based on the result (cluster-robust if >= 50 clusters, wild bootstrap if fewer).
93
- 6. **Sensitivity analysis** - `compute_honest_did(results)` for bounds under PT violations (MultiPeriodDiD, CS, or dCDH), `run_all_placebo_tests()` for 2x2 falsification, specification comparisons for staggered designs.
94
- 7. **Heterogeneity** - CS: `aggregate='group'`/`'event_study'`; SA: `results.event_study_effects` / `to_dataframe(level='cohort')`; subgroup re-estimation.
92
+ 5. **Estimate** - `estimator.fit(data, ...)`. Always print the cluster count first and choose inference method based on the result (cluster-robust if >= 50 clusters, wild bootstrap if fewer - for DifferenceInDifferences pass `cluster=`; TwoWayFixedEffects auto-clusters at unit level).
93
+ 6. **Sensitivity analysis** - `compute_honest_did(results)` for bounds under PT violations (MultiPeriodDiD, CS, or dCDH natively; the TwoWayFixedEffects `event_study=True` surface and a StackedDiD `results.aggregate('event_study')` container also admit - Stacked needs `kappa_pre >= 2`), `run_all_placebo_tests()` for 2x2 falsification, specification comparisons for staggered designs.
94
+ 7. **Heterogeneity** - CS: `results.aggregate('group')`/`'event_study'` (post-fit, no refit); SA: `results.event_study_effects` / `to_dataframe(level='cohort')`; Stacked: `results.aggregate('event_study')`/`'simple'` post-fit views (surface always computed since 3.9); EDiD: `results.aggregate(...)` post-fit from retained EIFs (3.9); ImputationDiD/TwoStageDiD: `results.aggregate(...)` post-fit from panel-backed kits (3.9); ContinuousDiD: `results.aggregate('dose'/'simple'/'event_study')` post-fit (3.9; dose/simple are views, event_study recomputes); subgroup re-estimation.
95
95
  8. **Robustness** - compare 2-3 estimators (CS vs SA vs BJS), report with and without covariates (shows whether conditioning drives identification), present pre-trends and sensitivity bounds.
96
96
 
97
97
  Full guide: `diff_diff.get_llm_guide("practitioner")`.
@@ -100,7 +100,7 @@ Full guide: `diff_diff.get_llm_guide("practitioner")`.
100
100
 
101
101
  - [DifferenceInDifferences](https://diff-diff.readthedocs.io/en/stable/api/estimators.html) - basic 2x2 DiD with robust/cluster-robust SEs, wild bootstrap, formula interface, and fixed effects
102
102
  - [TwoWayFixedEffects](https://diff-diff.readthedocs.io/en/stable/api/estimators.html) - panel data DiD with unit and time fixed effects via within-transformation or dummies
103
- - [MultiPeriodDiD](https://diff-diff.readthedocs.io/en/stable/api/estimators.html) - event study design with period-specific treatment effects for dynamic analysis
103
+ - [MultiPeriodDiD](https://diff-diff.readthedocs.io/en/stable/api/estimators.html) - event study design with period-specific treatment effects for dynamic analysis (deprecated 3.9 - use TwoWayFixedEffects `event_study=True`)
104
104
  - [CallawaySantAnna](https://diff-diff.readthedocs.io/en/stable/api/staggered.html) - Callaway & Sant'Anna (2021) group-time ATT estimator for staggered adoption
105
105
  - [ChaisemartinDHaultfoeuille](https://diff-diff.readthedocs.io/en/stable/api/chaisemartin_dhaultfoeuille.html) - de Chaisemartin & D'Haultfœuille (2020/2022) for **reversible (non-absorbing) treatments** with multi-horizon event study, normalized effects, cost-benefit delta, sup-t bands, and dynamic placebos. The most general option for treatments that switch on AND off (see also `LPDiD`/`TROP` `non_absorbing`). Alias `DCDH`.
106
106
  - [SunAbraham](https://diff-diff.readthedocs.io/en/stable/api/staggered.html) - Sun & Abraham (2021) interaction-weighted estimator for heterogeneity-robust event studies
@@ -109,24 +109,28 @@ Full guide: `diff_diff.get_llm_guide("practitioner")`.
109
109
  - [SpilloverDiD](https://diff-diff.readthedocs.io/en/stable/api/spillover.html) - Butts (2021) ring-indicator spillover-aware DiD identifying direct effect on treated + per-ring spillover on near-control units; handles non-staggered and staggered timing; supports survey-design variance under `survey_design=` for HC1 / CR1 (Wave E.1 Binder TSL) and Conley (Wave E.2 panel-aware stratified-Conley sandwich on per-period PSU totals; extended in Wave E.2 follow-up to `conley_lag_cutoff > 0` via panel-block composition with within-PSU serial Bartlett HAC — `lag>0` requires an effective PSU via explicit `survey_design.psu` or injected `cluster=<col>`); `SurveyDesign.subpopulation()` preserves full-design `n_psu` / `df_survey` via zero-padded scores (Wave E.3, R `svyrecvar(subset())` form)
110
110
  - [SyntheticDiD](https://diff-diff.readthedocs.io/en/stable/api/estimators.html) - Synthetic DiD combining standard DiD and synthetic control for few treated units
111
111
  - [SyntheticControl](https://diff-diff.readthedocs.io/en/stable/api/synthetic_control.html) - Abadie, Diamond & Hainmueller (2010) classic synthetic control for a single treated unit (donor-weight counterfactual, nested/cv/inverse-variance/custom V; in-space placebo permutation inference via `in_space_placebo()`, plus ADH-2015 `leave_one_out()` + `in_time_placebo()` robustness, Firpo-Possebom (2018) test-inversion confidence sets, and Chernozhukov-Wüthrich-Zhu (2021) conformal inference)
112
- - [TripleDifference](https://diff-diff.readthedocs.io/en/stable/api/triple_diff.html) - triple difference (DDD) estimator for designs requiring two criteria for treatment eligibility
112
+ - [TripleDifference](https://diff-diff.readthedocs.io/en/stable/api/triple_diff.html) - triple difference (DDD) estimator for designs requiring two criteria for treatment eligibility; serves both the 2x2x2 and the staggered-adoption design from one signature (`fit(..., first_treat=)` selects the staggered engine)
113
113
  - [ContinuousDiD](https://diff-diff.readthedocs.io/en/stable/api/continuous_did.html) - Callaway, Goodman-Bacon & Sant'Anna (2024) continuous treatment DiD with dose-response curves
114
114
  - [HeterogeneousAdoptionDiD](https://diff-diff.readthedocs.io/en/stable/api/had.html) - de Chaisemartin, Ciccia, D'Haultfœuille & Knau (2026) for designs where **no unit remains untreated**; local-linear estimator at the dose support boundary returning Weighted Average Slope (WAS) on Design 1' (`d̲ = 0` / QUG) or `WAS_{d̲}` on Design 1 (`d̲ > 0`, continuous-near-d̲ or mass-point), with a multi-period event-study extension (last-treatment cohort, pointwise CIs). **Panel-only** in this release - repeated cross-sections rejected by the validator. Alias `HAD`.
115
+ - [RegressionDiscontinuity](https://diff-diff.readthedocs.io/en/stable/api/regression_discontinuity.html) - Calonico, Cattaneo & Titiunik (2014) sharp, fuzzy, AND covariate-adjusted regression discontinuity with robust bias-corrected inference and rdrobust-parity bandwidth selection (all 10 selectors, mass-point handling; fuzzy via `takeup=` with a first-stage block and weak-identification warning; covariates via `covariates=` - CCFT 2019, same estimand, covariate-aware bandwidths). Canonical `att` is the bias-corrected estimate with a coherent robust CI (rdrobust's printed headline is `att_conventional`). Alias `RDD`.
115
116
  - [StackedDiD](https://diff-diff.readthedocs.io/en/stable/api/stacked_did.html) - Wing, Freedman & Hollingsworth (2024) stacked DiD with Q-weights and sub-experiments; optional covariate balancing (Ustyuzhanin 2026)
116
117
  - [EfficientDiD](https://diff-diff.readthedocs.io/en/stable/api/efficient_did.html) - Chen, Sant'Anna & Xie (2025) efficient DiD with optimal weighting for tighter SEs
117
118
  - [TROP](https://diff-diff.readthedocs.io/en/stable/api/trop.html) - Triply Robust Panel estimator (Athey et al. 2025) with nuclear norm factor adjustment
118
- - [StaggeredTripleDifference](https://diff-diff.readthedocs.io/en/stable/api/staggered.html#staggeredtripledifference) - Ortiz-Villavicencio & Sant'Anna (2025) staggered DDD with group-time ATT
119
+ - [StaggeredTripleDifference](https://diff-diff.readthedocs.io/en/stable/api/staggered.html#staggeredtripledifference) - Ortiz-Villavicencio & Sant'Anna (2025) staggered DDD with group-time ATT (deprecated 3.9 - use `TripleDifference` with `first_treat=`)
119
120
  - [WooldridgeDiD](https://diff-diff.readthedocs.io/en/stable/api/wooldridge_etwfe.html) - Wooldridge (2023, 2025) ETWFE: saturated OLS, logit/Poisson QMLE (ASF-based ATT). Alias `ETWFE`.
120
121
  - [LPDiD](https://diff-diff.readthedocs.io/en/stable/api/lpdid.html) - Dube, Girardi, Jorda & Taylor (2025) Local Projections DiD: per-horizon long-difference event study on clean controls (no negative weighting), variance- or equally-weighted ATT, for absorbing or non-absorbing (reversible) treatment
122
+ - [ChangesInChanges](https://diff-diff.readthedocs.io/en/stable/api/changes_in_changes.html) - Athey & Imbens (2006) nonlinear/distributional DiD for the 2x2 design: full counterfactual distribution and quantile treatment effects via CDF transformation, plus the QDiD comparison estimator via `method="qdid"`; bootstrap inference; R qte parity. Alias `CiC`
121
123
  - [BaconDecomposition](https://diff-diff.readthedocs.io/en/stable/api/bacon.html) - Goodman-Bacon (2021) decomposition for diagnosing TWFE bias in staggered settings
122
124
 
123
125
  ## Diagnostics & Sensitivity
124
126
 
127
+ - [RD Plots](https://diff-diff.readthedocs.io/en/stable/api/regression_discontinuity.html) - Calonico, Cattaneo & Titiunik (2015) optimal data-driven RD plots (`RDPlot`): all 8 rdrobust `binselect` bin selectors, implied-scale/WIMSE-weight reporting, optional matplotlib rendering
125
128
  - [Parallel Trends Testing](https://diff-diff.readthedocs.io/en/stable/api/diagnostics.html) - simple and Wasserstein-robust parallel trends tests, equivalence testing (TOST)
126
129
  - [Placebo Tests](https://diff-diff.readthedocs.io/en/stable/api/diagnostics.html) - placebo timing, group, permutation, leave-one-out
127
130
  - [Honest DiD](https://diff-diff.readthedocs.io/en/stable/api/honest_did.html) - Rambachan & Roth (2023) sensitivity analysis: robust CI under PT violations, breakdown values
128
131
  - [Pre-Trends Power Analysis](https://diff-diff.readthedocs.io/en/stable/api/pretrends.html) - Roth (2022) minimum detectable violation and power curves
129
132
  - [Power Analysis](https://diff-diff.readthedocs.io/en/stable/api/power.html) - analytical and simulation-based MDE, sample size, power curves for study design
133
+ - [MMM Calibration Export](https://diff-diff.readthedocs.io/en/stable/api/mmm.html) - convert experiment results into MMM calibration inputs: PyMC-Marketing lift-test frames and Google Meridian lognormal ROI priors
130
134
  - Conley spatial HAC SE (`vcov_type="conley"`) on cross-sectional `LinearRegression` / `compute_robust_vcov` plus panel `DifferenceInDifferences` / `MultiPeriodDiD` / `TwoWayFixedEffects` (with `conley_lag_cutoff` for within-unit Bartlett temporal HAC) - Conley (1999) spatial-correlation-aware SEs with parity vs R `conleyreg` on cross-sectional + panel fixtures, optional combined spatial + cluster product kernel via explicit `cluster=`, auto-activating sparse k-d-tree fast path for `n > 5_000`
131
135
 
132
136
  ## Survey Support