diffindiff 2.3.8__tar.gz → 2.4.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 (22) hide show
  1. {diffindiff-2.3.8 → diffindiff-2.4.0}/PKG-INFO +19 -5
  2. {diffindiff-2.3.8 → diffindiff-2.4.0}/README.md +18 -4
  3. {diffindiff-2.3.8 → diffindiff-2.4.0}/diffindiff/config.py +45 -20
  4. {diffindiff-2.3.8 → diffindiff-2.4.0}/diffindiff/didanalysis.py +214 -109
  5. {diffindiff-2.3.8 → diffindiff-2.4.0}/diffindiff/didanalysis_helper.py +295 -2
  6. {diffindiff-2.3.8 → diffindiff-2.4.0}/diffindiff/diddata.py +46 -12
  7. {diffindiff-2.3.8 → diffindiff-2.4.0}/diffindiff/didtools.py +189 -90
  8. {diffindiff-2.3.8 → diffindiff-2.4.0}/diffindiff/tests/tests_diffindiff.py +21 -4
  9. {diffindiff-2.3.8 → diffindiff-2.4.0}/diffindiff.egg-info/PKG-INFO +19 -5
  10. diffindiff-2.4.0/diffindiff.egg-info/requires.txt +9 -0
  11. {diffindiff-2.3.8 → diffindiff-2.4.0}/setup.py +7 -9
  12. diffindiff-2.3.8/diffindiff.egg-info/requires.txt +0 -11
  13. {diffindiff-2.3.8 → diffindiff-2.4.0}/MANIFEST.in +0 -0
  14. {diffindiff-2.3.8 → diffindiff-2.4.0}/diffindiff/__init__.py +0 -0
  15. {diffindiff-2.3.8 → diffindiff-2.4.0}/diffindiff/tests/__init__.py +0 -0
  16. {diffindiff-2.3.8 → diffindiff-2.4.0}/diffindiff/tests/data/Corona_Hesse.xlsx +0 -0
  17. {diffindiff-2.3.8 → diffindiff-2.4.0}/diffindiff/tests/data/counties_DE.csv +0 -0
  18. {diffindiff-2.3.8 → diffindiff-2.4.0}/diffindiff/tests/data/curfew_DE.csv +0 -0
  19. {diffindiff-2.3.8 → diffindiff-2.4.0}/diffindiff.egg-info/SOURCES.txt +0 -0
  20. {diffindiff-2.3.8 → diffindiff-2.4.0}/diffindiff.egg-info/dependency_links.txt +0 -0
  21. {diffindiff-2.3.8 → diffindiff-2.4.0}/diffindiff.egg-info/top_level.txt +0 -0
  22. {diffindiff-2.3.8 → diffindiff-2.4.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: diffindiff
3
- Version: 2.3.8
3
+ Version: 2.4.0
4
4
  Summary: diffindiff: Python library for convenient Difference-in-Differences analyses
5
5
  Author: Thomas Wieland
6
6
  Author-email: geowieland@googlemail.com
@@ -8,7 +8,7 @@ Description-Content-Type: text/markdown
8
8
 
9
9
  # diffindiff: Python library for convenient Difference-in-Differences analyses
10
10
 
11
- This Python library is designed for performing Difference-in-Differences (DiD) analyses in a convenient way. The package is intended to be used in econometric analyses of natural experiments by researchers in economics, marketing, economic geography, and health sciences. It is designed to cover the entire workflow of a DiD analysis, while not requiring extensive programming skills. The package allows users to construct datasets, define treatment and control groups, and set treatment periods. DiD model analyses may be conducted with both datasets created by built-in functions and ready-to-use external datasets. Both simultaneous and staggered adoption are supported. The library allows for various extensions, such as two-way fixed effects models, group- or individual-specific effects, post-treatment periods, and triple-difference estimations. Additionally, it includes functions for visualizing results, such as plotting DiD coefficients with confidence intervals and illustrating the temporal evolution of staggered treatments. Furthermore, several functions for rigorous treatment setting and data diagnostics are incorporated.
11
+ This Python library is designed for performing Difference-in-Differences (DiD) analyses in a convenient way. The package is intended to be used in econometric analyses of natural experiments by researchers in economics, marketing, economic geography, and health sciences. It is designed to cover the entire workflow of a DiD analysis, while not requiring extensive programming skills. The package allows users to construct datasets, define treatment and control groups, and set treatment periods. DiD model analyses may be conducted with both datasets created by built-in functions and ready-to-use external datasets. Both simultaneous and staggered adoption are supported. The library allows for various extensions, such as two-way fixed effects models, group- or individual-specific effects, post-treatment periods, and triple-difference estimations. Additionally, it includes functions for visualizing results, such as plotting DiD coefficients with confidence intervals and illustrating the temporal evolution of staggered treatments. Furthermore, several functions for rigorous treatment configuration and data diagnostics are incorporated.
12
12
 
13
13
 
14
14
  ## Author
@@ -27,7 +27,7 @@ Thomas Wieland [ORCID](https://orcid.org/0000-0001-5168-9846) [EMail](mailto:geo
27
27
 
28
28
  If you use this software, please cite:
29
29
 
30
- Wieland, T. (2026). diffindiff: A Python library for convenient difference-in-differences analyses (Version 2.3.8) [Computer software]. Zenodo. https://doi.org/10.5281/zenodo.18656820
30
+ Wieland, T. (2026). diffindiff: A Python library for convenient difference-in-differences analyses (Version 2.4.0) [Computer software]. Zenodo. https://doi.org/10.5281/zenodo.18656820
31
31
 
32
32
 
33
33
  ## Installation
@@ -63,6 +63,7 @@ pip install git+https://github.com/geowieland/diffindiff_official.git
63
63
  - Including covariates
64
64
  - Including after-treatment period
65
65
  - Perform Triple Difference (DDD) analysis
66
+ - Perform DiD analysis with demeaned data
66
67
  - **Diagnosis tools and extensions of analyses**:
67
68
  - Add own counterfactuals or create counterfactuals based on machine learning or OLS regression models
68
69
  - Bonferroni correction for treatment effects
@@ -166,6 +167,7 @@ See the /tests directory for usage examples of most of the included functions.
166
167
  - von Bismarck-Osten C, Borusyak K, Schönberg U (2022) The role of schools in transmission of the SARS-CoV-2 virus: quasi-experimental evidence from Germany. *Economic Policy* 37(109): 87–130. [10.1093/epolic/eiac001](https://doi.org/10.1093/epolic/eiac001)
167
168
  - Wieland T (2025) Assessing the effectiveness of non-pharmaceutical interventions in the SARS-CoV-2 pandemic: results of a natural experiment regarding Baden-Württemberg (Germany) and Switzerland in the second infection wave. *Journal of Public Health: From Theory to Practice* 33(11): 2497-2511. [10.1007/s10389-024-02218-x](https://doi.org/10.1007/s10389-024-02218-x)
168
169
  - Wooldridge JM (2012) *Introductory Econometrics. A Modern Approach*.
170
+ - Wooldridge JM (2025) Two-way fixed effects, the two-way mundlak regression, and difference-in-differences estimators. *Empirical Economics* 69(5): 2545-2587. [10.1007/s00181-025-02807-z](https://doi.org/10.1007/s00181-025-02807-z)
169
171
 
170
172
 
171
173
  ## AI Usage Statement
@@ -173,7 +175,19 @@ See the /tests directory for usage examples of most of the included functions.
173
175
  This software was developed without the use of AI-generated code. The Continue Agent in Microsoft Visual Studio Code using the GPT-5 mini model (by OpenAI) was used solely to assist in drafting and refining docstrings for documentation. The corresponding guidelines and constraints defined by the author are documented in `AGENTS-docstrings.md` in the [public GitHub repository](https://github.com/geowieland/diffindiff_official).
174
176
 
175
177
 
176
- ## What's new (v2.3.8)
178
+ ## What's new (v2.4.0)
177
179
 
180
+ - Extensions:
181
+ - Option of demeaning numeric variables instead of Two-way fixed effects in did_analysis.didanalysis() and diddata.DiffData.analysis() to save processing time and memory capacity
182
+ - didtools.model_wrapper() extended by multi-layer perceptron algorithm
178
183
  - Bugfixes:
179
- - DiffModel.plot() always shows the correct values if retransform_log_outcome is used
184
+ - Fixed pandas error (relevant only in newer pandas versions) in didtools.is_notreatment()
185
+ - Exception handling in didtools.model_wrapper() improved: errors during model training are now being caught
186
+ - didtools.is_numeric() performs a safer check of the specified cols whether they are numeric
187
+ - Extended variables checks in didtools.fit_metrics()
188
+ - Fixed name bug in diddata.create_counterfactual()
189
+ - In didanalysis.DiffModel.summary(), numbers are now always represented in decimal notation
190
+ - Corrected check in didanalysis.DiffModel.treatment_statistics() whether treatment is included
191
+ - Cleanup and adjustment of requirements with respect to compatibility
192
+ - Other:
193
+ - More specific outputs in NOTEs texts
@@ -1,6 +1,6 @@
1
1
  # diffindiff: Python library for convenient Difference-in-Differences analyses
2
2
 
3
- This Python library is designed for performing Difference-in-Differences (DiD) analyses in a convenient way. The package is intended to be used in econometric analyses of natural experiments by researchers in economics, marketing, economic geography, and health sciences. It is designed to cover the entire workflow of a DiD analysis, while not requiring extensive programming skills. The package allows users to construct datasets, define treatment and control groups, and set treatment periods. DiD model analyses may be conducted with both datasets created by built-in functions and ready-to-use external datasets. Both simultaneous and staggered adoption are supported. The library allows for various extensions, such as two-way fixed effects models, group- or individual-specific effects, post-treatment periods, and triple-difference estimations. Additionally, it includes functions for visualizing results, such as plotting DiD coefficients with confidence intervals and illustrating the temporal evolution of staggered treatments. Furthermore, several functions for rigorous treatment setting and data diagnostics are incorporated.
3
+ This Python library is designed for performing Difference-in-Differences (DiD) analyses in a convenient way. The package is intended to be used in econometric analyses of natural experiments by researchers in economics, marketing, economic geography, and health sciences. It is designed to cover the entire workflow of a DiD analysis, while not requiring extensive programming skills. The package allows users to construct datasets, define treatment and control groups, and set treatment periods. DiD model analyses may be conducted with both datasets created by built-in functions and ready-to-use external datasets. Both simultaneous and staggered adoption are supported. The library allows for various extensions, such as two-way fixed effects models, group- or individual-specific effects, post-treatment periods, and triple-difference estimations. Additionally, it includes functions for visualizing results, such as plotting DiD coefficients with confidence intervals and illustrating the temporal evolution of staggered treatments. Furthermore, several functions for rigorous treatment configuration and data diagnostics are incorporated.
4
4
 
5
5
 
6
6
  ## Author
@@ -19,7 +19,7 @@ Thomas Wieland [ORCID](https://orcid.org/0000-0001-5168-9846) [EMail](mailto:geo
19
19
 
20
20
  If you use this software, please cite:
21
21
 
22
- Wieland, T. (2026). diffindiff: A Python library for convenient difference-in-differences analyses (Version 2.3.8) [Computer software]. Zenodo. https://doi.org/10.5281/zenodo.18656820
22
+ Wieland, T. (2026). diffindiff: A Python library for convenient difference-in-differences analyses (Version 2.4.0) [Computer software]. Zenodo. https://doi.org/10.5281/zenodo.18656820
23
23
 
24
24
 
25
25
  ## Installation
@@ -55,6 +55,7 @@ pip install git+https://github.com/geowieland/diffindiff_official.git
55
55
  - Including covariates
56
56
  - Including after-treatment period
57
57
  - Perform Triple Difference (DDD) analysis
58
+ - Perform DiD analysis with demeaned data
58
59
  - **Diagnosis tools and extensions of analyses**:
59
60
  - Add own counterfactuals or create counterfactuals based on machine learning or OLS regression models
60
61
  - Bonferroni correction for treatment effects
@@ -158,6 +159,7 @@ See the /tests directory for usage examples of most of the included functions.
158
159
  - von Bismarck-Osten C, Borusyak K, Schönberg U (2022) The role of schools in transmission of the SARS-CoV-2 virus: quasi-experimental evidence from Germany. *Economic Policy* 37(109): 87–130. [10.1093/epolic/eiac001](https://doi.org/10.1093/epolic/eiac001)
159
160
  - Wieland T (2025) Assessing the effectiveness of non-pharmaceutical interventions in the SARS-CoV-2 pandemic: results of a natural experiment regarding Baden-Württemberg (Germany) and Switzerland in the second infection wave. *Journal of Public Health: From Theory to Practice* 33(11): 2497-2511. [10.1007/s10389-024-02218-x](https://doi.org/10.1007/s10389-024-02218-x)
160
161
  - Wooldridge JM (2012) *Introductory Econometrics. A Modern Approach*.
162
+ - Wooldridge JM (2025) Two-way fixed effects, the two-way mundlak regression, and difference-in-differences estimators. *Empirical Economics* 69(5): 2545-2587. [10.1007/s00181-025-02807-z](https://doi.org/10.1007/s00181-025-02807-z)
161
163
 
162
164
 
163
165
  ## AI Usage Statement
@@ -165,7 +167,19 @@ See the /tests directory for usage examples of most of the included functions.
165
167
  This software was developed without the use of AI-generated code. The Continue Agent in Microsoft Visual Studio Code using the GPT-5 mini model (by OpenAI) was used solely to assist in drafting and refining docstrings for documentation. The corresponding guidelines and constraints defined by the author are documented in `AGENTS-docstrings.md` in the [public GitHub repository](https://github.com/geowieland/diffindiff_official).
166
168
 
167
169
 
168
- ## What's new (v2.3.8)
170
+ ## What's new (v2.4.0)
169
171
 
172
+ - Extensions:
173
+ - Option of demeaning numeric variables instead of Two-way fixed effects in did_analysis.didanalysis() and diddata.DiffData.analysis() to save processing time and memory capacity
174
+ - didtools.model_wrapper() extended by multi-layer perceptron algorithm
170
175
  - Bugfixes:
171
- - DiffModel.plot() always shows the correct values if retransform_log_outcome is used
176
+ - Fixed pandas error (relevant only in newer pandas versions) in didtools.is_notreatment()
177
+ - Exception handling in didtools.model_wrapper() improved: errors during model training are now being caught
178
+ - didtools.is_numeric() performs a safer check of the specified cols whether they are numeric
179
+ - Extended variables checks in didtools.fit_metrics()
180
+ - Fixed name bug in diddata.create_counterfactual()
181
+ - In didanalysis.DiffModel.summary(), numbers are now always represented in decimal notation
182
+ - Corrected check in didanalysis.DiffModel.treatment_statistics() whether treatment is included
183
+ - Cleanup and adjustment of requirements with respect to compatibility
184
+ - Other:
185
+ - More specific outputs in NOTEs texts
@@ -4,15 +4,15 @@
4
4
  # Author: Thomas Wieland
5
5
  # ORCID: 0000-0001-5168-9846
6
6
  # mail: geowieland@googlemail.com
7
- # Version: 1.0.16
8
- # Last update: 2026-04-21 20:19
7
+ # Version: 1.0.18
8
+ # Last update: 2026-05-01 09:53
9
9
  # Copyright (c) 2025-2026 Thomas Wieland
10
10
  #-----------------------------------------------------------------------
11
11
 
12
12
  # Basic config:
13
13
 
14
14
  PACKAGE_NAME = "diffindiff"
15
- PACKAGE_VERSION = "2.3.8"
15
+ PACKAGE_VERSION = "2.4.0"
16
16
 
17
17
  VERBOSE = False
18
18
 
@@ -25,8 +25,13 @@ ACCEPT_CONTINUOUS_TREATMENTS = True
25
25
 
26
26
  # Description texts:
27
27
 
28
- DID_DESCRIPTION = "Difference-in-Differences Analysis"
29
- DDD_DESCRIPTION = "Triple-Difference Analysis"
28
+ DID = "Difference-in-Differences"
29
+ DDD = "Triple-Difference"
30
+
31
+ DID_DESCRIPTION = f"{DID} Analysis"
32
+ DDD_DESCRIPTION = f"{DDD} Analysis"
33
+ PLACEBO_DESCRIPTION = "Placebo"
34
+ PREDICTIVE_MODEL_DESCRIPTION = "Predictive Model"
30
35
 
31
36
  TREATMENT_DESCRIPTION = "Treatment"
32
37
  CONTROL_DESCRIPTION = "Control"
@@ -90,6 +95,7 @@ DUMMY_PREFIX = "DUMMY"
90
95
  LOG_PREFIX = "log"
91
96
  OBSERVED_SUFFIX = "observed"
92
97
  EXPECTED_SUFFIX = "expected"
98
+ DEMEAN_SUFFIX = "demean"
93
99
  PREDICTED_SUFFIX = "pred"
94
100
  CI_LOWER_SUFFIX = "CI_lower"
95
101
  CI_UPPER_SUFFIX = "CI_upper"
@@ -98,54 +104,63 @@ PI_UPPER_SUFFIX = "PI_upper"
98
104
  SPILLOVER_PREFIX = "Spillover"
99
105
  SPILLOVER_UNIT_PREFIX = f"{SPILLOVER_PREFIX}{DELIMITER}{UNIT_COL}"
100
106
  DIFFERENCE_SUFFIX = "diff"
107
+ RESIDUALS_SUFFIX = "resid"
108
+ PLACEBO_PREFIX = "Placebo"
101
109
 
102
110
  # Modeling config:
103
111
 
104
112
  # Coefficients/effects types:
105
113
 
106
- TREATMENT_EFFECTS_DESCRIPTION = "Difference-in-Differences coefficients"
114
+ TREATMENT_EFFECTS_DESCRIPTION = f"{DID} coefficients"
107
115
 
108
116
  EFFECTS_TYPES = {
109
117
  "ATE": {
110
118
  "description": "Average treatment effect",
111
119
  "model_results_key": "average_treatment_effects",
112
120
  "summary_treatment_effects": True,
113
- "summary_description": "{description} {coef}"
121
+ "summary_description": "{description} {coef}",
122
+ "derive_fixed_effects": True
114
123
  },
115
124
  "AATE": {
116
125
  "description": "Average after-treatment effect",
117
126
  "model_results_key": "average_after_treatment_effects",
118
127
  "summary_treatment_effects": True,
119
- "summary_description": "{description} {coef}"
128
+ "summary_description": "{description} {coef}",
129
+ "derive_fixed_effects": True
120
130
  },
121
131
  "beta_0": {
122
132
  "description": "Control group baseline",
123
133
  "model_results_key": "control_group_baseline",
124
134
  "summary_treatment_effects": True,
125
- "summary_description": "{description}"
135
+ "summary_description": "{description}",
136
+ "derive_fixed_effects": True
126
137
  },
127
138
  "beta_1": {
128
139
  "description": f"{TREATMENT_GROUP_DESCRIPTION} deviation",
129
140
  "model_results_key": "treatment_group_deviation",
130
141
  "summary_treatment_effects": True,
131
- "summary_description": "{description}"
142
+ "summary_description": "{description}",
143
+ "derive_fixed_effects": True
132
144
  },
133
145
  "delta_0": {
134
146
  "description": "Non-treatment time effect",
135
147
  "model_results_key": "non_treatment_time_effect",
136
148
  "summary_treatment_effects": True,
137
- "summary_description": "{description} {coef}"
149
+ "summary_description": "{description} {coef}",
150
+ "derive_fixed_effects": True
138
151
  },
139
152
  "ATT": {
140
153
  "description": "After-treatment time effect",
141
154
  "model_results_key": "after_treatment_time_effects",
142
155
  "summary_treatment_effects": True,
143
- "summary_description": "{description} {coef}"
156
+ "summary_description": "{description} {coef}",
157
+ "derive_fixed_effects": True
144
158
  },
145
159
  "FE": {
146
160
  "description": "Fixed effects",
147
161
  "model_results_key": "fixed_effects",
148
162
  "summary_treatment_effects": False,
163
+ "derive_fixed_effects": False,
149
164
  "types": {
150
165
  0: {
151
166
  "FE": "unit",
@@ -174,50 +189,57 @@ EFFECTS_TYPES = {
174
189
  "description": "Individual time trends",
175
190
  "model_results_key": "individual_time_trends",
176
191
  "model_config_key": "ITT",
177
- "summary_treatment_effects": False
192
+ "summary_treatment_effects": False,
193
+ "derive_fixed_effects": False
178
194
  },
179
195
  "ITE": {
180
196
  "description": "Individual treatment effects",
181
197
  "model_results_key": "individual_treatment_effects",
182
198
  "model_config_key": "ITE",
183
199
  "summary_treatment_effects": True,
184
- "summary_description": "{coef}"
200
+ "summary_description": "{coef}",
201
+ "derive_fixed_effects": False
185
202
  },
186
203
  "GTT": {
187
204
  "description": "Group time trends",
188
205
  "model_results_key": "group_time_trends",
189
206
  "model_config_key": "GTT",
190
- "summary_treatment_effects": False
207
+ "summary_treatment_effects": False,
208
+ "derive_fixed_effects": False
191
209
  },
192
210
  "GTE": {
193
211
  "description": "Group treatment effects",
194
212
  "model_results_key": "group_treatment_effects",
195
213
  "model_config_key": "GTE",
196
214
  "summary_treatment_effects": True,
197
- "summary_description": "{coef}"
215
+ "summary_description": "{coef}",
216
+ "derive_fixed_effects": False
198
217
  },
199
218
  "spillover": {
200
219
  "description": "Treatment spillover effect",
201
220
  "model_results_key": "treatment_spillover_effects",
202
221
  "model_config_key": "spillover_effects",
203
222
  "summary_treatment_effects": True,
204
- "summary_description": "{description} {coef}"
223
+ "summary_description": "{description} {coef}",
224
+ "derive_fixed_effects": True
205
225
  },
206
226
  "covariates": {
207
227
  "description": "Covariates",
208
228
  "model_results_key": "covariates_effects",
209
229
  "model_config_key": "covariates",
210
230
  "summary_treatment_effects": False,
211
- "summary_description": "{coef}"
231
+ "summary_description": "{coef}",
232
+ "derive_fixed_effects": True
212
233
  },
213
234
  }
214
235
  EFFECTS_TYPES_MODEL_RESULTS = [value["model_results_key"] for value in EFFECTS_TYPES.values() if "model_results_key" in value]
215
236
  EFFECTS_TYPES_MODEL_RESULTS_SUMMARY = [value["model_results_key"] for value in EFFECTS_TYPES.values() if "model_results_key" in value and value["summary_treatment_effects"]]
237
+ EFFECTS_TYPES_DERIVE_FE = [value["model_results_key"] for value in EFFECTS_TYPES.values() if "model_results_key" in value and value["derive_fixed_effects"]]
216
238
 
217
239
 
218
240
  EFFECTS_TYPES_DDD = {
219
241
  "TDATE": {
220
- "description": "Triple-Difference Average treatment effect",
242
+ "description": f"{DDD} Average treatment effect",
221
243
  "model_results_key": "TDATE"
222
244
  },
223
245
  "beta_2": {
@@ -374,10 +396,13 @@ MODEL_WRAPPER_AVAILABLE = {
374
396
  "knn": "K-nearest neighbor",
375
397
  "xgb": "Extreme Gradient Boosting",
376
398
  "lgbm": "LightGBM",
377
- "svr": "Support-vector regression",
399
+ "svr": "Support-Vector Regression",
400
+ "mlp": "Multi-layer Perceptron"
378
401
  }
379
402
  MODEL_WRAPPER_AVAILABLE_LIST = list(MODEL_WRAPPER_AVAILABLE.keys())
380
403
 
404
+ MODEL_WRAPPER_DEFAULT = MODEL_WRAPPER_AVAILABLE_LIST[0]
405
+
381
406
 
382
407
  # Treatment diagnostics:
383
408