diff-diff 2.4.3__tar.gz → 2.6.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 (48) hide show
  1. {diff_diff-2.4.3 → diff_diff-2.6.0}/PKG-INFO +133 -2
  2. {diff_diff-2.4.3 → diff_diff-2.6.0}/README.md +132 -1
  3. {diff_diff-2.4.3 → diff_diff-2.6.0}/diff_diff/__init__.py +19 -1
  4. diff_diff-2.6.0/diff_diff/bootstrap_utils.py +279 -0
  5. diff_diff-2.6.0/diff_diff/continuous_did.py +1155 -0
  6. diff_diff-2.6.0/diff_diff/continuous_did_bspline.py +188 -0
  7. diff_diff-2.6.0/diff_diff/continuous_did_results.py +353 -0
  8. {diff_diff-2.4.3 → diff_diff-2.6.0}/diff_diff/prep.py +1 -0
  9. {diff_diff-2.4.3 → diff_diff-2.6.0}/diff_diff/prep_dgp.py +156 -1
  10. diff_diff-2.6.0/diff_diff/stacked_did.py +871 -0
  11. diff_diff-2.6.0/diff_diff/stacked_did_results.py +318 -0
  12. {diff_diff-2.4.3 → diff_diff-2.6.0}/diff_diff/staggered.py +3 -1
  13. {diff_diff-2.4.3 → diff_diff-2.6.0}/diff_diff/staggered_bootstrap.py +23 -251
  14. {diff_diff-2.4.3 → diff_diff-2.6.0}/diff_diff/sun_abraham.py +9 -41
  15. {diff_diff-2.4.3 → diff_diff-2.6.0}/diff_diff/visualization.py +2 -0
  16. {diff_diff-2.4.3 → diff_diff-2.6.0}/pyproject.toml +1 -1
  17. {diff_diff-2.4.3 → diff_diff-2.6.0}/rust/Cargo.lock +12 -12
  18. {diff_diff-2.4.3 → diff_diff-2.6.0}/rust/Cargo.toml +1 -1
  19. {diff_diff-2.4.3 → diff_diff-2.6.0}/diff_diff/_backend.py +0 -0
  20. {diff_diff-2.4.3 → diff_diff-2.6.0}/diff_diff/bacon.py +0 -0
  21. {diff_diff-2.4.3 → diff_diff-2.6.0}/diff_diff/datasets.py +0 -0
  22. {diff_diff-2.4.3 → diff_diff-2.6.0}/diff_diff/diagnostics.py +0 -0
  23. {diff_diff-2.4.3 → diff_diff-2.6.0}/diff_diff/estimators.py +0 -0
  24. {diff_diff-2.4.3 → diff_diff-2.6.0}/diff_diff/honest_did.py +0 -0
  25. {diff_diff-2.4.3 → diff_diff-2.6.0}/diff_diff/imputation.py +0 -0
  26. {diff_diff-2.4.3 → diff_diff-2.6.0}/diff_diff/imputation_bootstrap.py +0 -0
  27. {diff_diff-2.4.3 → diff_diff-2.6.0}/diff_diff/imputation_results.py +0 -0
  28. {diff_diff-2.4.3 → diff_diff-2.6.0}/diff_diff/linalg.py +0 -0
  29. {diff_diff-2.4.3 → diff_diff-2.6.0}/diff_diff/power.py +0 -0
  30. {diff_diff-2.4.3 → diff_diff-2.6.0}/diff_diff/pretrends.py +0 -0
  31. {diff_diff-2.4.3 → diff_diff-2.6.0}/diff_diff/results.py +0 -0
  32. {diff_diff-2.4.3 → diff_diff-2.6.0}/diff_diff/staggered_aggregation.py +0 -0
  33. {diff_diff-2.4.3 → diff_diff-2.6.0}/diff_diff/staggered_results.py +0 -0
  34. {diff_diff-2.4.3 → diff_diff-2.6.0}/diff_diff/synthetic_did.py +0 -0
  35. {diff_diff-2.4.3 → diff_diff-2.6.0}/diff_diff/triple_diff.py +0 -0
  36. {diff_diff-2.4.3 → diff_diff-2.6.0}/diff_diff/trop.py +0 -0
  37. {diff_diff-2.4.3 → diff_diff-2.6.0}/diff_diff/trop_results.py +0 -0
  38. {diff_diff-2.4.3 → diff_diff-2.6.0}/diff_diff/twfe.py +0 -0
  39. {diff_diff-2.4.3 → diff_diff-2.6.0}/diff_diff/two_stage.py +0 -0
  40. {diff_diff-2.4.3 → diff_diff-2.6.0}/diff_diff/two_stage_bootstrap.py +0 -0
  41. {diff_diff-2.4.3 → diff_diff-2.6.0}/diff_diff/two_stage_results.py +0 -0
  42. {diff_diff-2.4.3 → diff_diff-2.6.0}/diff_diff/utils.py +0 -0
  43. {diff_diff-2.4.3 → diff_diff-2.6.0}/rust/build.rs +0 -0
  44. {diff_diff-2.4.3 → diff_diff-2.6.0}/rust/src/bootstrap.rs +0 -0
  45. {diff_diff-2.4.3 → diff_diff-2.6.0}/rust/src/lib.rs +0 -0
  46. {diff_diff-2.4.3 → diff_diff-2.6.0}/rust/src/linalg.rs +0 -0
  47. {diff_diff-2.4.3 → diff_diff-2.6.0}/rust/src/trop.rs +0 -0
  48. {diff_diff-2.4.3 → diff_diff-2.6.0}/rust/src/weights.rs +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: diff-diff
3
- Version: 2.4.3
3
+ Version: 2.6.0
4
4
  Classifier: Development Status :: 5 - Production/Stable
5
5
  Classifier: Intended Audience :: Science/Research
6
6
  Classifier: Operating System :: OS Independent
@@ -108,7 +108,7 @@ Signif. codes: '***' 0.001, '**' 0.01, '*' 0.05, '.' 0.1
108
108
  - **Wild cluster bootstrap**: Valid inference with few clusters (<50) using Rademacher, Webb, or Mammen weights
109
109
  - **Panel data support**: Two-way fixed effects estimator for panel designs
110
110
  - **Multi-period analysis**: Event-study style DiD with period-specific treatment effects
111
- - **Staggered adoption**: Callaway-Sant'Anna (2021), Sun-Abraham (2021), Borusyak-Jaravel-Spiess (2024) imputation, and Two-Stage DiD (Gardner 2022) estimators for heterogeneous treatment timing
111
+ - **Staggered adoption**: Callaway-Sant'Anna (2021), Sun-Abraham (2021), Borusyak-Jaravel-Spiess (2024) imputation, Two-Stage DiD (Gardner 2022), and Stacked DiD (Wing, Freedman & Hollingsworth 2024) estimators for heterogeneous treatment timing
112
112
  - **Triple Difference (DDD)**: Ortiz-Villavicencio & Sant'Anna (2025) estimators with proper covariate handling
113
113
  - **Synthetic DiD**: Combined DiD with synthetic control for improved robustness
114
114
  - **Triply Robust Panel (TROP)**: Factor-adjusted DiD with synthetic weights (Athey et al. 2025)
@@ -138,6 +138,9 @@ We provide Jupyter notebook tutorials in `docs/tutorials/`:
138
138
  | `08_triple_diff.ipynb` | Triple Difference (DDD) estimation with proper covariate handling |
139
139
  | `09_real_world_examples.ipynb` | Real-world data examples (Card-Krueger, Castle Doctrine, Divorce Laws) |
140
140
  | `10_trop.ipynb` | Triply Robust Panel (TROP) estimation with factor model adjustment |
141
+ | `11_imputation_did.ipynb` | Imputation DiD (Borusyak et al. 2024), pre-trend test, efficiency comparison |
142
+ | `12_two_stage_did.ipynb` | Two-Stage DiD (Gardner 2022), GMM sandwich variance, per-observation effects |
143
+ | `13_stacked_did.ipynb` | Stacked DiD (Wing et al. 2024), Q-weights, sub-experiment inspection, trimming, clean control definitions |
141
144
 
142
145
  ## Data Preparation
143
146
 
@@ -1012,6 +1015,78 @@ TwoStageDiD(
1012
1015
 
1013
1016
  Both estimators are the efficient estimator under homogeneous treatment effects, producing shorter confidence intervals than Callaway-Sant'Anna or Sun-Abraham.
1014
1017
 
1018
+ ### Stacked DiD (Wing, Freedman & Hollingsworth 2024)
1019
+
1020
+ Stacked DiD addresses TWFE bias in staggered adoption settings by constructing a "clean" comparison dataset for each treatment cohort and stacking them together. Each cohort's sub-experiment compares units treated at that cohort's timing against units that are not yet treated (or never treated) within a symmetric event-study window. This avoids the "bad comparisons" problem in TWFE while retaining a regression-based framework that practitioners familiar with event studies will find intuitive.
1021
+
1022
+ ```python
1023
+ from diff_diff import StackedDiD, generate_staggered_data
1024
+
1025
+ # Generate sample data
1026
+ data = generate_staggered_data(n_units=200, n_periods=12,
1027
+ cohort_periods=[4, 6, 8], seed=42)
1028
+
1029
+ # Fit stacked DiD with event study
1030
+ est = StackedDiD(kappa_pre=2, kappa_post=2)
1031
+ results = est.fit(data, outcome='outcome', unit='unit',
1032
+ time='period', first_treat='first_treat',
1033
+ aggregate='event_study')
1034
+ results.print_summary()
1035
+
1036
+ # Access stacked data for custom analysis
1037
+ stacked = results.stacked_data
1038
+
1039
+ # Convenience function
1040
+ from diff_diff import stacked_did
1041
+ results = stacked_did(data, 'outcome', 'unit', 'period', 'first_treat',
1042
+ kappa_pre=2, kappa_post=2, aggregate='event_study')
1043
+ ```
1044
+
1045
+ **Parameters:**
1046
+
1047
+ ```python
1048
+ StackedDiD(
1049
+ kappa_pre=1, # Pre-treatment event-study periods
1050
+ kappa_post=1, # Post-treatment event-study periods
1051
+ weighting='aggregate', # 'aggregate', 'population', or 'sample_share'
1052
+ clean_control='not_yet_treated', # 'not_yet_treated', 'strict', or 'never_treated'
1053
+ cluster='unit', # 'unit' or 'unit_subexp'
1054
+ alpha=0.05, # Significance level
1055
+ anticipation=0, # Anticipation periods
1056
+ rank_deficient_action='warn', # 'warn', 'error', or 'silent'
1057
+ )
1058
+ ```
1059
+
1060
+ > **Note:** Group aggregation (`aggregate='group'`) is not supported because the pooled
1061
+ > stacked regression cannot produce cohort-specific effects. Use `CallawaySantAnna` or
1062
+ > `ImputationDiD` for cohort-level estimates.
1063
+
1064
+ **When to use Stacked DiD vs Callaway-Sant'Anna:**
1065
+
1066
+ | Aspect | Stacked DiD | Callaway-Sant'Anna |
1067
+ |--------|-------------|-------------------|
1068
+ | Approach | Stack cohort sub-experiments, run pooled TWFE | 2x2 DiD aggregation |
1069
+ | Symmetric windows | Enforced via kappa_pre / kappa_post | Not required |
1070
+ | Control group | Not-yet-treated (default) or never-treated | Never-treated or not-yet-treated |
1071
+ | Covariates | Passed to pooled regression | Doubly robust / IPW |
1072
+ | Intuition | Familiar event-study regression | Nonparametric aggregation |
1073
+
1074
+ **Convenience function:**
1075
+
1076
+ ```python
1077
+ # One-liner estimation
1078
+ results = stacked_did(
1079
+ data,
1080
+ outcome='outcome',
1081
+ unit='unit',
1082
+ time='period',
1083
+ first_treat='first_treat',
1084
+ kappa_pre=3,
1085
+ kappa_post=3,
1086
+ aggregate='event_study'
1087
+ )
1088
+ ```
1089
+
1015
1090
  ### Triple Difference (DDD)
1016
1091
 
1017
1092
  Triple Difference (DDD) is used when treatment requires satisfying two criteria: belonging to a treated **group** AND being in an eligible **partition**. The `TripleDifference` class implements the methodology from Ortiz-Villavicencio & Sant'Anna (2025), which correctly handles covariate adjustment (unlike naive implementations).
@@ -2241,6 +2316,60 @@ TwoStageDiD(
2241
2316
  | `print_summary(alpha)` | Print summary to stdout |
2242
2317
  | `to_dataframe(level)` | Convert to DataFrame ('observation', 'event_study', 'group') |
2243
2318
 
2319
+ ### StackedDiD
2320
+
2321
+ ```python
2322
+ StackedDiD(
2323
+ kappa_pre=1, # Pre-treatment event-study periods
2324
+ kappa_post=1, # Post-treatment event-study periods
2325
+ weighting='aggregate', # 'aggregate', 'population', or 'sample_share'
2326
+ clean_control='not_yet_treated', # 'not_yet_treated', 'strict', or 'never_treated'
2327
+ cluster='unit', # 'unit' or 'unit_subexp'
2328
+ alpha=0.05, # Significance level
2329
+ anticipation=0, # Anticipation periods
2330
+ rank_deficient_action='warn', # 'warn', 'error', or 'silent'
2331
+ )
2332
+ ```
2333
+
2334
+ **fit() Parameters:**
2335
+
2336
+ | Parameter | Type | Description |
2337
+ |-----------|------|-------------|
2338
+ | `data` | DataFrame | Panel data |
2339
+ | `outcome` | str | Outcome variable column name |
2340
+ | `unit` | str | Unit identifier column |
2341
+ | `time` | str | Time period column |
2342
+ | `first_treat` | str | First treatment period column (0 for never-treated) |
2343
+ | `population` | str, optional | Population column (required if weighting='population') |
2344
+ | `aggregate` | str | Aggregation: None, `"simple"`, or `"event_study"` |
2345
+
2346
+ ### StackedDiDResults
2347
+
2348
+ **Attributes:**
2349
+
2350
+ | Attribute | Description |
2351
+ |-----------|-------------|
2352
+ | `overall_att` | Overall average treatment effect on the treated |
2353
+ | `overall_se` | Standard error |
2354
+ | `overall_t_stat` | T-statistic |
2355
+ | `overall_p_value` | P-value for H0: ATT = 0 |
2356
+ | `overall_conf_int` | Confidence interval |
2357
+ | `event_study_effects` | Dict of relative time -> effect dict (if `aggregate='event_study'`) |
2358
+ | `stacked_data` | The stacked dataset used for estimation |
2359
+ | `n_treated_obs` | Number of treated observations |
2360
+ | `n_untreated_obs` | Number of untreated (clean control) observations |
2361
+ | `n_cohorts` | Number of treatment cohorts |
2362
+ | `kappa_pre` | Pre-treatment window used |
2363
+ | `kappa_post` | Post-treatment window used |
2364
+
2365
+ **Methods:**
2366
+
2367
+ | Method | Description |
2368
+ |--------|-------------|
2369
+ | `summary(alpha)` | Get formatted summary string |
2370
+ | `print_summary(alpha)` | Print summary to stdout |
2371
+ | `to_dataframe(level)` | Convert to DataFrame ('event_study') |
2372
+
2244
2373
  ### TripleDifference
2245
2374
 
2246
2375
  ```python
@@ -2727,6 +2856,8 @@ The `HonestDiD` module implements sensitivity analysis methods for relaxing the
2727
2856
 
2728
2857
  - **Goodman-Bacon, A. (2021).** "Difference-in-Differences with Variation in Treatment Timing." *Journal of Econometrics*, 225(2), 254-277. [https://doi.org/10.1016/j.jeconom.2021.03.014](https://doi.org/10.1016/j.jeconom.2021.03.014)
2729
2858
 
2859
+ - **Wing, C., Freedman, S. M., & Hollingsworth, A. (2024).** "Stacked Difference-in-Differences." *NBER Working Paper* 32054. [https://www.nber.org/papers/w32054](https://www.nber.org/papers/w32054)
2860
+
2730
2861
  ### Power Analysis
2731
2862
 
2732
2863
  - **Bloom, H. S. (1995).** "Minimum Detectable Effects: A Simple Way to Report the Statistical Power of Experimental Designs." *Evaluation Review*, 19(5), 547-556. [https://doi.org/10.1177/0193841X9501900504](https://doi.org/10.1177/0193841X9501900504)
@@ -70,7 +70,7 @@ Signif. codes: '***' 0.001, '**' 0.01, '*' 0.05, '.' 0.1
70
70
  - **Wild cluster bootstrap**: Valid inference with few clusters (<50) using Rademacher, Webb, or Mammen weights
71
71
  - **Panel data support**: Two-way fixed effects estimator for panel designs
72
72
  - **Multi-period analysis**: Event-study style DiD with period-specific treatment effects
73
- - **Staggered adoption**: Callaway-Sant'Anna (2021), Sun-Abraham (2021), Borusyak-Jaravel-Spiess (2024) imputation, and Two-Stage DiD (Gardner 2022) estimators for heterogeneous treatment timing
73
+ - **Staggered adoption**: Callaway-Sant'Anna (2021), Sun-Abraham (2021), Borusyak-Jaravel-Spiess (2024) imputation, Two-Stage DiD (Gardner 2022), and Stacked DiD (Wing, Freedman & Hollingsworth 2024) estimators for heterogeneous treatment timing
74
74
  - **Triple Difference (DDD)**: Ortiz-Villavicencio & Sant'Anna (2025) estimators with proper covariate handling
75
75
  - **Synthetic DiD**: Combined DiD with synthetic control for improved robustness
76
76
  - **Triply Robust Panel (TROP)**: Factor-adjusted DiD with synthetic weights (Athey et al. 2025)
@@ -100,6 +100,9 @@ We provide Jupyter notebook tutorials in `docs/tutorials/`:
100
100
  | `08_triple_diff.ipynb` | Triple Difference (DDD) estimation with proper covariate handling |
101
101
  | `09_real_world_examples.ipynb` | Real-world data examples (Card-Krueger, Castle Doctrine, Divorce Laws) |
102
102
  | `10_trop.ipynb` | Triply Robust Panel (TROP) estimation with factor model adjustment |
103
+ | `11_imputation_did.ipynb` | Imputation DiD (Borusyak et al. 2024), pre-trend test, efficiency comparison |
104
+ | `12_two_stage_did.ipynb` | Two-Stage DiD (Gardner 2022), GMM sandwich variance, per-observation effects |
105
+ | `13_stacked_did.ipynb` | Stacked DiD (Wing et al. 2024), Q-weights, sub-experiment inspection, trimming, clean control definitions |
103
106
 
104
107
  ## Data Preparation
105
108
 
@@ -974,6 +977,78 @@ TwoStageDiD(
974
977
 
975
978
  Both estimators are the efficient estimator under homogeneous treatment effects, producing shorter confidence intervals than Callaway-Sant'Anna or Sun-Abraham.
976
979
 
980
+ ### Stacked DiD (Wing, Freedman & Hollingsworth 2024)
981
+
982
+ Stacked DiD addresses TWFE bias in staggered adoption settings by constructing a "clean" comparison dataset for each treatment cohort and stacking them together. Each cohort's sub-experiment compares units treated at that cohort's timing against units that are not yet treated (or never treated) within a symmetric event-study window. This avoids the "bad comparisons" problem in TWFE while retaining a regression-based framework that practitioners familiar with event studies will find intuitive.
983
+
984
+ ```python
985
+ from diff_diff import StackedDiD, generate_staggered_data
986
+
987
+ # Generate sample data
988
+ data = generate_staggered_data(n_units=200, n_periods=12,
989
+ cohort_periods=[4, 6, 8], seed=42)
990
+
991
+ # Fit stacked DiD with event study
992
+ est = StackedDiD(kappa_pre=2, kappa_post=2)
993
+ results = est.fit(data, outcome='outcome', unit='unit',
994
+ time='period', first_treat='first_treat',
995
+ aggregate='event_study')
996
+ results.print_summary()
997
+
998
+ # Access stacked data for custom analysis
999
+ stacked = results.stacked_data
1000
+
1001
+ # Convenience function
1002
+ from diff_diff import stacked_did
1003
+ results = stacked_did(data, 'outcome', 'unit', 'period', 'first_treat',
1004
+ kappa_pre=2, kappa_post=2, aggregate='event_study')
1005
+ ```
1006
+
1007
+ **Parameters:**
1008
+
1009
+ ```python
1010
+ StackedDiD(
1011
+ kappa_pre=1, # Pre-treatment event-study periods
1012
+ kappa_post=1, # Post-treatment event-study periods
1013
+ weighting='aggregate', # 'aggregate', 'population', or 'sample_share'
1014
+ clean_control='not_yet_treated', # 'not_yet_treated', 'strict', or 'never_treated'
1015
+ cluster='unit', # 'unit' or 'unit_subexp'
1016
+ alpha=0.05, # Significance level
1017
+ anticipation=0, # Anticipation periods
1018
+ rank_deficient_action='warn', # 'warn', 'error', or 'silent'
1019
+ )
1020
+ ```
1021
+
1022
+ > **Note:** Group aggregation (`aggregate='group'`) is not supported because the pooled
1023
+ > stacked regression cannot produce cohort-specific effects. Use `CallawaySantAnna` or
1024
+ > `ImputationDiD` for cohort-level estimates.
1025
+
1026
+ **When to use Stacked DiD vs Callaway-Sant'Anna:**
1027
+
1028
+ | Aspect | Stacked DiD | Callaway-Sant'Anna |
1029
+ |--------|-------------|-------------------|
1030
+ | Approach | Stack cohort sub-experiments, run pooled TWFE | 2x2 DiD aggregation |
1031
+ | Symmetric windows | Enforced via kappa_pre / kappa_post | Not required |
1032
+ | Control group | Not-yet-treated (default) or never-treated | Never-treated or not-yet-treated |
1033
+ | Covariates | Passed to pooled regression | Doubly robust / IPW |
1034
+ | Intuition | Familiar event-study regression | Nonparametric aggregation |
1035
+
1036
+ **Convenience function:**
1037
+
1038
+ ```python
1039
+ # One-liner estimation
1040
+ results = stacked_did(
1041
+ data,
1042
+ outcome='outcome',
1043
+ unit='unit',
1044
+ time='period',
1045
+ first_treat='first_treat',
1046
+ kappa_pre=3,
1047
+ kappa_post=3,
1048
+ aggregate='event_study'
1049
+ )
1050
+ ```
1051
+
977
1052
  ### Triple Difference (DDD)
978
1053
 
979
1054
  Triple Difference (DDD) is used when treatment requires satisfying two criteria: belonging to a treated **group** AND being in an eligible **partition**. The `TripleDifference` class implements the methodology from Ortiz-Villavicencio & Sant'Anna (2025), which correctly handles covariate adjustment (unlike naive implementations).
@@ -2203,6 +2278,60 @@ TwoStageDiD(
2203
2278
  | `print_summary(alpha)` | Print summary to stdout |
2204
2279
  | `to_dataframe(level)` | Convert to DataFrame ('observation', 'event_study', 'group') |
2205
2280
 
2281
+ ### StackedDiD
2282
+
2283
+ ```python
2284
+ StackedDiD(
2285
+ kappa_pre=1, # Pre-treatment event-study periods
2286
+ kappa_post=1, # Post-treatment event-study periods
2287
+ weighting='aggregate', # 'aggregate', 'population', or 'sample_share'
2288
+ clean_control='not_yet_treated', # 'not_yet_treated', 'strict', or 'never_treated'
2289
+ cluster='unit', # 'unit' or 'unit_subexp'
2290
+ alpha=0.05, # Significance level
2291
+ anticipation=0, # Anticipation periods
2292
+ rank_deficient_action='warn', # 'warn', 'error', or 'silent'
2293
+ )
2294
+ ```
2295
+
2296
+ **fit() Parameters:**
2297
+
2298
+ | Parameter | Type | Description |
2299
+ |-----------|------|-------------|
2300
+ | `data` | DataFrame | Panel data |
2301
+ | `outcome` | str | Outcome variable column name |
2302
+ | `unit` | str | Unit identifier column |
2303
+ | `time` | str | Time period column |
2304
+ | `first_treat` | str | First treatment period column (0 for never-treated) |
2305
+ | `population` | str, optional | Population column (required if weighting='population') |
2306
+ | `aggregate` | str | Aggregation: None, `"simple"`, or `"event_study"` |
2307
+
2308
+ ### StackedDiDResults
2309
+
2310
+ **Attributes:**
2311
+
2312
+ | Attribute | Description |
2313
+ |-----------|-------------|
2314
+ | `overall_att` | Overall average treatment effect on the treated |
2315
+ | `overall_se` | Standard error |
2316
+ | `overall_t_stat` | T-statistic |
2317
+ | `overall_p_value` | P-value for H0: ATT = 0 |
2318
+ | `overall_conf_int` | Confidence interval |
2319
+ | `event_study_effects` | Dict of relative time -> effect dict (if `aggregate='event_study'`) |
2320
+ | `stacked_data` | The stacked dataset used for estimation |
2321
+ | `n_treated_obs` | Number of treated observations |
2322
+ | `n_untreated_obs` | Number of untreated (clean control) observations |
2323
+ | `n_cohorts` | Number of treatment cohorts |
2324
+ | `kappa_pre` | Pre-treatment window used |
2325
+ | `kappa_post` | Post-treatment window used |
2326
+
2327
+ **Methods:**
2328
+
2329
+ | Method | Description |
2330
+ |--------|-------------|
2331
+ | `summary(alpha)` | Get formatted summary string |
2332
+ | `print_summary(alpha)` | Print summary to stdout |
2333
+ | `to_dataframe(level)` | Convert to DataFrame ('event_study') |
2334
+
2206
2335
  ### TripleDifference
2207
2336
 
2208
2337
  ```python
@@ -2689,6 +2818,8 @@ The `HonestDiD` module implements sensitivity analysis methods for relaxing the
2689
2818
 
2690
2819
  - **Goodman-Bacon, A. (2021).** "Difference-in-Differences with Variation in Treatment Timing." *Journal of Econometrics*, 225(2), 254-277. [https://doi.org/10.1016/j.jeconom.2021.03.014](https://doi.org/10.1016/j.jeconom.2021.03.014)
2691
2820
 
2821
+ - **Wing, C., Freedman, S. M., & Hollingsworth, A. (2024).** "Stacked Difference-in-Differences." *NBER Working Paper* 32054. [https://www.nber.org/papers/w32054](https://www.nber.org/papers/w32054)
2822
+
2692
2823
  ### Power Analysis
2693
2824
 
2694
2825
  - **Bloom, H. S. (1995).** "Minimum Detectable Effects: A Simple Way to Report the Statistical Power of Experimental Designs." *Evaluation Review*, 19(5), 547-556. [https://doi.org/10.1177/0193841X9501900504](https://doi.org/10.1177/0193841X9501900504)
@@ -70,6 +70,7 @@ from diff_diff.prep import (
70
70
  aggregate_to_cohorts,
71
71
  balance_panel,
72
72
  create_event_time,
73
+ generate_continuous_did_data,
73
74
  generate_did_data,
74
75
  generate_ddd_data,
75
76
  generate_event_study_data,
@@ -107,6 +108,11 @@ from diff_diff.two_stage import (
107
108
  TwoStageDiDResults,
108
109
  two_stage_did,
109
110
  )
111
+ from diff_diff.stacked_did import (
112
+ StackedDiD,
113
+ StackedDiDResults,
114
+ stacked_did,
115
+ )
110
116
  from diff_diff.sun_abraham import (
111
117
  SABootstrapResults,
112
118
  SunAbraham,
@@ -117,6 +123,11 @@ from diff_diff.triple_diff import (
117
123
  TripleDifferenceResults,
118
124
  triple_difference,
119
125
  )
126
+ from diff_diff.continuous_did import (
127
+ ContinuousDiD,
128
+ ContinuousDiDResults,
129
+ DoseResponseCurve,
130
+ )
120
131
  from diff_diff.trop import (
121
132
  TROP,
122
133
  TROPResults,
@@ -148,7 +159,7 @@ from diff_diff.datasets import (
148
159
  load_mpdta,
149
160
  )
150
161
 
151
- __version__ = "2.4.3"
162
+ __version__ = "2.6.0"
152
163
  __all__ = [
153
164
  # Estimators
154
165
  "DifferenceInDifferences",
@@ -156,11 +167,13 @@ __all__ = [
156
167
  "MultiPeriodDiD",
157
168
  "SyntheticDiD",
158
169
  "CallawaySantAnna",
170
+ "ContinuousDiD",
159
171
  "SunAbraham",
160
172
  "ImputationDiD",
161
173
  "TwoStageDiD",
162
174
  "TripleDifference",
163
175
  "TROP",
176
+ "StackedDiD",
164
177
  # Bacon Decomposition
165
178
  "BaconDecomposition",
166
179
  "BaconDecompositionResults",
@@ -175,6 +188,8 @@ __all__ = [
175
188
  "CallawaySantAnnaResults",
176
189
  "CSBootstrapResults",
177
190
  "GroupTimeEffect",
191
+ "ContinuousDiDResults",
192
+ "DoseResponseCurve",
178
193
  "SunAbrahamResults",
179
194
  "SABootstrapResults",
180
195
  "ImputationDiDResults",
@@ -187,6 +202,8 @@ __all__ = [
187
202
  "triple_difference",
188
203
  "TROPResults",
189
204
  "trop",
205
+ "StackedDiDResults",
206
+ "stacked_did",
190
207
  # Visualization
191
208
  "plot_event_study",
192
209
  "plot_group_effects",
@@ -220,6 +237,7 @@ __all__ = [
220
237
  "generate_ddd_data",
221
238
  "generate_panel_data",
222
239
  "generate_event_study_data",
240
+ "generate_continuous_did_data",
223
241
  "create_event_time",
224
242
  "aggregate_to_cohorts",
225
243
  "rank_control_units",