diff-diff 0.5.0__py3-none-any.whl → 0.6.0__py3-none-any.whl
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/__init__.py +53 -30
- diff_diff/diagnostics.py +3 -0
- diff_diff/estimators.py +6 -4
- diff_diff/honest_did.py +1491 -0
- diff_diff/prep.py +1 -1
- diff_diff/staggered.py +341 -52
- diff_diff/utils.py +21 -21
- diff_diff/visualization.py +350 -1
- {diff_diff-0.5.0.dist-info → diff_diff-0.6.0.dist-info}/METADATA +194 -6
- diff_diff-0.6.0.dist-info/RECORD +13 -0
- diff_diff-0.5.0.dist-info/RECORD +0 -12
- {diff_diff-0.5.0.dist-info → diff_diff-0.6.0.dist-info}/WHEEL +0 -0
- {diff_diff-0.5.0.dist-info → diff_diff-0.6.0.dist-info}/top_level.txt +0 -0
diff_diff/__init__.py
CHANGED
|
@@ -5,16 +5,42 @@ This library provides sklearn-like estimators for causal inference
|
|
|
5
5
|
using the difference-in-differences methodology.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
+
from diff_diff.diagnostics import (
|
|
9
|
+
PlaceboTestResults,
|
|
10
|
+
leave_one_out_test,
|
|
11
|
+
permutation_test,
|
|
12
|
+
placebo_group_test,
|
|
13
|
+
placebo_timing_test,
|
|
14
|
+
run_all_placebo_tests,
|
|
15
|
+
run_placebo_test,
|
|
16
|
+
)
|
|
8
17
|
from diff_diff.estimators import (
|
|
9
18
|
DifferenceInDifferences,
|
|
10
|
-
TwoWayFixedEffects,
|
|
11
19
|
MultiPeriodDiD,
|
|
12
20
|
SyntheticDiD,
|
|
21
|
+
TwoWayFixedEffects,
|
|
13
22
|
)
|
|
14
|
-
from diff_diff.
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
23
|
+
from diff_diff.honest_did import (
|
|
24
|
+
DeltaRM,
|
|
25
|
+
DeltaSD,
|
|
26
|
+
DeltaSDRM,
|
|
27
|
+
HonestDiD,
|
|
28
|
+
HonestDiDResults,
|
|
29
|
+
SensitivityResults,
|
|
30
|
+
compute_honest_did,
|
|
31
|
+
sensitivity_plot,
|
|
32
|
+
)
|
|
33
|
+
from diff_diff.prep import (
|
|
34
|
+
aggregate_to_cohorts,
|
|
35
|
+
balance_panel,
|
|
36
|
+
create_event_time,
|
|
37
|
+
generate_did_data,
|
|
38
|
+
make_post_indicator,
|
|
39
|
+
make_treatment_indicator,
|
|
40
|
+
rank_control_units,
|
|
41
|
+
summarize_did_data,
|
|
42
|
+
validate_did_data,
|
|
43
|
+
wide_to_long,
|
|
18
44
|
)
|
|
19
45
|
from diff_diff.results import (
|
|
20
46
|
DiDResults,
|
|
@@ -22,40 +48,26 @@ from diff_diff.results import (
|
|
|
22
48
|
PeriodEffect,
|
|
23
49
|
SyntheticDiDResults,
|
|
24
50
|
)
|
|
25
|
-
from diff_diff.
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
from diff_diff.prep import (
|
|
30
|
-
make_treatment_indicator,
|
|
31
|
-
make_post_indicator,
|
|
32
|
-
wide_to_long,
|
|
33
|
-
balance_panel,
|
|
34
|
-
validate_did_data,
|
|
35
|
-
summarize_did_data,
|
|
36
|
-
generate_did_data,
|
|
37
|
-
create_event_time,
|
|
38
|
-
aggregate_to_cohorts,
|
|
39
|
-
rank_control_units,
|
|
51
|
+
from diff_diff.staggered import (
|
|
52
|
+
CallawaySantAnna,
|
|
53
|
+
CallawaySantAnnaResults,
|
|
54
|
+
GroupTimeEffect,
|
|
40
55
|
)
|
|
41
56
|
from diff_diff.utils import (
|
|
57
|
+
WildBootstrapResults,
|
|
42
58
|
check_parallel_trends,
|
|
43
59
|
check_parallel_trends_robust,
|
|
44
60
|
equivalence_test_trends,
|
|
45
|
-
WildBootstrapResults,
|
|
46
61
|
wild_bootstrap_se,
|
|
47
62
|
)
|
|
48
|
-
from diff_diff.
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
permutation_test,
|
|
54
|
-
leave_one_out_test,
|
|
55
|
-
run_all_placebo_tests,
|
|
63
|
+
from diff_diff.visualization import (
|
|
64
|
+
plot_event_study,
|
|
65
|
+
plot_group_effects,
|
|
66
|
+
plot_honest_event_study,
|
|
67
|
+
plot_sensitivity,
|
|
56
68
|
)
|
|
57
69
|
|
|
58
|
-
__version__ = "0.
|
|
70
|
+
__version__ = "0.6.0"
|
|
59
71
|
__all__ = [
|
|
60
72
|
# Estimators
|
|
61
73
|
"DifferenceInDifferences",
|
|
@@ -73,6 +85,8 @@ __all__ = [
|
|
|
73
85
|
# Visualization
|
|
74
86
|
"plot_event_study",
|
|
75
87
|
"plot_group_effects",
|
|
88
|
+
"plot_sensitivity",
|
|
89
|
+
"plot_honest_event_study",
|
|
76
90
|
# Parallel trends testing
|
|
77
91
|
"check_parallel_trends",
|
|
78
92
|
"check_parallel_trends_robust",
|
|
@@ -99,4 +113,13 @@ __all__ = [
|
|
|
99
113
|
"create_event_time",
|
|
100
114
|
"aggregate_to_cohorts",
|
|
101
115
|
"rank_control_units",
|
|
116
|
+
# Honest DiD sensitivity analysis
|
|
117
|
+
"HonestDiD",
|
|
118
|
+
"HonestDiDResults",
|
|
119
|
+
"SensitivityResults",
|
|
120
|
+
"DeltaSD",
|
|
121
|
+
"DeltaRM",
|
|
122
|
+
"DeltaSDRM",
|
|
123
|
+
"compute_honest_did",
|
|
124
|
+
"sensitivity_plot",
|
|
102
125
|
]
|
diff_diff/diagnostics.py
CHANGED
diff_diff/estimators.py
CHANGED
|
@@ -603,6 +603,7 @@ class DifferenceInDifferences:
|
|
|
603
603
|
"""
|
|
604
604
|
if not self.is_fitted_:
|
|
605
605
|
raise RuntimeError("Model must be fitted before calling summary()")
|
|
606
|
+
assert self.results_ is not None
|
|
606
607
|
return self.results_.summary()
|
|
607
608
|
|
|
608
609
|
def print_summary(self) -> None:
|
|
@@ -641,7 +642,7 @@ class TwoWayFixedEffects(DifferenceInDifferences):
|
|
|
641
642
|
staggered designs.
|
|
642
643
|
"""
|
|
643
644
|
|
|
644
|
-
def fit(
|
|
645
|
+
def fit( # type: ignore[override]
|
|
645
646
|
self,
|
|
646
647
|
data: pd.DataFrame,
|
|
647
648
|
outcome: str,
|
|
@@ -763,7 +764,7 @@ class TwoWayFixedEffects(DifferenceInDifferences):
|
|
|
763
764
|
n_treated=n_treated,
|
|
764
765
|
n_control=n_control,
|
|
765
766
|
alpha=self.alpha,
|
|
766
|
-
coefficients={"ATT": att},
|
|
767
|
+
coefficients={"ATT": float(att)},
|
|
767
768
|
vcov=vcov,
|
|
768
769
|
residuals=residuals,
|
|
769
770
|
fitted_values=fitted,
|
|
@@ -892,7 +893,7 @@ class MultiPeriodDiD(DifferenceInDifferences):
|
|
|
892
893
|
The average ATT is computed as the mean of the δ_t coefficients.
|
|
893
894
|
"""
|
|
894
895
|
|
|
895
|
-
def fit(
|
|
896
|
+
def fit( # type: ignore[override]
|
|
896
897
|
self,
|
|
897
898
|
data: pd.DataFrame,
|
|
898
899
|
outcome: str,
|
|
@@ -1166,6 +1167,7 @@ class MultiPeriodDiD(DifferenceInDifferences):
|
|
|
1166
1167
|
"""
|
|
1167
1168
|
if not self.is_fitted_:
|
|
1168
1169
|
raise RuntimeError("Model must be fitted before calling summary()")
|
|
1170
|
+
assert self.results_ is not None
|
|
1169
1171
|
return self.results_.summary()
|
|
1170
1172
|
|
|
1171
1173
|
|
|
@@ -1284,7 +1286,7 @@ class SyntheticDiD(DifferenceInDifferences):
|
|
|
1284
1286
|
self._unit_weights = None
|
|
1285
1287
|
self._time_weights = None
|
|
1286
1288
|
|
|
1287
|
-
def fit(
|
|
1289
|
+
def fit( # type: ignore[override]
|
|
1288
1290
|
self,
|
|
1289
1291
|
data: pd.DataFrame,
|
|
1290
1292
|
outcome: str,
|