diff-diff 2.4.3__tar.gz → 2.5.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 (44) hide show
  1. {diff_diff-2.4.3 → diff_diff-2.5.0}/PKG-INFO +130 -2
  2. {diff_diff-2.4.3 → diff_diff-2.5.0}/README.md +129 -1
  3. {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/__init__.py +9 -1
  4. diff_diff-2.5.0/diff_diff/stacked_did.py +871 -0
  5. diff_diff-2.5.0/diff_diff/stacked_did_results.py +318 -0
  6. {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/visualization.py +2 -0
  7. {diff_diff-2.4.3 → diff_diff-2.5.0}/pyproject.toml +1 -1
  8. {diff_diff-2.4.3 → diff_diff-2.5.0}/rust/Cargo.lock +1 -1
  9. {diff_diff-2.4.3 → diff_diff-2.5.0}/rust/Cargo.toml +1 -1
  10. {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/_backend.py +0 -0
  11. {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/bacon.py +0 -0
  12. {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/datasets.py +0 -0
  13. {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/diagnostics.py +0 -0
  14. {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/estimators.py +0 -0
  15. {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/honest_did.py +0 -0
  16. {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/imputation.py +0 -0
  17. {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/imputation_bootstrap.py +0 -0
  18. {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/imputation_results.py +0 -0
  19. {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/linalg.py +0 -0
  20. {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/power.py +0 -0
  21. {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/prep.py +0 -0
  22. {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/prep_dgp.py +0 -0
  23. {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/pretrends.py +0 -0
  24. {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/results.py +0 -0
  25. {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/staggered.py +0 -0
  26. {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/staggered_aggregation.py +0 -0
  27. {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/staggered_bootstrap.py +0 -0
  28. {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/staggered_results.py +0 -0
  29. {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/sun_abraham.py +0 -0
  30. {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/synthetic_did.py +0 -0
  31. {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/triple_diff.py +0 -0
  32. {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/trop.py +0 -0
  33. {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/trop_results.py +0 -0
  34. {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/twfe.py +0 -0
  35. {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/two_stage.py +0 -0
  36. {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/two_stage_bootstrap.py +0 -0
  37. {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/two_stage_results.py +0 -0
  38. {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/utils.py +0 -0
  39. {diff_diff-2.4.3 → diff_diff-2.5.0}/rust/build.rs +0 -0
  40. {diff_diff-2.4.3 → diff_diff-2.5.0}/rust/src/bootstrap.rs +0 -0
  41. {diff_diff-2.4.3 → diff_diff-2.5.0}/rust/src/lib.rs +0 -0
  42. {diff_diff-2.4.3 → diff_diff-2.5.0}/rust/src/linalg.rs +0 -0
  43. {diff_diff-2.4.3 → diff_diff-2.5.0}/rust/src/trop.rs +0 -0
  44. {diff_diff-2.4.3 → diff_diff-2.5.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.5.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)
@@ -1012,6 +1012,78 @@ TwoStageDiD(
1012
1012
 
1013
1013
  Both estimators are the efficient estimator under homogeneous treatment effects, producing shorter confidence intervals than Callaway-Sant'Anna or Sun-Abraham.
1014
1014
 
1015
+ ### Stacked DiD (Wing, Freedman & Hollingsworth 2024)
1016
+
1017
+ 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.
1018
+
1019
+ ```python
1020
+ from diff_diff import StackedDiD, generate_staggered_data
1021
+
1022
+ # Generate sample data
1023
+ data = generate_staggered_data(n_units=200, n_periods=12,
1024
+ cohort_periods=[4, 6, 8], seed=42)
1025
+
1026
+ # Fit stacked DiD with event study
1027
+ est = StackedDiD(kappa_pre=2, kappa_post=2)
1028
+ results = est.fit(data, outcome='outcome', unit='unit',
1029
+ time='period', first_treat='first_treat',
1030
+ aggregate='event_study')
1031
+ results.print_summary()
1032
+
1033
+ # Access stacked data for custom analysis
1034
+ stacked = results.stacked_data
1035
+
1036
+ # Convenience function
1037
+ from diff_diff import stacked_did
1038
+ results = stacked_did(data, 'outcome', 'unit', 'period', 'first_treat',
1039
+ kappa_pre=2, kappa_post=2, aggregate='event_study')
1040
+ ```
1041
+
1042
+ **Parameters:**
1043
+
1044
+ ```python
1045
+ StackedDiD(
1046
+ kappa_pre=1, # Pre-treatment event-study periods
1047
+ kappa_post=1, # Post-treatment event-study periods
1048
+ weighting='aggregate', # 'aggregate', 'population', or 'sample_share'
1049
+ clean_control='not_yet_treated', # 'not_yet_treated', 'strict', or 'never_treated'
1050
+ cluster='unit', # 'unit' or 'unit_subexp'
1051
+ alpha=0.05, # Significance level
1052
+ anticipation=0, # Anticipation periods
1053
+ rank_deficient_action='warn', # 'warn', 'error', or 'silent'
1054
+ )
1055
+ ```
1056
+
1057
+ > **Note:** Group aggregation (`aggregate='group'`) is not supported because the pooled
1058
+ > stacked regression cannot produce cohort-specific effects. Use `CallawaySantAnna` or
1059
+ > `ImputationDiD` for cohort-level estimates.
1060
+
1061
+ **When to use Stacked DiD vs Callaway-Sant'Anna:**
1062
+
1063
+ | Aspect | Stacked DiD | Callaway-Sant'Anna |
1064
+ |--------|-------------|-------------------|
1065
+ | Approach | Stack cohort sub-experiments, run pooled TWFE | 2x2 DiD aggregation |
1066
+ | Symmetric windows | Enforced via kappa_pre / kappa_post | Not required |
1067
+ | Control group | Not-yet-treated (default) or never-treated | Never-treated or not-yet-treated |
1068
+ | Covariates | Passed to pooled regression | Doubly robust / IPW |
1069
+ | Intuition | Familiar event-study regression | Nonparametric aggregation |
1070
+
1071
+ **Convenience function:**
1072
+
1073
+ ```python
1074
+ # One-liner estimation
1075
+ results = stacked_did(
1076
+ data,
1077
+ outcome='outcome',
1078
+ unit='unit',
1079
+ time='period',
1080
+ first_treat='first_treat',
1081
+ kappa_pre=3,
1082
+ kappa_post=3,
1083
+ aggregate='event_study'
1084
+ )
1085
+ ```
1086
+
1015
1087
  ### Triple Difference (DDD)
1016
1088
 
1017
1089
  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 +2313,60 @@ TwoStageDiD(
2241
2313
  | `print_summary(alpha)` | Print summary to stdout |
2242
2314
  | `to_dataframe(level)` | Convert to DataFrame ('observation', 'event_study', 'group') |
2243
2315
 
2316
+ ### StackedDiD
2317
+
2318
+ ```python
2319
+ StackedDiD(
2320
+ kappa_pre=1, # Pre-treatment event-study periods
2321
+ kappa_post=1, # Post-treatment event-study periods
2322
+ weighting='aggregate', # 'aggregate', 'population', or 'sample_share'
2323
+ clean_control='not_yet_treated', # 'not_yet_treated', 'strict', or 'never_treated'
2324
+ cluster='unit', # 'unit' or 'unit_subexp'
2325
+ alpha=0.05, # Significance level
2326
+ anticipation=0, # Anticipation periods
2327
+ rank_deficient_action='warn', # 'warn', 'error', or 'silent'
2328
+ )
2329
+ ```
2330
+
2331
+ **fit() Parameters:**
2332
+
2333
+ | Parameter | Type | Description |
2334
+ |-----------|------|-------------|
2335
+ | `data` | DataFrame | Panel data |
2336
+ | `outcome` | str | Outcome variable column name |
2337
+ | `unit` | str | Unit identifier column |
2338
+ | `time` | str | Time period column |
2339
+ | `first_treat` | str | First treatment period column (0 for never-treated) |
2340
+ | `population` | str, optional | Population column (required if weighting='population') |
2341
+ | `aggregate` | str | Aggregation: None, `"simple"`, or `"event_study"` |
2342
+
2343
+ ### StackedDiDResults
2344
+
2345
+ **Attributes:**
2346
+
2347
+ | Attribute | Description |
2348
+ |-----------|-------------|
2349
+ | `overall_att` | Overall average treatment effect on the treated |
2350
+ | `overall_se` | Standard error |
2351
+ | `overall_t_stat` | T-statistic |
2352
+ | `overall_p_value` | P-value for H0: ATT = 0 |
2353
+ | `overall_conf_int` | Confidence interval |
2354
+ | `event_study_effects` | Dict of relative time -> effect dict (if `aggregate='event_study'`) |
2355
+ | `stacked_data` | The stacked dataset used for estimation |
2356
+ | `n_treated_obs` | Number of treated observations |
2357
+ | `n_untreated_obs` | Number of untreated (clean control) observations |
2358
+ | `n_cohorts` | Number of treatment cohorts |
2359
+ | `kappa_pre` | Pre-treatment window used |
2360
+ | `kappa_post` | Post-treatment window used |
2361
+
2362
+ **Methods:**
2363
+
2364
+ | Method | Description |
2365
+ |--------|-------------|
2366
+ | `summary(alpha)` | Get formatted summary string |
2367
+ | `print_summary(alpha)` | Print summary to stdout |
2368
+ | `to_dataframe(level)` | Convert to DataFrame ('event_study') |
2369
+
2244
2370
  ### TripleDifference
2245
2371
 
2246
2372
  ```python
@@ -2727,6 +2853,8 @@ The `HonestDiD` module implements sensitivity analysis methods for relaxing the
2727
2853
 
2728
2854
  - **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
2855
 
2856
+ - **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)
2857
+
2730
2858
  ### Power Analysis
2731
2859
 
2732
2860
  - **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)
@@ -974,6 +974,78 @@ TwoStageDiD(
974
974
 
975
975
  Both estimators are the efficient estimator under homogeneous treatment effects, producing shorter confidence intervals than Callaway-Sant'Anna or Sun-Abraham.
976
976
 
977
+ ### Stacked DiD (Wing, Freedman & Hollingsworth 2024)
978
+
979
+ 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.
980
+
981
+ ```python
982
+ from diff_diff import StackedDiD, generate_staggered_data
983
+
984
+ # Generate sample data
985
+ data = generate_staggered_data(n_units=200, n_periods=12,
986
+ cohort_periods=[4, 6, 8], seed=42)
987
+
988
+ # Fit stacked DiD with event study
989
+ est = StackedDiD(kappa_pre=2, kappa_post=2)
990
+ results = est.fit(data, outcome='outcome', unit='unit',
991
+ time='period', first_treat='first_treat',
992
+ aggregate='event_study')
993
+ results.print_summary()
994
+
995
+ # Access stacked data for custom analysis
996
+ stacked = results.stacked_data
997
+
998
+ # Convenience function
999
+ from diff_diff import stacked_did
1000
+ results = stacked_did(data, 'outcome', 'unit', 'period', 'first_treat',
1001
+ kappa_pre=2, kappa_post=2, aggregate='event_study')
1002
+ ```
1003
+
1004
+ **Parameters:**
1005
+
1006
+ ```python
1007
+ StackedDiD(
1008
+ kappa_pre=1, # Pre-treatment event-study periods
1009
+ kappa_post=1, # Post-treatment event-study periods
1010
+ weighting='aggregate', # 'aggregate', 'population', or 'sample_share'
1011
+ clean_control='not_yet_treated', # 'not_yet_treated', 'strict', or 'never_treated'
1012
+ cluster='unit', # 'unit' or 'unit_subexp'
1013
+ alpha=0.05, # Significance level
1014
+ anticipation=0, # Anticipation periods
1015
+ rank_deficient_action='warn', # 'warn', 'error', or 'silent'
1016
+ )
1017
+ ```
1018
+
1019
+ > **Note:** Group aggregation (`aggregate='group'`) is not supported because the pooled
1020
+ > stacked regression cannot produce cohort-specific effects. Use `CallawaySantAnna` or
1021
+ > `ImputationDiD` for cohort-level estimates.
1022
+
1023
+ **When to use Stacked DiD vs Callaway-Sant'Anna:**
1024
+
1025
+ | Aspect | Stacked DiD | Callaway-Sant'Anna |
1026
+ |--------|-------------|-------------------|
1027
+ | Approach | Stack cohort sub-experiments, run pooled TWFE | 2x2 DiD aggregation |
1028
+ | Symmetric windows | Enforced via kappa_pre / kappa_post | Not required |
1029
+ | Control group | Not-yet-treated (default) or never-treated | Never-treated or not-yet-treated |
1030
+ | Covariates | Passed to pooled regression | Doubly robust / IPW |
1031
+ | Intuition | Familiar event-study regression | Nonparametric aggregation |
1032
+
1033
+ **Convenience function:**
1034
+
1035
+ ```python
1036
+ # One-liner estimation
1037
+ results = stacked_did(
1038
+ data,
1039
+ outcome='outcome',
1040
+ unit='unit',
1041
+ time='period',
1042
+ first_treat='first_treat',
1043
+ kappa_pre=3,
1044
+ kappa_post=3,
1045
+ aggregate='event_study'
1046
+ )
1047
+ ```
1048
+
977
1049
  ### Triple Difference (DDD)
978
1050
 
979
1051
  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 +2275,60 @@ TwoStageDiD(
2203
2275
  | `print_summary(alpha)` | Print summary to stdout |
2204
2276
  | `to_dataframe(level)` | Convert to DataFrame ('observation', 'event_study', 'group') |
2205
2277
 
2278
+ ### StackedDiD
2279
+
2280
+ ```python
2281
+ StackedDiD(
2282
+ kappa_pre=1, # Pre-treatment event-study periods
2283
+ kappa_post=1, # Post-treatment event-study periods
2284
+ weighting='aggregate', # 'aggregate', 'population', or 'sample_share'
2285
+ clean_control='not_yet_treated', # 'not_yet_treated', 'strict', or 'never_treated'
2286
+ cluster='unit', # 'unit' or 'unit_subexp'
2287
+ alpha=0.05, # Significance level
2288
+ anticipation=0, # Anticipation periods
2289
+ rank_deficient_action='warn', # 'warn', 'error', or 'silent'
2290
+ )
2291
+ ```
2292
+
2293
+ **fit() Parameters:**
2294
+
2295
+ | Parameter | Type | Description |
2296
+ |-----------|------|-------------|
2297
+ | `data` | DataFrame | Panel data |
2298
+ | `outcome` | str | Outcome variable column name |
2299
+ | `unit` | str | Unit identifier column |
2300
+ | `time` | str | Time period column |
2301
+ | `first_treat` | str | First treatment period column (0 for never-treated) |
2302
+ | `population` | str, optional | Population column (required if weighting='population') |
2303
+ | `aggregate` | str | Aggregation: None, `"simple"`, or `"event_study"` |
2304
+
2305
+ ### StackedDiDResults
2306
+
2307
+ **Attributes:**
2308
+
2309
+ | Attribute | Description |
2310
+ |-----------|-------------|
2311
+ | `overall_att` | Overall average treatment effect on the treated |
2312
+ | `overall_se` | Standard error |
2313
+ | `overall_t_stat` | T-statistic |
2314
+ | `overall_p_value` | P-value for H0: ATT = 0 |
2315
+ | `overall_conf_int` | Confidence interval |
2316
+ | `event_study_effects` | Dict of relative time -> effect dict (if `aggregate='event_study'`) |
2317
+ | `stacked_data` | The stacked dataset used for estimation |
2318
+ | `n_treated_obs` | Number of treated observations |
2319
+ | `n_untreated_obs` | Number of untreated (clean control) observations |
2320
+ | `n_cohorts` | Number of treatment cohorts |
2321
+ | `kappa_pre` | Pre-treatment window used |
2322
+ | `kappa_post` | Post-treatment window used |
2323
+
2324
+ **Methods:**
2325
+
2326
+ | Method | Description |
2327
+ |--------|-------------|
2328
+ | `summary(alpha)` | Get formatted summary string |
2329
+ | `print_summary(alpha)` | Print summary to stdout |
2330
+ | `to_dataframe(level)` | Convert to DataFrame ('event_study') |
2331
+
2206
2332
  ### TripleDifference
2207
2333
 
2208
2334
  ```python
@@ -2689,6 +2815,8 @@ The `HonestDiD` module implements sensitivity analysis methods for relaxing the
2689
2815
 
2690
2816
  - **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
2817
 
2818
+ - **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)
2819
+
2692
2820
  ### Power Analysis
2693
2821
 
2694
2822
  - **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)
@@ -107,6 +107,11 @@ from diff_diff.two_stage import (
107
107
  TwoStageDiDResults,
108
108
  two_stage_did,
109
109
  )
110
+ from diff_diff.stacked_did import (
111
+ StackedDiD,
112
+ StackedDiDResults,
113
+ stacked_did,
114
+ )
110
115
  from diff_diff.sun_abraham import (
111
116
  SABootstrapResults,
112
117
  SunAbraham,
@@ -148,7 +153,7 @@ from diff_diff.datasets import (
148
153
  load_mpdta,
149
154
  )
150
155
 
151
- __version__ = "2.4.3"
156
+ __version__ = "2.5.0"
152
157
  __all__ = [
153
158
  # Estimators
154
159
  "DifferenceInDifferences",
@@ -161,6 +166,7 @@ __all__ = [
161
166
  "TwoStageDiD",
162
167
  "TripleDifference",
163
168
  "TROP",
169
+ "StackedDiD",
164
170
  # Bacon Decomposition
165
171
  "BaconDecomposition",
166
172
  "BaconDecompositionResults",
@@ -187,6 +193,8 @@ __all__ = [
187
193
  "triple_difference",
188
194
  "TROPResults",
189
195
  "trop",
196
+ "StackedDiDResults",
197
+ "stacked_did",
190
198
  # Visualization
191
199
  "plot_event_study",
192
200
  "plot_group_effects",