diff-diff 2.7.4__tar.gz → 2.7.6__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 (68) hide show
  1. {diff_diff-2.7.4 → diff_diff-2.7.6}/PKG-INFO +5 -1
  2. {diff_diff-2.7.4 → diff_diff-2.7.6}/diff_diff/__init__.py +19 -4
  3. {diff_diff-2.7.4 → diff_diff-2.7.6}/diff_diff/_backend.py +20 -19
  4. {diff_diff-2.7.4 → diff_diff-2.7.6}/diff_diff/bacon.py +282 -121
  5. {diff_diff-2.7.4 → diff_diff-2.7.6}/diff_diff/bootstrap_utils.py +274 -17
  6. {diff_diff-2.7.4 → diff_diff-2.7.6}/diff_diff/continuous_did.py +579 -108
  7. {diff_diff-2.7.4 → diff_diff-2.7.6}/diff_diff/continuous_did_bspline.py +7 -5
  8. {diff_diff-2.7.4 → diff_diff-2.7.6}/diff_diff/continuous_did_results.py +60 -53
  9. {diff_diff-2.7.4 → diff_diff-2.7.6}/diff_diff/datasets.py +179 -72
  10. {diff_diff-2.7.4 → diff_diff-2.7.6}/diff_diff/diagnostics.py +62 -101
  11. diff_diff-2.7.6/diff_diff/efficient_did.py +1688 -0
  12. {diff_diff-2.7.4 → diff_diff-2.7.6}/diff_diff/efficient_did_bootstrap.py +41 -5
  13. diff_diff-2.7.6/diff_diff/efficient_did_covariates.py +814 -0
  14. {diff_diff-2.7.4 → diff_diff-2.7.6}/diff_diff/efficient_did_results.py +70 -5
  15. {diff_diff-2.7.4 → diff_diff-2.7.6}/diff_diff/efficient_did_weights.py +96 -17
  16. {diff_diff-2.7.4 → diff_diff-2.7.6}/diff_diff/estimators.py +39 -24
  17. {diff_diff-2.7.4 → diff_diff-2.7.6}/diff_diff/imputation.py +298 -49
  18. {diff_diff-2.7.4 → diff_diff-2.7.6}/diff_diff/imputation_bootstrap.py +116 -10
  19. {diff_diff-2.7.4 → diff_diff-2.7.6}/diff_diff/imputation_results.py +8 -1
  20. {diff_diff-2.7.4 → diff_diff-2.7.6}/diff_diff/linalg.py +271 -53
  21. diff_diff-2.7.6/diff_diff/practitioner.py +869 -0
  22. {diff_diff-2.7.4 → diff_diff-2.7.6}/diff_diff/prep.py +75 -92
  23. {diff_diff-2.7.4 → diff_diff-2.7.6}/diff_diff/prep_dgp.py +69 -60
  24. {diff_diff-2.7.4 → diff_diff-2.7.6}/diff_diff/results.py +53 -36
  25. {diff_diff-2.7.4 → diff_diff-2.7.6}/diff_diff/stacked_did.py +139 -4
  26. {diff_diff-2.7.4 → diff_diff-2.7.6}/diff_diff/stacked_did_results.py +8 -1
  27. {diff_diff-2.7.4 → diff_diff-2.7.6}/diff_diff/staggered.py +608 -118
  28. {diff_diff-2.7.4 → diff_diff-2.7.6}/diff_diff/staggered_aggregation.py +243 -92
  29. {diff_diff-2.7.4 → diff_diff-2.7.6}/diff_diff/staggered_bootstrap.py +205 -94
  30. {diff_diff-2.7.4 → diff_diff-2.7.6}/diff_diff/staggered_results.py +9 -2
  31. {diff_diff-2.7.4 → diff_diff-2.7.6}/diff_diff/sun_abraham.py +413 -13
  32. diff_diff-2.7.6/diff_diff/survey.py +1646 -0
  33. {diff_diff-2.7.4 → diff_diff-2.7.6}/diff_diff/synthetic_did.py +390 -102
  34. {diff_diff-2.7.4 → diff_diff-2.7.6}/diff_diff/triple_diff.py +398 -62
  35. diff_diff-2.7.6/diff_diff/trop.py +981 -0
  36. diff_diff-2.7.6/diff_diff/trop_global.py +1251 -0
  37. diff_diff-2.7.6/diff_diff/trop_local.py +1261 -0
  38. {diff_diff-2.7.4 → diff_diff-2.7.6}/diff_diff/trop_results.py +53 -32
  39. {diff_diff-2.7.4 → diff_diff-2.7.6}/diff_diff/twfe.py +16 -1
  40. {diff_diff-2.7.4 → diff_diff-2.7.6}/diff_diff/two_stage.py +304 -52
  41. {diff_diff-2.7.4 → diff_diff-2.7.6}/diff_diff/two_stage_bootstrap.py +92 -14
  42. {diff_diff-2.7.4 → diff_diff-2.7.6}/diff_diff/two_stage_results.py +8 -1
  43. {diff_diff-2.7.4 → diff_diff-2.7.6}/diff_diff/utils.py +7 -0
  44. diff_diff-2.7.6/diff_diff/visualization/__init__.py +61 -0
  45. diff_diff-2.7.6/diff_diff/visualization/_common.py +292 -0
  46. diff_diff-2.7.6/diff_diff/visualization/_continuous.py +274 -0
  47. diff_diff-2.7.6/diff_diff/visualization/_diagnostic.py +798 -0
  48. diff_diff-2.7.6/diff_diff/visualization/_event_study.py +1066 -0
  49. diff_diff-2.7.6/diff_diff/visualization/_power.py +651 -0
  50. diff_diff-2.7.6/diff_diff/visualization/_staggered.py +833 -0
  51. diff_diff-2.7.6/diff_diff/visualization/_synthetic.py +197 -0
  52. {diff_diff-2.7.4 → diff_diff-2.7.6}/pyproject.toml +6 -1
  53. {diff_diff-2.7.4 → diff_diff-2.7.6}/rust/Cargo.lock +7 -7
  54. {diff_diff-2.7.4 → diff_diff-2.7.6}/rust/Cargo.toml +1 -1
  55. {diff_diff-2.7.4 → diff_diff-2.7.6}/rust/src/trop.rs +43 -8
  56. diff_diff-2.7.4/diff_diff/efficient_did.py +0 -843
  57. diff_diff-2.7.4/diff_diff/survey.py +0 -668
  58. diff_diff-2.7.4/diff_diff/trop.py +0 -2738
  59. diff_diff-2.7.4/diff_diff/visualization.py +0 -1764
  60. {diff_diff-2.7.4 → diff_diff-2.7.6}/README.md +0 -0
  61. {diff_diff-2.7.4 → diff_diff-2.7.6}/diff_diff/honest_did.py +0 -0
  62. {diff_diff-2.7.4 → diff_diff-2.7.6}/diff_diff/power.py +0 -0
  63. {diff_diff-2.7.4 → diff_diff-2.7.6}/diff_diff/pretrends.py +0 -0
  64. {diff_diff-2.7.4 → diff_diff-2.7.6}/rust/build.rs +0 -0
  65. {diff_diff-2.7.4 → diff_diff-2.7.6}/rust/src/bootstrap.rs +0 -0
  66. {diff_diff-2.7.4 → diff_diff-2.7.6}/rust/src/lib.rs +0 -0
  67. {diff_diff-2.7.4 → diff_diff-2.7.6}/rust/src/linalg.rs +0 -0
  68. {diff_diff-2.7.4 → diff_diff-2.7.6}/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.4
3
+ Version: 2.7.6
4
4
  Classifier: Development Status :: 5 - Production/Stable
5
5
  Classifier: Intended Audience :: Science/Research
6
6
  Classifier: Operating System :: OS Independent
@@ -24,14 +24,18 @@ Requires-Dist: ruff>=0.1.0 ; extra == 'dev'
24
24
  Requires-Dist: mypy>=1.0 ; extra == 'dev'
25
25
  Requires-Dist: maturin>=1.4,<2.0 ; extra == 'dev'
26
26
  Requires-Dist: matplotlib>=3.5 ; extra == 'dev'
27
+ Requires-Dist: nbmake>=1.5 ; extra == 'dev'
28
+ Requires-Dist: plotly>=5.0 ; extra == 'dev'
27
29
  Requires-Dist: sphinx>=6.0 ; extra == 'docs'
28
30
  Requires-Dist: pydata-sphinx-theme>=0.15 ; extra == 'docs'
29
31
  Requires-Dist: sphinxext-opengraph>=0.9 ; extra == 'docs'
30
32
  Requires-Dist: sphinx-sitemap>=2.5 ; extra == 'docs'
31
33
  Requires-Dist: nbsphinx>=0.9 ; extra == 'docs'
32
34
  Requires-Dist: matplotlib>=3.5 ; extra == 'docs'
35
+ Requires-Dist: plotly>=5.0 ; extra == 'plotly'
33
36
  Provides-Extra: dev
34
37
  Provides-Extra: docs
38
+ Provides-Extra: plotly
35
39
  Summary: Difference-in-Differences causal inference with sklearn-like API. Callaway-Sant'Anna, Synthetic DiD, Honest DiD, event studies, parallel trends.
36
40
  Keywords: causal-inference,difference-in-differences,econometrics,statistics,treatment-effects,event-study,staggered-adoption,parallel-trends,synthetic-control,panel-data,did,twfe,callaway-santanna,honest-did,sensitivity-analysis
37
41
  Author: diff-diff contributors
@@ -95,8 +95,10 @@ from diff_diff.results import (
95
95
  SyntheticDiDResults,
96
96
  )
97
97
  from diff_diff.survey import (
98
+ DEFFDiagnostics,
98
99
  SurveyDesign,
99
100
  SurveyMetadata,
101
+ compute_deff_diagnostics,
100
102
  )
101
103
  from diff_diff.staggered import (
102
104
  CallawaySantAnna,
@@ -155,13 +157,18 @@ from diff_diff.utils import (
155
157
  )
156
158
  from diff_diff.visualization import (
157
159
  plot_bacon,
160
+ plot_dose_response,
158
161
  plot_event_study,
159
162
  plot_group_effects,
163
+ plot_group_time_heatmap,
160
164
  plot_honest_event_study,
161
165
  plot_power_curve,
162
166
  plot_pretrends_power,
163
167
  plot_sensitivity,
168
+ plot_staircase,
169
+ plot_synth_weights,
164
170
  )
171
+ from diff_diff.practitioner import practitioner_next_steps
165
172
  from diff_diff.datasets import (
166
173
  clear_cache,
167
174
  list_datasets,
@@ -187,7 +194,7 @@ Stacked = StackedDiD
187
194
  Bacon = BaconDecomposition
188
195
  EDiD = EfficientDiD
189
196
 
190
- __version__ = "2.7.4"
197
+ __version__ = "2.7.6"
191
198
  __all__ = [
192
199
  # Estimators
193
200
  "DifferenceInDifferences",
@@ -220,7 +227,6 @@ __all__ = [
220
227
  "BaconDecompositionResults",
221
228
  "Comparison2x2",
222
229
  "bacon_decompose",
223
- "plot_bacon",
224
230
  # Results
225
231
  "DiDResults",
226
232
  "MultiPeriodDiDResults",
@@ -251,10 +257,17 @@ __all__ = [
251
257
  "EDiDBootstrapResults",
252
258
  "EDiD",
253
259
  # Visualization
260
+ "plot_bacon",
254
261
  "plot_event_study",
255
262
  "plot_group_effects",
256
263
  "plot_sensitivity",
257
264
  "plot_honest_event_study",
265
+ "plot_power_curve",
266
+ "plot_pretrends_power",
267
+ "plot_synth_weights",
268
+ "plot_staircase",
269
+ "plot_dose_response",
270
+ "plot_group_time_heatmap",
258
271
  # Parallel trends testing
259
272
  "check_parallel_trends",
260
273
  "check_parallel_trends_robust",
@@ -308,17 +321,17 @@ __all__ = [
308
321
  "simulate_mde",
309
322
  "simulate_power",
310
323
  "simulate_sample_size",
311
- "plot_power_curve",
312
324
  # Pre-trends power analysis
313
325
  "PreTrendsPower",
314
326
  "PreTrendsPowerResults",
315
327
  "PreTrendsPowerCurve",
316
328
  "compute_pretrends_power",
317
329
  "compute_mdv",
318
- "plot_pretrends_power",
319
330
  # Survey support
320
331
  "SurveyDesign",
321
332
  "SurveyMetadata",
333
+ "DEFFDiagnostics",
334
+ "compute_deff_diagnostics",
322
335
  # Rust backend
323
336
  "HAS_RUST_BACKEND",
324
337
  # Linear algebra helpers
@@ -332,4 +345,6 @@ __all__ = [
332
345
  "load_dataset",
333
346
  "list_datasets",
334
347
  "clear_cache",
348
+ # Practitioner guidance
349
+ "practitioner_next_steps",
335
350
  ]
@@ -13,7 +13,7 @@ import os
13
13
 
14
14
  # Check for backend override via environment variable
15
15
  # DIFF_DIFF_BACKEND can be: 'auto' (default), 'python', or 'rust'
16
- _backend_env = os.environ.get('DIFF_DIFF_BACKEND', 'auto').lower()
16
+ _backend_env = os.environ.get("DIFF_DIFF_BACKEND", "auto").lower()
17
17
 
18
18
  # Try to import Rust backend for accelerated operations
19
19
  try:
@@ -38,6 +38,7 @@ try:
38
38
  # Diagnostics
39
39
  rust_backend_info as _rust_backend_info,
40
40
  )
41
+
41
42
  _rust_available = True
42
43
  except ImportError:
43
44
  _rust_available = False
@@ -61,7 +62,7 @@ except ImportError:
61
62
  _rust_backend_info = None
62
63
 
63
64
  # Determine final backend based on environment variable and availability
64
- if _backend_env == 'python':
65
+ if _backend_env == "python":
65
66
  # Force pure Python mode - disable Rust even if available
66
67
  HAS_RUST_BACKEND = False
67
68
  _rust_bootstrap_weights = None
@@ -82,7 +83,7 @@ if _backend_env == 'python':
82
83
  _rust_compute_noise_level = None
83
84
  _rust_sc_weight_fw = None
84
85
  _rust_backend_info = None
85
- elif _backend_env == 'rust':
86
+ elif _backend_env == "rust":
86
87
  # Force Rust mode - fail if not available
87
88
  if not _rust_available:
88
89
  raise ImportError(
@@ -111,23 +112,23 @@ def rust_backend_info():
111
112
 
112
113
 
113
114
  __all__ = [
114
- 'HAS_RUST_BACKEND',
115
- 'rust_backend_info',
116
- '_rust_bootstrap_weights',
117
- '_rust_synthetic_weights',
118
- '_rust_project_simplex',
119
- '_rust_solve_ols',
120
- '_rust_compute_robust_vcov',
115
+ "HAS_RUST_BACKEND",
116
+ "rust_backend_info",
117
+ "_rust_bootstrap_weights",
118
+ "_rust_synthetic_weights",
119
+ "_rust_project_simplex",
120
+ "_rust_solve_ols",
121
+ "_rust_compute_robust_vcov",
121
122
  # TROP estimator acceleration (local method)
122
- '_rust_unit_distance_matrix',
123
- '_rust_loocv_grid_search',
124
- '_rust_bootstrap_trop_variance',
123
+ "_rust_unit_distance_matrix",
124
+ "_rust_loocv_grid_search",
125
+ "_rust_bootstrap_trop_variance",
125
126
  # TROP estimator acceleration (global method)
126
- '_rust_loocv_grid_search_global',
127
- '_rust_bootstrap_trop_variance_global',
127
+ "_rust_loocv_grid_search_global",
128
+ "_rust_bootstrap_trop_variance_global",
128
129
  # SDID weights (Frank-Wolfe matching R's synthdid)
129
- '_rust_sdid_unit_weights',
130
- '_rust_compute_time_weights',
131
- '_rust_compute_noise_level',
132
- '_rust_sc_weight_fw',
130
+ "_rust_sdid_unit_weights",
131
+ "_rust_compute_time_weights",
132
+ "_rust_compute_noise_level",
133
+ "_rust_sc_weight_fw",
133
134
  ]