pycomorb 0.4.2__tar.gz → 0.5.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.
- {pycomorb-0.4.2/src/pycomorb.egg-info → pycomorb-0.5.1}/PKG-INFO +4 -1
- {pycomorb-0.4.2 → pycomorb-0.5.1}/README.md +3 -0
- {pycomorb-0.4.2 → pycomorb-0.5.1}/pyproject.toml +1 -1
- {pycomorb-0.4.2 → pycomorb-0.5.1}/src/pycomorb/CharlsonComorbidityIndex.py +11 -2
- pycomorb-0.5.1/src/pycomorb/ICDModifications.py +61 -0
- {pycomorb-0.4.2 → pycomorb-0.5.1}/src/pycomorb/__init__.py +60 -12
- pycomorb-0.5.1/src/pycomorb/common/CHARLSON_RCS.csv +16 -0
- pycomorb-0.5.1/src/pycomorb/germanmodification/germanmodification.py +87 -0
- {pycomorb-0.4.2 → pycomorb-0.5.1/src/pycomorb.egg-info}/PKG-INFO +4 -1
- {pycomorb-0.4.2 → pycomorb-0.5.1}/src/pycomorb.egg-info/SOURCES.txt +4 -1
- {pycomorb-0.4.2 → pycomorb-0.5.1}/LICENSE +0 -0
- {pycomorb-0.4.2 → pycomorb-0.5.1}/setup.cfg +0 -0
- {pycomorb-0.4.2 → pycomorb-0.5.1}/src/pycomorb/CustomComorbidityIndex.py +0 -0
- {pycomorb-0.4.2 → pycomorb-0.5.1}/src/pycomorb/ElixhauserComorbidityIndex.py +0 -0
- {pycomorb-0.4.2 → pycomorb-0.5.1}/src/pycomorb/GagneComorbidityIndex.py +0 -0
- {pycomorb-0.4.2 → pycomorb-0.5.1}/src/pycomorb/HospitalFrailtyRiskScore.py +0 -0
- {pycomorb-0.4.2 → pycomorb-0.5.1}/src/pycomorb/common/CHARLSON_AUSTRALIA.csv +0 -0
- {pycomorb-0.4.2 → pycomorb-0.5.1}/src/pycomorb/common/CHARLSON_DEYO.csv +0 -0
- {pycomorb-0.4.2 → pycomorb-0.5.1}/src/pycomorb/common/CHARLSON_DHOORE.csv +0 -0
- {pycomorb-0.4.2 → pycomorb-0.5.1}/src/pycomorb/common/CHARLSON_QUAN.csv +0 -0
- {pycomorb-0.4.2 → pycomorb-0.5.1}/src/pycomorb/common/CHARLSON_ROMANO.csv +0 -0
- {pycomorb-0.4.2 → pycomorb-0.5.1}/src/pycomorb/common/CHARLSON_SWEDEN.csv +0 -0
- {pycomorb-0.4.2 → pycomorb-0.5.1}/src/pycomorb/common/CHARLSON_UK_SHMI_v1.55.csv +0 -0
- {pycomorb-0.4.2 → pycomorb-0.5.1}/src/pycomorb/common/ELIXHAUSER.csv +0 -0
- {pycomorb-0.4.2 → pycomorb-0.5.1}/src/pycomorb/common/ELIXHAUSER_AHRQ_ICD10.csv +0 -0
- {pycomorb-0.4.2 → pycomorb-0.5.1}/src/pycomorb/common/ELIXHAUSER_AHRQ_ICD9.csv +0 -0
- {pycomorb-0.4.2 → pycomorb-0.5.1}/src/pycomorb/common/ELIXHAUSER_QUAN.csv +0 -0
- {pycomorb-0.4.2 → pycomorb-0.5.1}/src/pycomorb/common/ELIXHAUSER_WEIGHTS.csv +0 -0
- {pycomorb-0.4.2 → pycomorb-0.5.1}/src/pycomorb/common/GAGNE.csv +0 -0
- {pycomorb-0.4.2 → pycomorb-0.5.1}/src/pycomorb/common/HFRS.csv +0 -0
- {pycomorb-0.4.2 → pycomorb-0.5.1}/src/pycomorb.egg-info/dependency_links.txt +0 -0
- {pycomorb-0.4.2 → pycomorb-0.5.1}/src/pycomorb.egg-info/requires.txt +0 -0
- {pycomorb-0.4.2 → pycomorb-0.5.1}/src/pycomorb.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pycomorb
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.1
|
|
4
4
|
Summary: Comorbidity and frailty score calculation utilities (Charlson, Elixhauser, Gagne, HFRS) using polars
|
|
5
5
|
Author-email: Finn Fassbender <finn.fassbender@charite.de>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -23,6 +23,8 @@ Python package to calculate comorbidity and frailty scores using ICD codes and p
|
|
|
23
23
|
|
|
24
24
|
It is inspired by the R package [`comorbidity`](https://github.com/ellessenne/comorbidity) by Alessandro Gasparini and the corresponding Python rewrite [`comorbidipy`](https://github.com/vvcb/comorbidipy) by Vishnu V Chandrabalan.
|
|
25
25
|
|
|
26
|
+
As a special feature, it also implements the history of the German Modification of the ICD-10 (ICD-10-GM) coding system, allowing users to apply the correct mappings and weights based on the year of diagnosis.
|
|
27
|
+
|
|
26
28
|
## Included Indices / Scores
|
|
27
29
|
|
|
28
30
|
- **Charlson Comorbidity Index** (multiple mappings and weights)
|
|
@@ -108,3 +110,4 @@ See the docstrings in each module for details on arguments and supported variant
|
|
|
108
110
|
|
|
109
111
|
- Free software: MIT license
|
|
110
112
|
- Documentation: (TODO)
|
|
113
|
+
- _Die Erstellung erfolgt unter Verwendung der maschinenlesbaren Fassung des Bundesinstituts für Arzneimittel und Medizinprodukte (BfArM)._
|
|
@@ -8,6 +8,8 @@ Python package to calculate comorbidity and frailty scores using ICD codes and p
|
|
|
8
8
|
|
|
9
9
|
It is inspired by the R package [`comorbidity`](https://github.com/ellessenne/comorbidity) by Alessandro Gasparini and the corresponding Python rewrite [`comorbidipy`](https://github.com/vvcb/comorbidipy) by Vishnu V Chandrabalan.
|
|
10
10
|
|
|
11
|
+
As a special feature, it also implements the history of the German Modification of the ICD-10 (ICD-10-GM) coding system, allowing users to apply the correct mappings and weights based on the year of diagnosis.
|
|
12
|
+
|
|
11
13
|
## Included Indices / Scores
|
|
12
14
|
|
|
13
15
|
- **Charlson Comorbidity Index** (multiple mappings and weights)
|
|
@@ -93,3 +95,4 @@ See the docstrings in each module for details on arguments and supported variant
|
|
|
93
95
|
|
|
94
96
|
- Free software: MIT license
|
|
95
97
|
- Documentation: (TODO)
|
|
98
|
+
- _Die Erstellung erfolgt unter Verwendung der maschinenlesbaren Fassung des Bundesinstituts für Arzneimittel und Medizinprodukte (BfArM)._
|
|
@@ -21,6 +21,10 @@
|
|
|
21
21
|
# Coding algorithms for defining comorbidities in ICD-9-CM and ICD-10 administrative data.
|
|
22
22
|
# Med Care. 2005 Nov;43(11):1130-9.
|
|
23
23
|
# doi: 10.1097/01.mlr.0000182534.19832.83. PMID: 16224307.
|
|
24
|
+
# 7. Armitage JN, van der Meulen JH; Royal College of Surgeons Co-morbidity Consensus Group.
|
|
25
|
+
# Identifying co-morbidity in surgical patients using administrative data with the Royal College of Surgeons Charlson Score.
|
|
26
|
+
# Br J Surg. 2010 May;97(5):772-81.
|
|
27
|
+
# doi: 10.1002/bjs.6930. PMID: 20306528.
|
|
24
28
|
|
|
25
29
|
from pathlib import Path
|
|
26
30
|
|
|
@@ -51,7 +55,7 @@ def CharlsonComorbidityIndex(
|
|
|
51
55
|
age_col (str): Name of the column containing patient ages. Default: "age".
|
|
52
56
|
icd_version (str): ICD version ('icd9', 'icd10', or 'icd9_10'). Default: "icd10".
|
|
53
57
|
icd_version_col (str, optional): Name of the column with ICD version for 'icd9_10'. Default: None.
|
|
54
|
-
implementation (str): CCI implementation ('quan', 'deyo', 'romano', 'australia', 'sweden', 'uk_shmi'). Default: "quan".
|
|
58
|
+
implementation (str): CCI implementation ('quan', 'deyo', 'romano', 'australia', 'sweden', 'rcs', 'uk_shmi'). Default: "quan".
|
|
55
59
|
return_categories (bool): If True, also return presence indicators for each CCI category.
|
|
56
60
|
|
|
57
61
|
Returns:
|
|
@@ -76,6 +80,7 @@ def CharlsonComorbidityIndex(
|
|
|
76
80
|
elif icd_version == "icd9" and implementation in [
|
|
77
81
|
"australia",
|
|
78
82
|
"sweden",
|
|
83
|
+
"rcs",
|
|
79
84
|
"uk_shmi",
|
|
80
85
|
]:
|
|
81
86
|
print(f"Warning: Implementation '{implementation}' only uses ICD-10. Setting ICD version to 'icd10'.") # fmt: skip
|
|
@@ -86,12 +91,14 @@ def CharlsonComorbidityIndex(
|
|
|
86
91
|
"quan",
|
|
87
92
|
"deyo",
|
|
88
93
|
"romano",
|
|
94
|
+
"dhoore",
|
|
89
95
|
"australia",
|
|
90
96
|
"sweden",
|
|
97
|
+
"rcs",
|
|
91
98
|
"uk_shmi",
|
|
92
99
|
], (
|
|
93
100
|
"implementation must be one of: "
|
|
94
|
-
"'quan', 'deyo', 'romano', 'australia', 'sweden', or 'uk_shmi'."
|
|
101
|
+
"'quan', 'deyo', 'romano', 'dhoore', 'australia', 'sweden', 'rcs', or 'uk_shmi'."
|
|
95
102
|
)
|
|
96
103
|
assert (
|
|
97
104
|
age_col in df.columns
|
|
@@ -140,6 +147,8 @@ def CharlsonComorbidityIndex(
|
|
|
140
147
|
definition_file = "CHARLSON_AUSTRALIA.csv"
|
|
141
148
|
elif implementation == "sweden":
|
|
142
149
|
definition_file = "CHARLSON_SWEDEN.csv"
|
|
150
|
+
elif implementation == "rcs":
|
|
151
|
+
definition_file = "CHARLSON_RCS.csv"
|
|
143
152
|
elif implementation == "uk_shmi":
|
|
144
153
|
definition_file = "CHARLSON_UK_SHMI_v1.55.csv"
|
|
145
154
|
else:
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Reference for ICD-10-GM modifications:
|
|
2
|
+
# BfArM: https://www.bfarm.de/DE/Kodiersysteme/Services/Downloads/_node.html
|
|
3
|
+
|
|
4
|
+
import polars as pl
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def get_icd10gm(
|
|
9
|
+
data: pl.DataFrame, code_col="code", year_col="year", target_year=2024
|
|
10
|
+
) -> pl.DataFrame:
|
|
11
|
+
"""
|
|
12
|
+
Map ICD-10-GM codes to the target year using official transfer files.
|
|
13
|
+
|
|
14
|
+
Args:
|
|
15
|
+
data (pl.DataFrame): Input DataFrame with at least columns [code_col, year_col].
|
|
16
|
+
code_col (str): Name of the column containing ICD codes. Default: "code".
|
|
17
|
+
year_col (str): Name of the column containing the year of the ICD code. Default: "year".
|
|
18
|
+
target_year (int): Target year for ICD-10-GM codes (e.g., 2024). Default: 2024.
|
|
19
|
+
|
|
20
|
+
Returns:
|
|
21
|
+
pl.DataFrame: DataFrame with original columns plus a new column 'icd10gm_{target_year}' with mapped codes.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
assert (
|
|
25
|
+
code_col in data.columns
|
|
26
|
+
), f"Column '{code_col}' (ICD code) must be present in input DataFrame."
|
|
27
|
+
assert (
|
|
28
|
+
data.height
|
|
29
|
+
== data.filter(pl.col(code_col).str.contains(r"^[A-Z]")).height
|
|
30
|
+
), f"All values in column '{code_col}' must start with an uppercase letter (A-Z)."
|
|
31
|
+
assert (
|
|
32
|
+
year_col in data.columns
|
|
33
|
+
), f"Column '{year_col}' (year) must be present in input DataFrame."
|
|
34
|
+
assert target_year in range(
|
|
35
|
+
2004, 2026
|
|
36
|
+
), "Target year must be between 2004 and 2025."
|
|
37
|
+
|
|
38
|
+
# Load all transfer files into a dictionary of DataFrames
|
|
39
|
+
transfer_file_path = Path(__file__).parent / "germanmodification/icd10gm.csv" # fmt: skip
|
|
40
|
+
|
|
41
|
+
# Unpivot the data to long format
|
|
42
|
+
transfer_data = (
|
|
43
|
+
pl.read_csv(transfer_file_path, null_values=["", " "], separator=",")
|
|
44
|
+
.unpivot(
|
|
45
|
+
index=str(target_year),
|
|
46
|
+
variable_name=year_col,
|
|
47
|
+
value_name=code_col,
|
|
48
|
+
)
|
|
49
|
+
.cast({year_col: int})
|
|
50
|
+
.rename({str(target_year): f"icd10gm_{target_year}"})
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
data.join(transfer_data, on=[code_col, year_col], how="left")
|
|
55
|
+
# Prefer mapped code, but fall back to original if no mapping available
|
|
56
|
+
.with_columns(
|
|
57
|
+
pl.coalesce(
|
|
58
|
+
pl.col(f"icd10gm_{target_year}"), pl.col(code_col)
|
|
59
|
+
).alias(f"icd10gm_{target_year}")
|
|
60
|
+
)
|
|
61
|
+
)
|
|
@@ -2,25 +2,36 @@
|
|
|
2
2
|
|
|
3
3
|
__author__ = """Finn Fassbender"""
|
|
4
4
|
__email__ = "finn.fassbender@charite.de"
|
|
5
|
-
__version__ = "0.
|
|
5
|
+
__version__ = "0.5.1"
|
|
6
6
|
|
|
7
7
|
from .CharlsonComorbidityIndex import CharlsonComorbidityIndex
|
|
8
8
|
from .ElixhauserComorbidityIndex import ElixhauserComorbidityIndex
|
|
9
9
|
from .GagneComorbidityIndex import GagneComorbidityIndex
|
|
10
|
+
from .CustomComorbidityIndex import CustomComorbidityIndex
|
|
10
11
|
from .HospitalFrailtyRiskScore import HospitalFrailtyRiskScore
|
|
12
|
+
from .ICDModifications import get_icd10gm
|
|
11
13
|
|
|
12
14
|
|
|
13
15
|
def comorbidity(
|
|
14
16
|
score: str,
|
|
15
17
|
df,
|
|
16
|
-
id_col="id",
|
|
17
|
-
code_col="code",
|
|
18
|
-
age_col="age",
|
|
18
|
+
id_col: str = "id",
|
|
19
|
+
code_col: str = "code",
|
|
20
|
+
age_col: str = "age",
|
|
19
21
|
icd_version="icd10",
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
year_col: str = "year",
|
|
23
|
+
icd_version: str = "icd10",
|
|
24
|
+
icd_version_col: str = None,
|
|
25
|
+
icd_modification: str = None,
|
|
26
|
+
icd_modification_target_year: int = 2004,
|
|
27
|
+
implementation: str = None,
|
|
28
|
+
weights: str = None,
|
|
29
|
+
definition_data=None,
|
|
30
|
+
definition_file_path: str = None,
|
|
31
|
+
weight_col_name: str = "weights",
|
|
32
|
+
score_col_name: str = "Custom Comorbidity Score",
|
|
33
|
+
mutual_exclusion_rules: list[tuple[str, str]] = None,
|
|
34
|
+
return_categories: bool = False,
|
|
24
35
|
):
|
|
25
36
|
"""
|
|
26
37
|
Unified wrapper to calculate a comorbidity or frailty score.
|
|
@@ -31,16 +42,38 @@ def comorbidity(
|
|
|
31
42
|
id_col (str): Name of the column containing unique identifier. Default: "id".
|
|
32
43
|
code_col (str): Name of the column containing ICD codes. Default: "code".
|
|
33
44
|
age_col (str): Name of the column containing patient ages (Charlson only). Default: "age".
|
|
45
|
+
year_col (str): Name of the column containing the year of the ICD code (for ICD history modifications). Default: "year".
|
|
34
46
|
icd_version (str): ICD version. Default: "icd10".
|
|
35
47
|
icd_version_col (str, optional): Name of the column with ICD version for 'icd9_10'. Default: None.
|
|
48
|
+
icd_modification (str, optional): ICD modification to apply ('icd10gm'). Default: None.
|
|
49
|
+
icd_modification_target_year (int): Target year for ICD modification (if applicable). Default: 2004.
|
|
36
50
|
implementation (str, optional): Implementation variant (see individual index docs).
|
|
37
51
|
weights (str, optional): Weighting scheme (Elixhauser only).
|
|
52
|
+
definition_data (DataFrame, optional): DataFrame with ICD definitions and weights (Custom only).
|
|
53
|
+
definition_file_path (str, optional): Path to CSV with ICD definitions and weights (Custom only).
|
|
54
|
+
weight_col_name (str): Name of the column with weights in definition_data (Custom only).
|
|
55
|
+
score_col_name (str): Name for the calculated score column (Custom only).
|
|
56
|
+
mutual_exclusion_rules (list of tuple, optional): List of mutually exclusive category pairs (Custom only).
|
|
38
57
|
return_categories (bool): Whether to return category indicators.
|
|
39
58
|
|
|
40
59
|
Returns:
|
|
41
60
|
- DataFrame with [id_col, score].
|
|
42
61
|
- DataFrame with category indicators if return_categories is True, else None.
|
|
43
62
|
"""
|
|
63
|
+
# apply ICD modification if requested
|
|
64
|
+
if icd_modification is not None:
|
|
65
|
+
if icd_modification.lower() == "icd10gm":
|
|
66
|
+
df = get_icd10gm(
|
|
67
|
+
data=df,
|
|
68
|
+
code_col=code_col,
|
|
69
|
+
year_col=year_col,
|
|
70
|
+
target_year=icd_modification_target_year,
|
|
71
|
+
)
|
|
72
|
+
code_col = f"icd10gm_{icd_modification_target_year}"
|
|
73
|
+
else:
|
|
74
|
+
raise ValueError(f"Unknown icd_modification: '{icd_modification}'. Currently, only 'icd10gm' is supported.") # fmt: skip
|
|
75
|
+
|
|
76
|
+
# calculate scores
|
|
44
77
|
score = score.lower()
|
|
45
78
|
if score in (
|
|
46
79
|
"cci",
|
|
@@ -49,9 +82,7 @@ def comorbidity(
|
|
|
49
82
|
"charlson_comorbidity_index",
|
|
50
83
|
):
|
|
51
84
|
if age_col not in df.columns:
|
|
52
|
-
raise ValueError(
|
|
53
|
-
f"Column '{age_col}' (age) must be present in input DataFrame for Charlson calculation."
|
|
54
|
-
)
|
|
85
|
+
raise ValueError(f"Column '{age_col}' (age) must be present in input DataFrame for Charlson calculation.") # fmt: skip
|
|
55
86
|
return CharlsonComorbidityIndex(
|
|
56
87
|
df=df,
|
|
57
88
|
id_col=id_col,
|
|
@@ -108,8 +139,25 @@ def comorbidity(
|
|
|
108
139
|
icd_version=icd_version,
|
|
109
140
|
return_categories=return_categories,
|
|
110
141
|
)
|
|
142
|
+
elif score in (
|
|
143
|
+
"custom",
|
|
144
|
+
"customcomorbidityindex",
|
|
145
|
+
"custom_comorbidity_index",
|
|
146
|
+
):
|
|
147
|
+
return CustomComorbidityIndex(
|
|
148
|
+
df=df,
|
|
149
|
+
id_col=id_col,
|
|
150
|
+
code_col=code_col,
|
|
151
|
+
icd_version=icd_version,
|
|
152
|
+
icd_version_col=icd_version_col,
|
|
153
|
+
definition_data=definition_data or definition_file_path,
|
|
154
|
+
weight_col_name=weight_col_name,
|
|
155
|
+
score_col_name=score_col_name,
|
|
156
|
+
mutual_exclusion_rules=mutual_exclusion_rules,
|
|
157
|
+
return_categories=return_categories,
|
|
158
|
+
)
|
|
111
159
|
else:
|
|
112
160
|
raise ValueError(
|
|
113
161
|
f"Unknown score: '{score}'. Must be one of: "
|
|
114
|
-
"'charlson', 'elixhauser', 'gagne', 'hfrs'."
|
|
162
|
+
"'charlson', 'elixhauser', 'gagne', 'hfrs' or 'custom'."
|
|
115
163
|
)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
index,category,icd9_codes,icd10_codes,weights
|
|
2
|
+
0,Age,,YYYY|YYYY,0
|
|
3
|
+
1,Myocardial infarction,,I21|I22|I23|I252,1
|
|
4
|
+
2,Congestive heart failure,,I11|I13|I255|I42|I43|I50|I517,1
|
|
5
|
+
3,Peripheral vascular disease,,I70|I71|I72|I73|I770|I771|K551|K558|K559|R02|Z958|Z959,1
|
|
6
|
+
4,Cerebrovascular disease,,G45|G46|I60|I61|I62|I63|I65|I66|I67|I68|I69,1
|
|
7
|
+
5,Dementia,,A810|F00|F01|F02|F03|F051|G30|G31,1
|
|
8
|
+
6,Chronic pulmonary disease,,I26|I27|J40|J41|J42|J44|J43|J45|J46|J47|J60|J61|J62|J63|J66|J64|J65|J66|J67|J684|J701|J703,1
|
|
9
|
+
7,Rheumatological disease,,M05|M06|M09|M120|M315|M32|M33|M34|M35|M36,1
|
|
10
|
+
8,Liver disease,,B18|I85|I864|I982|K70|K71|K721|K729|K76|R162|Z944,1
|
|
11
|
+
9,Diabetes,,E10|E11|E12|E13|E14,1
|
|
12
|
+
10,Hemiplegia or paraplegia,,G114|G81|G82|G83,1
|
|
13
|
+
11,Renal disease,,I12|I13|N01|N03|N05|N07|N08|N171|N172|N18|N19|N25|Z49|Z940|Z992,1
|
|
14
|
+
12,Any malignancy,,C0|C1|C20|C21|C22|C23|C24|C25|C26|C30|C31|C32|C33|C34|C37|C38|C39|C40|C41|C43|C45|C46|C47|C48|C49|C50|C51|C52|C53|C54|C55|C56|C57|C58|C60|C61|C62|C63|C64|C65|C66|C67|C68|C69|C70|C71|C72|C73|C74|C75|C76|C80|C81|C82|C83|C84|C85|C88|C90|C91|C92|C93|C94|C95|C96|C97,1
|
|
15
|
+
13,Metastatic solid tumor,,C77|C78|C79,1
|
|
16
|
+
14,AIDS/HIV,,B20|B21|B22|B23|B24,1
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# 1. download all the relevant ICD-10-GM versions from https://www.bfarm.de/DE/Kodiersysteme/Services/Downloads/_node.html
|
|
2
|
+
# 2. unzip them into a folder, e.g. data/icd10gm
|
|
3
|
+
# 3. take only the transfer files (e.g. icd10gm2013syst_umsteiger_2012_2013.txt for 2012->2013) and put them into a separate folder, e.g. data/icd10gm/transfers
|
|
4
|
+
# 4. run this script in that folder
|
|
5
|
+
|
|
6
|
+
import os
|
|
7
|
+
import polars as pl
|
|
8
|
+
|
|
9
|
+
files = [
|
|
10
|
+
"umsteiger20042005.txt", # 2004->2005, renamed from 'umsteiger.txt' for clarity
|
|
11
|
+
"umsteiger20052006.txt", # 2005->2006, renamed from 'umsteiger.txt' for clarity
|
|
12
|
+
"umsteiger20062007.txt", # 2006->2007, renamed from 'Umsteiger.txt' for clarity
|
|
13
|
+
"umsteiger20072008.txt", # 2007->2008
|
|
14
|
+
"umsteiger_icd10gmsyst2008_icd10gmsyst2009.txt", # 2008->2009
|
|
15
|
+
"umsteiger_icd10gmsyst2009_icd10gmsyst2010.txt", # 2009->2010
|
|
16
|
+
"umsteiger_icd10gmsyst2010_icd10gmsyst2011.txt", # 2010->2011
|
|
17
|
+
"umsteiger_icd10gmsyst2011_icd10gmsyst2012.txt", # 2011->2012
|
|
18
|
+
"icd10gm2013syst_umsteiger_2012_2013.txt", # 2012->2013
|
|
19
|
+
"icd10gm2014syst_umsteiger_2013_2014.txt", # 2013->2014
|
|
20
|
+
"icd10gm2015syst_umsteiger_2014_2015.txt", # 2014->2015
|
|
21
|
+
"icd10gm2016syst_umsteiger_2015_2016.txt", # 2015->2016
|
|
22
|
+
"icd10gm2017syst_umsteiger_2016_2017.txt", # 2016->2017
|
|
23
|
+
"icd10gm2018syst_umsteiger_2017_2018.txt", # 2017->2018
|
|
24
|
+
"icd10gm2019syst_umsteiger_2018_2019.txt", # 2018->2019
|
|
25
|
+
"icd10gm2020syst_umsteiger_2019_2020.txt", # 2019->2020
|
|
26
|
+
"icd10gm2021syst_umsteiger_2020_2021.txt", # 2020->2021
|
|
27
|
+
"icd10gm2022syst_umsteiger_2021_2022.txt", # 2021->2022
|
|
28
|
+
"icd10gm2023syst_umsteiger_2022_2023_20221206.txt", # 2022->2023
|
|
29
|
+
"icd10gm2024syst_umsteiger_2023_20221206_2024.txt", # 2023->2024
|
|
30
|
+
"icd10gm2025syst_umsteiger_2024_2025.txt", # 2024->2025
|
|
31
|
+
]
|
|
32
|
+
years = range(2004, 2025)
|
|
33
|
+
|
|
34
|
+
df = None
|
|
35
|
+
for year, file in zip(years, files):
|
|
36
|
+
print(f"Processing {year}->{year+1}: {file}")
|
|
37
|
+
if df is None:
|
|
38
|
+
df = pl.DataFrame(schema={str(year): pl.Utf8})
|
|
39
|
+
|
|
40
|
+
year_df = (
|
|
41
|
+
pl.read_csv(
|
|
42
|
+
file,
|
|
43
|
+
separator=";",
|
|
44
|
+
has_header=False,
|
|
45
|
+
null_values=["", " "], # , "UNDEF"],
|
|
46
|
+
schema={
|
|
47
|
+
str(year): pl.Utf8, # Alte_Kodiernummer
|
|
48
|
+
str(year + 1): pl.Utf8, # Neue_Kodiernummer
|
|
49
|
+
"A1": pl.Utf8,
|
|
50
|
+
"A2": pl.Utf8,
|
|
51
|
+
},
|
|
52
|
+
)
|
|
53
|
+
.drop("A1", "A2")
|
|
54
|
+
# Clean up codes: remove dots, uppercase
|
|
55
|
+
.with_columns(
|
|
56
|
+
pl.col(str(year))
|
|
57
|
+
.str.replace_all(r"\.", "")
|
|
58
|
+
.replace("UNDEF", f"UNDEF{year}")
|
|
59
|
+
.str.to_uppercase(),
|
|
60
|
+
pl.col(str(year + 1))
|
|
61
|
+
.str.replace_all(r"\.", "")
|
|
62
|
+
.replace("UNDEF", f"UNDEF{year}")
|
|
63
|
+
.str.to_uppercase(),
|
|
64
|
+
)
|
|
65
|
+
.filter(pl.col(str(year)).ne_missing(pl.col(str(year + 1))))
|
|
66
|
+
.unique()
|
|
67
|
+
)
|
|
68
|
+
df = df.join(year_df, on=str(year), how="full", coalesce=True)
|
|
69
|
+
|
|
70
|
+
# Propagate codes forward to fill in unmapped codes
|
|
71
|
+
for year in years:
|
|
72
|
+
df = df.with_columns(
|
|
73
|
+
pl.when(pl.col(str(year + 1)).is_null())
|
|
74
|
+
.then(pl.col(str(year)))
|
|
75
|
+
.otherwise(pl.col(str(year + 1)))
|
|
76
|
+
.alias(str(year + 1))
|
|
77
|
+
)
|
|
78
|
+
# Propagate codes backward to fill in unmapped codes
|
|
79
|
+
for year in reversed(years):
|
|
80
|
+
df = df.with_columns(
|
|
81
|
+
pl.when(pl.col(str(year)).is_null())
|
|
82
|
+
.then(pl.col(str(year + 1)))
|
|
83
|
+
.otherwise(pl.col(str(year)))
|
|
84
|
+
.alias(str(year))
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
df.write_csv("icd10gm.csv")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pycomorb
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.1
|
|
4
4
|
Summary: Comorbidity and frailty score calculation utilities (Charlson, Elixhauser, Gagne, HFRS) using polars
|
|
5
5
|
Author-email: Finn Fassbender <finn.fassbender@charite.de>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -23,6 +23,8 @@ Python package to calculate comorbidity and frailty scores using ICD codes and p
|
|
|
23
23
|
|
|
24
24
|
It is inspired by the R package [`comorbidity`](https://github.com/ellessenne/comorbidity) by Alessandro Gasparini and the corresponding Python rewrite [`comorbidipy`](https://github.com/vvcb/comorbidipy) by Vishnu V Chandrabalan.
|
|
25
25
|
|
|
26
|
+
As a special feature, it also implements the history of the German Modification of the ICD-10 (ICD-10-GM) coding system, allowing users to apply the correct mappings and weights based on the year of diagnosis.
|
|
27
|
+
|
|
26
28
|
## Included Indices / Scores
|
|
27
29
|
|
|
28
30
|
- **Charlson Comorbidity Index** (multiple mappings and weights)
|
|
@@ -108,3 +110,4 @@ See the docstrings in each module for details on arguments and supported variant
|
|
|
108
110
|
|
|
109
111
|
- Free software: MIT license
|
|
110
112
|
- Documentation: (TODO)
|
|
113
|
+
- _Die Erstellung erfolgt unter Verwendung der maschinenlesbaren Fassung des Bundesinstituts für Arzneimittel und Medizinprodukte (BfArM)._
|
|
@@ -6,6 +6,7 @@ src/pycomorb/CustomComorbidityIndex.py
|
|
|
6
6
|
src/pycomorb/ElixhauserComorbidityIndex.py
|
|
7
7
|
src/pycomorb/GagneComorbidityIndex.py
|
|
8
8
|
src/pycomorb/HospitalFrailtyRiskScore.py
|
|
9
|
+
src/pycomorb/ICDModifications.py
|
|
9
10
|
src/pycomorb/__init__.py
|
|
10
11
|
src/pycomorb.egg-info/PKG-INFO
|
|
11
12
|
src/pycomorb.egg-info/SOURCES.txt
|
|
@@ -16,6 +17,7 @@ src/pycomorb/common/CHARLSON_AUSTRALIA.csv
|
|
|
16
17
|
src/pycomorb/common/CHARLSON_DEYO.csv
|
|
17
18
|
src/pycomorb/common/CHARLSON_DHOORE.csv
|
|
18
19
|
src/pycomorb/common/CHARLSON_QUAN.csv
|
|
20
|
+
src/pycomorb/common/CHARLSON_RCS.csv
|
|
19
21
|
src/pycomorb/common/CHARLSON_ROMANO.csv
|
|
20
22
|
src/pycomorb/common/CHARLSON_SWEDEN.csv
|
|
21
23
|
src/pycomorb/common/CHARLSON_UK_SHMI_v1.55.csv
|
|
@@ -25,4 +27,5 @@ src/pycomorb/common/ELIXHAUSER_AHRQ_ICD9.csv
|
|
|
25
27
|
src/pycomorb/common/ELIXHAUSER_QUAN.csv
|
|
26
28
|
src/pycomorb/common/ELIXHAUSER_WEIGHTS.csv
|
|
27
29
|
src/pycomorb/common/GAGNE.csv
|
|
28
|
-
src/pycomorb/common/HFRS.csv
|
|
30
|
+
src/pycomorb/common/HFRS.csv
|
|
31
|
+
src/pycomorb/germanmodification/germanmodification.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|