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.
- {diff_diff-2.4.3 → diff_diff-2.5.0}/PKG-INFO +130 -2
- {diff_diff-2.4.3 → diff_diff-2.5.0}/README.md +129 -1
- {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/__init__.py +9 -1
- diff_diff-2.5.0/diff_diff/stacked_did.py +871 -0
- diff_diff-2.5.0/diff_diff/stacked_did_results.py +318 -0
- {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/visualization.py +2 -0
- {diff_diff-2.4.3 → diff_diff-2.5.0}/pyproject.toml +1 -1
- {diff_diff-2.4.3 → diff_diff-2.5.0}/rust/Cargo.lock +1 -1
- {diff_diff-2.4.3 → diff_diff-2.5.0}/rust/Cargo.toml +1 -1
- {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/_backend.py +0 -0
- {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/bacon.py +0 -0
- {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/datasets.py +0 -0
- {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/diagnostics.py +0 -0
- {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/estimators.py +0 -0
- {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/honest_did.py +0 -0
- {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/imputation.py +0 -0
- {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/imputation_bootstrap.py +0 -0
- {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/imputation_results.py +0 -0
- {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/linalg.py +0 -0
- {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/power.py +0 -0
- {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/prep.py +0 -0
- {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/prep_dgp.py +0 -0
- {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/pretrends.py +0 -0
- {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/results.py +0 -0
- {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/staggered.py +0 -0
- {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/staggered_aggregation.py +0 -0
- {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/staggered_bootstrap.py +0 -0
- {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/staggered_results.py +0 -0
- {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/sun_abraham.py +0 -0
- {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/synthetic_did.py +0 -0
- {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/triple_diff.py +0 -0
- {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/trop.py +0 -0
- {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/trop_results.py +0 -0
- {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/twfe.py +0 -0
- {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/two_stage.py +0 -0
- {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/two_stage_bootstrap.py +0 -0
- {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/two_stage_results.py +0 -0
- {diff_diff-2.4.3 → diff_diff-2.5.0}/diff_diff/utils.py +0 -0
- {diff_diff-2.4.3 → diff_diff-2.5.0}/rust/build.rs +0 -0
- {diff_diff-2.4.3 → diff_diff-2.5.0}/rust/src/bootstrap.rs +0 -0
- {diff_diff-2.4.3 → diff_diff-2.5.0}/rust/src/lib.rs +0 -0
- {diff_diff-2.4.3 → diff_diff-2.5.0}/rust/src/linalg.rs +0 -0
- {diff_diff-2.4.3 → diff_diff-2.5.0}/rust/src/trop.rs +0 -0
- {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.
|
|
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,
|
|
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,
|
|
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.
|
|
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",
|