diffindiff 2.2.0__tar.gz → 2.2.1__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 (21) hide show
  1. {diffindiff-2.2.0 → diffindiff-2.2.1}/PKG-INFO +3 -14
  2. {diffindiff-2.2.0 → diffindiff-2.2.1}/README.md +2 -13
  3. {diffindiff-2.2.0 → diffindiff-2.2.1}/diffindiff/config.py +4 -4
  4. {diffindiff-2.2.0 → diffindiff-2.2.1}/diffindiff/diddata.py +50 -13
  5. {diffindiff-2.2.0 → diffindiff-2.2.1}/diffindiff/didtools.py +33 -3
  6. {diffindiff-2.2.0 → diffindiff-2.2.1}/diffindiff.egg-info/PKG-INFO +3 -14
  7. {diffindiff-2.2.0 → diffindiff-2.2.1}/setup.py +1 -1
  8. {diffindiff-2.2.0 → diffindiff-2.2.1}/MANIFEST.in +0 -0
  9. {diffindiff-2.2.0 → diffindiff-2.2.1}/diffindiff/__init__.py +0 -0
  10. {diffindiff-2.2.0 → diffindiff-2.2.1}/diffindiff/didanalysis.py +0 -0
  11. {diffindiff-2.2.0 → diffindiff-2.2.1}/diffindiff/didanalysis_helper.py +0 -0
  12. {diffindiff-2.2.0 → diffindiff-2.2.1}/diffindiff/tests/__init__.py +0 -0
  13. {diffindiff-2.2.0 → diffindiff-2.2.1}/diffindiff/tests/data/Corona_Hesse.xlsx +0 -0
  14. {diffindiff-2.2.0 → diffindiff-2.2.1}/diffindiff/tests/data/counties_DE.csv +0 -0
  15. {diffindiff-2.2.0 → diffindiff-2.2.1}/diffindiff/tests/data/curfew_DE.csv +0 -0
  16. {diffindiff-2.2.0 → diffindiff-2.2.1}/diffindiff/tests/tests_diffindiff.py +0 -0
  17. {diffindiff-2.2.0 → diffindiff-2.2.1}/diffindiff.egg-info/SOURCES.txt +0 -0
  18. {diffindiff-2.2.0 → diffindiff-2.2.1}/diffindiff.egg-info/dependency_links.txt +0 -0
  19. {diffindiff-2.2.0 → diffindiff-2.2.1}/diffindiff.egg-info/requires.txt +0 -0
  20. {diffindiff-2.2.0 → diffindiff-2.2.1}/diffindiff.egg-info/top_level.txt +0 -0
  21. {diffindiff-2.2.0 → diffindiff-2.2.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: diffindiff
3
- Version: 2.2.0
3
+ Version: 2.2.1
4
4
  Summary: diffindiff: Python library for convenient Difference-in-Differences Analyses
5
5
  Author: Thomas Wieland
6
6
  Author-email: geowieland@googlemail.com
@@ -16,20 +16,9 @@ This Python library is designed for performing Difference-in-Differences (DiD) a
16
16
  Thomas Wieland [ORCID](https://orcid.org/0000-0001-5168-9846) [EMail](mailto:geowieland@googlemail.com)
17
17
 
18
18
 
19
- ## Updates v2.2.0
20
- - More efficient and modularized code in general
21
- - Extensions:
22
- - Triple-difference analysis in own function
23
- - Ordinary Least Squares (OLS) and Maximum Likelihood (ML) estimation
24
- - Extended model fit metrices
25
- - Optional clustered standard errors in didanalysis.did_analysis()
26
- - New data diagnostics function didtools.is_prepost()
27
- - New data diagnostics function didtools.is_multiple_treatment_period()
19
+ ## Updates v2.2.1
28
20
  - Bugfixes:
29
- - Correct import from patsy
30
- - Automatic switch to pre-post data processing if detected
31
- - Completion of package dependencies
32
- - No (redundant) calculation of ITE/GTE for control group anymore
21
+ - Always converting unit and time col to str and calculating unit-time-index col
33
22
 
34
23
 
35
24
  ## Features
@@ -8,20 +8,9 @@ This Python library is designed for performing Difference-in-Differences (DiD) a
8
8
  Thomas Wieland [ORCID](https://orcid.org/0000-0001-5168-9846) [EMail](mailto:geowieland@googlemail.com)
9
9
 
10
10
 
11
- ## Updates v2.2.0
12
- - More efficient and modularized code in general
13
- - Extensions:
14
- - Triple-difference analysis in own function
15
- - Ordinary Least Squares (OLS) and Maximum Likelihood (ML) estimation
16
- - Extended model fit metrices
17
- - Optional clustered standard errors in didanalysis.did_analysis()
18
- - New data diagnostics function didtools.is_prepost()
19
- - New data diagnostics function didtools.is_multiple_treatment_period()
11
+ ## Updates v2.2.1
20
12
  - Bugfixes:
21
- - Correct import from patsy
22
- - Automatic switch to pre-post data processing if detected
23
- - Completion of package dependencies
24
- - No (redundant) calculation of ITE/GTE for control group anymore
13
+ - Always converting unit and time col to str and calculating unit-time-index col
25
14
 
26
15
 
27
16
  ## Features
@@ -4,16 +4,16 @@
4
4
  # Author: Thomas Wieland
5
5
  # ORCID: 0000-0001-5168-9846
6
6
  # mail: geowieland@googlemail.com
7
- # Version: 1.0.2
8
- # Last update: 2025-12-05 17:23
7
+ # Version: 1.0.3
8
+ # Last update: 2025-12-06 10:48
9
9
  # Copyright (c) 2025 Thomas Wieland
10
10
  #-----------------------------------------------------------------------
11
11
 
12
12
  # Basic config:
13
13
 
14
- PACKAGE_VERSION = "2.2.0"
14
+ PACKAGE_VERSION = "2.2.1"
15
15
 
16
- VERBOSE = False
16
+ VERBOSE = True
17
17
 
18
18
  ROUND_STATISTIC = 3
19
19
  ROUND_PERCENT = 2
@@ -4,8 +4,8 @@
4
4
  # Author: Thomas Wieland
5
5
  # ORCID: 0000-0001-5168-9846
6
6
  # mail: geowieland@googlemail.com
7
- # Version: 2.1.2
8
- # Last update: 2025-12-05 17:23
7
+ # Version: 2.1.3
8
+ # Last update: 2025-12-06 10:49
9
9
  # Copyright (c) 2025 Thomas Wieland
10
10
  #-----------------------------------------------------------------------
11
11
 
@@ -492,8 +492,12 @@ class DiffData:
492
492
 
493
493
  if unit_col is not None and time_col is not None:
494
494
 
495
- if config.UNIT_TIME_COL not in additional_df.columns:
496
- additional_df[config.UNIT_TIME_COL] = additional_df[unit_col]+config.DELIMITER+additional_df[time_col]
495
+ additional_df = tools.panel_index(
496
+ data=additional_df,
497
+ unit_col=unit_col,
498
+ time_col=time_col,
499
+ verbose=verbose
500
+ )
497
501
 
498
502
  if variables is None:
499
503
 
@@ -653,13 +657,28 @@ class DiffData:
653
657
  if after_treatment_period:
654
658
  new_merge[after_treatment_name] = new_merge[TG_col]*new_merge[ATT_col]
655
659
 
656
- if config.UNIT_TIME_COL not in new_merge.columns:
657
- new_merge[config.UNIT_TIME_COL] = new_merge[config.UNIT_COL].astype(str) + config.DELIMITER + new_merge[config.TIME_COL].astype(str)
660
+ new_merge = tools.panel_index(
661
+ data=new_merge,
662
+ unit_col=unit_id_col,
663
+ time_col=time_col,
664
+ verbose=verbose
665
+ )
658
666
 
659
- if config.UNIT_TIME_COL not in did_modeldata_old.columns:
660
- did_modeldata_old[config.UNIT_TIME_COL] = did_modeldata_old[unit_id_col].astype(str) + config.DELIMITER + did_modeldata_old[time_col].astype(str)
667
+ did_modeldata_old = tools.panel_index(
668
+ data=did_modeldata_old,
669
+ unit_col=unit_id_col,
670
+ time_col=time_col,
671
+ verbose=verbose
672
+ )
661
673
 
662
- new_merge = new_merge[[config.UNIT_TIME_COL, TT_col, TG_col, treatment_name]].copy()
674
+ new_merge = new_merge[
675
+ [
676
+ config.UNIT_TIME_COL,
677
+ TT_col,
678
+ TG_col,
679
+ treatment_name
680
+ ]
681
+ ].copy()
663
682
 
664
683
  did_modeldata_new = did_modeldata_old.merge(
665
684
  new_merge,
@@ -736,7 +755,8 @@ class DiffData:
736
755
  additional_df,
737
756
  counterfactual_outcome_col,
738
757
  time_col,
739
- counterfactual_UID = "counterfac"
758
+ counterfactual_UID = "counterfac",
759
+ verbose: bool = config.VERBOSE
740
760
  ):
741
761
 
742
762
  if time_col is None or counterfactual_outcome_col is None:
@@ -766,7 +786,14 @@ class DiffData:
766
786
  did_modeldata_counterfac[config.TIME_COUNTER_COL] = treatment_data[config.TIME_COUNTER_COL].values
767
787
  did_modeldata_counterfac[config.TT_COL] = treatment_data[config.TT_COL].values
768
788
  did_modeldata_counterfac[config.TREATMENT_COL] = did_modeldata_counterfac[config.TG_COL] * did_modeldata_counterfac[config.TT_COL]
769
- did_modeldata_counterfac[config.UNIT_TIME_COL] = did_modeldata_counterfac[config.UNIT_COL].astype(str) + config.DELIMITER + did_modeldata_counterfac[config.TIME_COL].astype(str)
789
+
790
+ did_modeldata_counterfac = tools.panel_index(
791
+ data=did_modeldata_counterfac,
792
+ unit_col=config.UNIT_COL,
793
+ time_col=config.TIME_COL,
794
+ verbose=verbose
795
+ )
796
+
770
797
  if treatment_config["after_treatment_period"]:
771
798
  did_modeldata_counterfac["ATT"] = treatment_data["ATT"].values
772
799
 
@@ -1046,9 +1073,19 @@ def merge_data(
1046
1073
  if np.dtype(did_modeldata[config.TIME_COL]) != np.dtype(outcome_data[time_col]):
1047
1074
  print(f"WARNING: Time columns of treatment data and outcome data differ: {str(np.dtype(did_modeldata[config.TIME_COL]))}, {str(np.dtype(outcome_data[time_col]))}. This might induce an error while building the model dataset.")
1048
1075
 
1049
- did_modeldata[config.UNIT_TIME_COL] = did_modeldata[config.UNIT_COL].astype(str) + config.DELIMITER + did_modeldata[config.TIME_COL].astype(str)
1076
+ did_modeldata = tools.panel_index(
1077
+ data=did_modeldata,
1078
+ unit_col=config.UNIT_COL,
1079
+ time_col=config.TIME_COL,
1080
+ verbose=verbose
1081
+ )
1050
1082
 
1051
- outcome_data[config.UNIT_TIME_COL] = outcome_data[unit_id_col].astype(str) + config.DELIMITER + outcome_data[time_col].astype(str)
1083
+ outcome_data = tools.panel_index(
1084
+ data=outcome_data,
1085
+ unit_col=unit_id_col,
1086
+ time_col=time_col,
1087
+ verbose=verbose
1088
+ )
1052
1089
 
1053
1090
  if keep_columns:
1054
1091
  outcome_data_short = outcome_data
@@ -4,8 +4,8 @@
4
4
  # Author: Thomas Wieland
5
5
  # ORCID: 0000-0001-5168-9846
6
6
  # mail: geowieland@googlemail.com
7
- # Version: 2.1.0
8
- # Last update: 2025-12-05 17:24
7
+ # Version: 2.1.1
8
+ # Last update: 2025-12-06 10:48
9
9
  # Copyright (c) 2025 Thomas Wieland
10
10
  #-----------------------------------------------------------------------
11
11
 
@@ -45,7 +45,37 @@ def check_columns(
45
45
 
46
46
  if missing_columns:
47
47
  raise KeyError(f"Data do not contain column(s): {', '.join(missing_columns)}")
48
-
48
+
49
+ def panel_index(
50
+ data: pd.DataFrame,
51
+ unit_col: str,
52
+ time_col: str,
53
+ verbose: bool = config.VERBOSE
54
+ ):
55
+
56
+ to_str = []
57
+ unit_x_time = True
58
+
59
+ if data[unit_col].dtype != 'object':
60
+ data[unit_col] = data[unit_col].astype(str)
61
+ to_str.append(unit_col)
62
+
63
+ if data[time_col].dtype != 'object':
64
+ data[time_col] = data[time_col].astype(str)
65
+ to_str.append(time_col)
66
+
67
+ if config.UNIT_TIME_COL not in data.columns:
68
+ unit_x_time = False
69
+ data[config.UNIT_TIME_COL] = data[unit_col]+config.DELIMITER+data[time_col]
70
+
71
+ if verbose:
72
+ if len(to_str) > 0:
73
+ print(f"NOTE: The following columns were converted to str: {', '.join(to_str)}.")
74
+ if not unit_x_time:
75
+ print(f"NOTE: The following unit-time-index column was included: {config.UNIT_TIME_COL}.")
76
+
77
+ return data
78
+
49
79
  def is_balanced(
50
80
  data: pd.DataFrame,
51
81
  unit_col: str,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: diffindiff
3
- Version: 2.2.0
3
+ Version: 2.2.1
4
4
  Summary: diffindiff: Python library for convenient Difference-in-Differences Analyses
5
5
  Author: Thomas Wieland
6
6
  Author-email: geowieland@googlemail.com
@@ -16,20 +16,9 @@ This Python library is designed for performing Difference-in-Differences (DiD) a
16
16
  Thomas Wieland [ORCID](https://orcid.org/0000-0001-5168-9846) [EMail](mailto:geowieland@googlemail.com)
17
17
 
18
18
 
19
- ## Updates v2.2.0
20
- - More efficient and modularized code in general
21
- - Extensions:
22
- - Triple-difference analysis in own function
23
- - Ordinary Least Squares (OLS) and Maximum Likelihood (ML) estimation
24
- - Extended model fit metrices
25
- - Optional clustered standard errors in didanalysis.did_analysis()
26
- - New data diagnostics function didtools.is_prepost()
27
- - New data diagnostics function didtools.is_multiple_treatment_period()
19
+ ## Updates v2.2.1
28
20
  - Bugfixes:
29
- - Correct import from patsy
30
- - Automatic switch to pre-post data processing if detected
31
- - Completion of package dependencies
32
- - No (redundant) calculation of ITE/GTE for control group anymore
21
+ - Always converting unit and time col to str and calculating unit-time-index col
33
22
 
34
23
 
35
24
  ## Features
@@ -8,7 +8,7 @@ def read_README():
8
8
 
9
9
  setup(
10
10
  name='diffindiff',
11
- version='2.2.0',
11
+ version='2.2.1',
12
12
  description='diffindiff: Python library for convenient Difference-in-Differences Analyses',
13
13
  packages=find_packages(include=["diffindiff", "diffindiff.tests"]),
14
14
  include_package_data=True,
File without changes
File without changes