diff-diff 2.7.6__tar.gz → 2.8.1__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 (67) hide show
  1. {diff_diff-2.7.6 → diff_diff-2.8.1}/PKG-INFO +11 -1
  2. {diff_diff-2.7.6 → diff_diff-2.8.1}/README.md +9 -0
  3. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/__init__.py +22 -1
  4. diff_diff-2.8.1/diff_diff/honest_did.py +2585 -0
  5. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/prep.py +2 -0
  6. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/prep_dgp.py +473 -0
  7. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/staggered.py +1418 -159
  8. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/staggered_aggregation.py +181 -53
  9. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/staggered_bootstrap.py +30 -17
  10. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/staggered_results.py +6 -2
  11. diff_diff-2.8.1/diff_diff/staggered_triple_diff.py +1453 -0
  12. diff_diff-2.8.1/diff_diff/staggered_triple_diff_results.py +348 -0
  13. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/survey.py +138 -48
  14. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/visualization/_common.py +36 -0
  15. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/visualization/_diagnostic.py +23 -4
  16. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/visualization/_event_study.py +24 -4
  17. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/visualization/_power.py +14 -4
  18. {diff_diff-2.7.6 → diff_diff-2.8.1}/pyproject.toml +2 -1
  19. {diff_diff-2.7.6 → diff_diff-2.8.1}/rust/Cargo.lock +3 -3
  20. {diff_diff-2.7.6 → diff_diff-2.8.1}/rust/Cargo.toml +1 -1
  21. diff_diff-2.7.6/diff_diff/honest_did.py +0 -1511
  22. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/_backend.py +0 -0
  23. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/bacon.py +0 -0
  24. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/bootstrap_utils.py +0 -0
  25. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/continuous_did.py +0 -0
  26. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/continuous_did_bspline.py +0 -0
  27. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/continuous_did_results.py +0 -0
  28. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/datasets.py +0 -0
  29. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/diagnostics.py +0 -0
  30. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/efficient_did.py +0 -0
  31. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/efficient_did_bootstrap.py +0 -0
  32. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/efficient_did_covariates.py +0 -0
  33. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/efficient_did_results.py +0 -0
  34. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/efficient_did_weights.py +0 -0
  35. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/estimators.py +0 -0
  36. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/imputation.py +0 -0
  37. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/imputation_bootstrap.py +0 -0
  38. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/imputation_results.py +0 -0
  39. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/linalg.py +0 -0
  40. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/power.py +0 -0
  41. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/practitioner.py +0 -0
  42. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/pretrends.py +0 -0
  43. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/results.py +0 -0
  44. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/stacked_did.py +0 -0
  45. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/stacked_did_results.py +0 -0
  46. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/sun_abraham.py +0 -0
  47. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/synthetic_did.py +0 -0
  48. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/triple_diff.py +0 -0
  49. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/trop.py +0 -0
  50. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/trop_global.py +0 -0
  51. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/trop_local.py +0 -0
  52. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/trop_results.py +0 -0
  53. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/twfe.py +0 -0
  54. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/two_stage.py +0 -0
  55. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/two_stage_bootstrap.py +0 -0
  56. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/two_stage_results.py +0 -0
  57. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/utils.py +0 -0
  58. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/visualization/__init__.py +0 -0
  59. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/visualization/_continuous.py +0 -0
  60. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/visualization/_staggered.py +0 -0
  61. {diff_diff-2.7.6 → diff_diff-2.8.1}/diff_diff/visualization/_synthetic.py +0 -0
  62. {diff_diff-2.7.6 → diff_diff-2.8.1}/rust/build.rs +0 -0
  63. {diff_diff-2.7.6 → diff_diff-2.8.1}/rust/src/bootstrap.rs +0 -0
  64. {diff_diff-2.7.6 → diff_diff-2.8.1}/rust/src/lib.rs +0 -0
  65. {diff_diff-2.7.6 → diff_diff-2.8.1}/rust/src/linalg.rs +0 -0
  66. {diff_diff-2.7.6 → diff_diff-2.8.1}/rust/src/trop.rs +0 -0
  67. {diff_diff-2.7.6 → diff_diff-2.8.1}/rust/src/weights.rs +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: diff-diff
3
- Version: 2.7.6
3
+ Version: 2.8.1
4
4
  Classifier: Development Status :: 5 - Production/Stable
5
5
  Classifier: Intended Audience :: Science/Research
6
6
  Classifier: Operating System :: OS Independent
@@ -45,6 +45,7 @@ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
45
45
  Project-URL: Documentation, https://diff-diff.readthedocs.io
46
46
  Project-URL: Homepage, https://github.com/igerber/diff-diff
47
47
  Project-URL: Issues, https://github.com/igerber/diff-diff/issues
48
+ Project-URL: Practitioner Guide, https://github.com/igerber/diff-diff/blob/main/docs/llms-practitioner.txt
48
49
  Project-URL: Repository, https://github.com/igerber/diff-diff
49
50
 
50
51
  # diff-diff
@@ -116,6 +117,14 @@ Signif. codes: '***' 0.001, '**' 0.01, '*' 0.05, '.' 0.1
116
117
  ======================================================================
117
118
  ```
118
119
 
120
+ ## For AI Agents
121
+
122
+ If you are an AI agent or LLM using this library, read [`docs/llms.txt`](docs/llms.txt) for a concise API reference with an 8-step practitioner workflow (based on Baker et al. 2025). The workflow ensures rigorous DiD analysis — not just calling `fit()`, but testing assumptions, running sensitivity analysis, and checking robustness.
123
+
124
+ After estimation, call `practitioner_next_steps(results)` for context-aware guidance on remaining diagnostic steps.
125
+
126
+ Detailed guide: [`docs/llms-practitioner.txt`](docs/llms-practitioner.txt)
127
+
119
128
  ## Features
120
129
 
121
130
  - **sklearn-like API**: Familiar `fit()` interface with `get_params()` and `set_params()`
@@ -181,6 +190,7 @@ We provide Jupyter notebook tutorials in `docs/tutorials/`:
181
190
  | `12_two_stage_did.ipynb` | Two-Stage DiD (Gardner 2022), GMM sandwich variance, per-observation effects |
182
191
  | `13_stacked_did.ipynb` | Stacked DiD (Wing et al. 2024), Q-weights, sub-experiment inspection, trimming, clean control definitions |
183
192
  | `15_efficient_did.ipynb` | Efficient DiD (Chen et al. 2025), optimal weighting, PT-All vs PT-Post, efficiency gains, bootstrap inference |
193
+ | `16_survey_did.ipynb` | Survey-aware DiD with complex sampling designs (strata, PSU, FPC, weights), replicate weights, subpopulation analysis, DEFF diagnostics |
184
194
 
185
195
  ## Data Preparation
186
196
 
@@ -67,6 +67,14 @@ Signif. codes: '***' 0.001, '**' 0.01, '*' 0.05, '.' 0.1
67
67
  ======================================================================
68
68
  ```
69
69
 
70
+ ## For AI Agents
71
+
72
+ If you are an AI agent or LLM using this library, read [`docs/llms.txt`](docs/llms.txt) for a concise API reference with an 8-step practitioner workflow (based on Baker et al. 2025). The workflow ensures rigorous DiD analysis — not just calling `fit()`, but testing assumptions, running sensitivity analysis, and checking robustness.
73
+
74
+ After estimation, call `practitioner_next_steps(results)` for context-aware guidance on remaining diagnostic steps.
75
+
76
+ Detailed guide: [`docs/llms-practitioner.txt`](docs/llms-practitioner.txt)
77
+
70
78
  ## Features
71
79
 
72
80
  - **sklearn-like API**: Familiar `fit()` interface with `get_params()` and `set_params()`
@@ -132,6 +140,7 @@ We provide Jupyter notebook tutorials in `docs/tutorials/`:
132
140
  | `12_two_stage_did.ipynb` | Two-Stage DiD (Gardner 2022), GMM sandwich variance, per-observation effects |
133
141
  | `13_stacked_did.ipynb` | Stacked DiD (Wing et al. 2024), Q-weights, sub-experiment inspection, trimming, clean control definitions |
134
142
  | `15_efficient_did.ipynb` | Efficient DiD (Chen et al. 2025), optimal weighting, PT-All vs PT-Post, efficiency gains, bootstrap inference |
143
+ | `16_survey_did.ipynb` | Survey-aware DiD with complex sampling designs (strata, PSU, FPC, weights), replicate weights, subpopulation analysis, DEFF diagnostics |
135
144
 
136
145
  ## Data Preparation
137
146
 
@@ -3,6 +3,13 @@ diff-diff: A library for Difference-in-Differences analysis.
3
3
 
4
4
  This library provides sklearn-like estimators for causal inference
5
5
  using the difference-in-differences methodology.
6
+
7
+ For rigorous analysis, follow the 8-step practitioner workflow in
8
+ docs/llms-practitioner.txt (based on Baker et al. 2025). After
9
+ estimation, call ``practitioner_next_steps(results)`` for context-aware
10
+ guidance on remaining diagnostic steps.
11
+
12
+ AI agent reference: docs/llms.txt
6
13
  """
7
14
 
8
15
  # Import backend detection from dedicated module (avoids circular imports)
@@ -81,6 +88,8 @@ from diff_diff.prep import (
81
88
  generate_factor_data,
82
89
  generate_panel_data,
83
90
  generate_staggered_data,
91
+ generate_staggered_ddd_data,
92
+ generate_survey_did_data,
84
93
  make_post_indicator,
85
94
  make_treatment_indicator,
86
95
  rank_control_units,
@@ -133,6 +142,12 @@ from diff_diff.triple_diff import (
133
142
  TripleDifferenceResults,
134
143
  triple_difference,
135
144
  )
145
+ from diff_diff.staggered_triple_diff import (
146
+ StaggeredTripleDifference,
147
+ )
148
+ from diff_diff.staggered_triple_diff_results import (
149
+ StaggeredTripleDiffResults,
150
+ )
136
151
  from diff_diff.continuous_did import (
137
152
  ContinuousDiD,
138
153
  ContinuousDiDResults,
@@ -190,11 +205,12 @@ SA = SunAbraham
190
205
  BJS = ImputationDiD
191
206
  Gardner = TwoStageDiD
192
207
  DDD = TripleDifference
208
+ SDDD = StaggeredTripleDifference
193
209
  Stacked = StackedDiD
194
210
  Bacon = BaconDecomposition
195
211
  EDiD = EfficientDiD
196
212
 
197
- __version__ = "2.7.6"
213
+ __version__ = "2.8.1"
198
214
  __all__ = [
199
215
  # Estimators
200
216
  "DifferenceInDifferences",
@@ -220,6 +236,7 @@ __all__ = [
220
236
  "BJS",
221
237
  "Gardner",
222
238
  "DDD",
239
+ "SDDD",
223
240
  "Stacked",
224
241
  "Bacon",
225
242
  # Bacon Decomposition
@@ -247,6 +264,8 @@ __all__ = [
247
264
  "two_stage_did",
248
265
  "TripleDifferenceResults",
249
266
  "triple_difference",
267
+ "StaggeredTripleDifference",
268
+ "StaggeredTripleDiffResults",
250
269
  "TROPResults",
251
270
  "trop",
252
271
  "StackedDiDResults",
@@ -296,6 +315,8 @@ __all__ = [
296
315
  "generate_ddd_data",
297
316
  "generate_panel_data",
298
317
  "generate_event_study_data",
318
+ "generate_staggered_ddd_data",
319
+ "generate_survey_did_data",
299
320
  "generate_continuous_did_data",
300
321
  "create_event_time",
301
322
  "aggregate_to_cohorts",