Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"python.testing.pytestArgs": ["tests"],
"python.testing.unittestEnabled": false,
"python.testing.pytestEnabled": true
}
139 changes: 67 additions & 72 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,20 @@

[![CircleCI](https://circleci.com/gh/topspinj/medcodes.svg?style=svg&circle-token=15b881e69898a9326b263b848fabd0036b5eb6ae)](https://circleci.com/gh/topspinj/medcodes)

MedCodes is a Python package that facilitates the standardization and interpretation of clinical data.

MedCodes is a Python package that facilitates the standardization and interpretation of clinical data.

## Drug Classification

Drugs can be categorized based on attributes such as mechanism of action, chemical structure, function, and metabolic properties. [RxNorm](https://www.nlm.nih.gov/research/umls/rxnorm/) is one component of the Unified Medical Language System (UMLS) that standardizes clinical drug names into a unique identifier and provides capabilities to extract meaningful information for a given drug such as Anatomical Therapeutic Chemical (ATC) classification and MeSH terms.
Drugs can be categorized based on attributes such as mechanism of action, chemical structure, function, and metabolic properties. [RxNorm](https://www.nlm.nih.gov/research/umls/rxnorm/) is one component of the Unified Medical Language System (UMLS) that standardizes clinical drug names into a unique identifier and provides capabilities to extract meaningful information for a given drug such as Anatomical Therapeutic Chemical (ATC) classification and MeSH terms.

##### 1. Anatomical Therapeutic Chemical (ATC) classification

ATC divides the active substances of a drug into different groups accordingly to the organ or system on which they act and their therapeutic, pharmacological, and chemical properties ([1](https://www.who.int/medicines/regulation/medicines-safety/toolkit_atc/en/)). Drugs are grouped at five different levels in which each level represents a different part of a 7 character ATC code. The first (most generic) level contains 14 anatomical/pharmacological groups that are represented by different letters:

- **A:** alimentary tract and metabolism
- **A:** alimentary tract and metabolism
- **B:** blood and blood forming organs
- **C:** cardiovascular system
- **D:** dermatologicals
- **C:** cardiovascular system
- **D:** dermatologicals
- **G:** genito-urinary system and sex hormones
- **H:** systemic hormonal preparations
- **J:** anti-infectives for systemic use
Expand All @@ -42,24 +42,23 @@ MedCodes provides functionality to interpret a given ATC code.
Example of how it works:

```
get_atc_info('M01AE01')
from medcodes import atc_classification
atc_classification('M01AE01')
```

Output:

|atc_level|code|description|
|---------|----|-----------|
|1|M|MUSCOLOSKELETAL SYSTEM|
|2|M01|ANTIINFLAMMATORY AND ANTIRHEUMATIC PRODUCTS|
|3|M01A|NON-STEROIDS|
|4|M01AE|PROPRIONIC ACID DERIVATIVES|
|5|M01AE01|IBUPROFEN|


| atc_level | code | description |
| --------- | ------- | ------------------------------------------- |
| 1 | M | MUSCOLOSKELETAL SYSTEM |
| 2 | M01 | ANTIINFLAMMATORY AND ANTIRHEUMATIC PRODUCTS |
| 3 | M01A | NON-STEROIDS |
| 4 | M01AE | PROPRIONIC ACID DERIVATIVES |
| 5 | M01AE01 | IBUPROFEN |

##### 2. Medical Subject Headings (MeSH) classification

MeSH terms are typically used in the context of indexing and retrieval of literature. Unlike ATC's 5-level classification system, MeSH has several parallel classifications: chemical structure, mechanism of action, and therapeutic use ([2](https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4120719/)).
MeSH terms are typically used in the context of indexing and retrieval of literature. Unlike ATC's 5-level classification system, MeSH has several parallel classifications: chemical structure, mechanism of action, and therapeutic use ([2](https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4120719/)).

<img src="docs/imgs/drug_classification_example.png"/>

Expand All @@ -71,63 +70,60 @@ get_mesh_info('ibuprofen')

Outputs:

|mesh_term|mesh_type|
|---------|---------|
|cyclooxygenase inhibitors|mechanism of action|
|anti-inflammatory agents|therapeutic use|
|analgesic|therapeutic use|
| mesh_term | mesh_type |
| ------------------------- | ------------------- |
| cyclooxygenase inhibitors | mechanism of action |
| anti-inflammatory agents | therapeutic use |
| analgesic | therapeutic use |

## Drug Information

WIP.
WIP.

- To-do: investigate whether it's possible to extract the following information for a given drug:
- patent info
- side effects
- studies involving said drug

- patent info
- side effects
- studies involving said drug

## Comorbidities

`International Statistical Classification of Diseases`, also known as ICD, is a classification system used for patient diagnosis. ICD-9 contains 13,000 codes, while ICD-10 has 68,000 codes. At the end of a patient's hospital stay, a list of ICD codes are assigned to that particular hospital admission, which ultimately gets used for reimbursement purposes.
`International Statistical Classification of Diseases`, also known as ICD, is a classification system used for patient diagnosis. ICD-9 contains 13,000 codes, while ICD-10 has 68,000 codes. At the end of a patient's hospital stay, a list of ICD codes are assigned to that particular hospital admission, which ultimately gets used for reimbursement purposes.

Comorbidity measures, such as the Charlson comorbidity index and Elixhauser score, are used to cluster the overwhelming number of ICD codes into a smaller subset of well-defined comorbidities. These tools have been used in the context of clinical prognosis and comorbidity adjustment in epidemiological outcome studies ([3](https://www.ncbi.nlm.nih.gov/pubmed/15528055), [4](https://www.ncbi.nlm.nih.gov/pubmed/21305268), [5](https://www.ncbi.nlm.nih.gov/pubmed/21509773)). The Charlson comorbidity index covers 17 comorbidities, while the Elixhauser score covers 30. A complete list of Charlson and Elixhauser comorbidity categories can be found in the table below:

|Charlson|Elixhauser|
|----------|---------|
|myocardial infarction |cardiac arrythmias|
|congestive heart failure |congestive heart failure|
|peripheral vascular disease |valvular disease|
|cerebrovascular disease |pulmonary circulation disorders|
|dementia |peripheral vascular disorders|
|chronic pulmonary disease |hypertension (uncomplicated)|
|rheumatic disease |hypertension (complicated)|
|peptic ulcer disease |paralysis|
|mild liver disease |other neurological disorders|
|diabetes without chronic complication |chronic pulmonary disease|
|diabetes with chronic complication |diabetes (uncomplicated)|
|hemiplegia/paraplegia |diabetes (complicated)|
|renal disease |hypothyroidism|
|any malignancy |renal failure|
|moderate/severe liver disease |liver disease|
|metastatic solid tumor |peptic ulcer disease|
|AIDS/HIV |AIDS/HIV|
| |lymphoma|
| |metastatic cancer|
| |solid tutor without metastasis|
| |rheumatoid arthritis|
| |coagulopathy|
| |obesity|
| |weight loss|
| |fluid and electrolyte disorders|
| |blood loss anemia|
| |deficiency anemia|
| |alcohol abuse|
| |drug abuse|
| |psychoses|
| |depression|


| Charlson | Elixhauser |
| ------------------------------------- | ------------------------------- |
| myocardial infarction | cardiac arrythmias |
| congestive heart failure | congestive heart failure |
| peripheral vascular disease | valvular disease |
| cerebrovascular disease | pulmonary circulation disorders |
| dementia | peripheral vascular disorders |
| chronic pulmonary disease | hypertension (uncomplicated) |
| rheumatic disease | hypertension (complicated) |
| peptic ulcer disease | paralysis |
| mild liver disease | other neurological disorders |
| diabetes without chronic complication | chronic pulmonary disease |
| diabetes with chronic complication | diabetes (uncomplicated) |
| hemiplegia/paraplegia | diabetes (complicated) |
| renal disease | hypothyroidism |
| any malignancy | renal failure |
| moderate/severe liver disease | liver disease |
| metastatic solid tumor | peptic ulcer disease |
| AIDS/HIV | AIDS/HIV |
| | lymphoma |
| | metastatic cancer |
| | solid tutor without metastasis |
| | rheumatoid arthritis |
| | coagulopathy |
| | obesity |
| | weight loss |
| | fluid and electrolyte disorders |
| | blood loss anemia |
| | deficiency anemia |
| | alcohol abuse |
| | drug abuse |
| | psychoses |
| | depression |

There are 6 overlapping comorbidities between Charlson and Elixhauser comorbidity mappings:

Expand All @@ -138,7 +134,7 @@ There are 6 overlapping comorbidities between Charlson and Elixhauser comorbidit
5. HIV/AIDS
6. metastatic solid tumors

An example of a Charlson/Elixhauser comorbidty is `congestive heart failure`, which includes the following ICD codes:
An example of a Charlson/Elixhauser comorbidty is `congestive heart failure`, which includes the following ICD codes:

- **428.0:** Congestive heart failure, unspecified
- **428.1:** Left heart failure
Expand All @@ -147,7 +143,7 @@ An example of a Charlson/Elixhauser comorbidty is `congestive heart failure`, wh
- **428.4:** Combined systolic and diastolic heart failure
- **428.9:** Heart failure, unspecified

These comorbidity mappings are able to cluster ICD codes into well-defined categories. This reduces the dimensionality of our clinical dataset, which makes it significantly easier for machine learning models.
These comorbidity mappings are able to cluster ICD codes into well-defined categories. This reduces the dimensionality of our clinical dataset, which makes it significantly easier for machine learning models.

Example of how it works:

Expand All @@ -158,16 +154,15 @@ comorbidities(icd_code=['4280','4284'], mapping='elixhauser')

Outputs:

|icd_code|description|elixhauser|
|----|----|-----|
|4280|Congestive heart failure, unspecified|congestive heart failure|
|4284|Combined systolic and diastolic heart failure|congestive heart failure|

| icd_code | description | elixhauser |
| -------- | --------------------------------------------- | ------------------------ |
| 4280 | Congestive heart failure, unspecified | congestive heart failure |
| 4284 | Combined systolic and diastolic heart failure | congestive heart failure |

### References

1. The World Health Organization. https://www.who.int/medicines/regulation/medicines-safety/toolkit_atc/en/
2. Winnenburg R, Bodenreider O. A framework for assessing the consistency of drug classes across sources. J Biomed Semantics. 2014;5:30.
2. Winnenburg R, Bodenreider O. A framework for assessing the consistency of drug classes across sources. J Biomed Semantics. 2014;5:30.
3. Perkins AJ, Kroenke K, Unützer J, et al. Common comorbidity scales were similar in their ability to predict health care costs and mortality. J Clin Epidemiol. 2004;57(10):1040–1048. https://www.ncbi.nlm.nih.gov/pubmed/15528055
4. Lix LM, Quail J, Teare G, et al. Performance of comorbidity measures for predicting outcomes in population-based osteoporosis cohorts. Osteoporos Int. 2011;22(10):2633–2643 https://www.ncbi.nlm.nih.gov/pubmed/21305268
5. Lieffers JR, Baracos VE, Winget M, et al. A comparison of Charlson and Elixhauser comorbidity measures to predict colorectal cancer survival using administrative health data. Cancer. 2011;117(9):1957–1965. https://www.ncbi.nlm.nih.gov/pubmed/21509773
5. Lieffers JR, Baracos VE, Winget M, et al. A comparison of Charlson and Elixhauser comorbidity measures to predict colorectal cancer survival using administrative health data. Cancer. 2011;117(9):1957–1965. https://www.ncbi.nlm.nih.gov/pubmed/21509773
6 changes: 3 additions & 3 deletions medcodes/drugs/classification.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def atc_classification(atc_id):
lv3_code = ''.join(atc_id[0:4])
lv4_code = ''.join(atc_id[0:5])
lv5_code = None
if len(atc_id) == 6:
if len(atc_id) == 7:
lv5_code = ''.join(atc_id)
codes = [lv1_code, lv2_code, lv3_code, lv4_code, lv5_code]

Expand All @@ -39,12 +39,12 @@ def atc_classification(atc_id):
lv3_desc = ATC_LV3[lv3_code]
lv4_desc = ATC_LV4[lv4_code]
lv5_desc = None
if len(atc_id) == 6:
if len(atc_id) == 7:
lv5_desc = ATC_LV5[lv5_code]
descriptions = [lv1_desc, lv2_desc, lv3_desc, lv4_desc, lv5_desc]

atc_info = DataFrame({
'level': [1, 2, 3, 4, 5],
'code': codes,
'description': descriptions})
return atc_info
return atc_info
10 changes: 5 additions & 5 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
from setuptools import setup, find_packages

setup(
name="icd",
version="0.1",
url="https://github.com/mark-hoffmann/icd",
name="medcodes",
version="0.2",
url="https://github.com/topspinj/medcodes",

author="Jill Cates",
author_email="jill@biosymetrics.com",

description="Tools for working with medical codes such as ICD and CPT",
description="Tools for working with medical codes such as ICD and CPT, forked from https://github.com/mark-hoffmann/icd",

packages=find_packages(),

Expand All @@ -17,4 +17,4 @@
classifiers=[
'Programming Language :: Python :: 3.6'
],
)
)
9 changes: 6 additions & 3 deletions tests/test_atc_classification.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,21 @@
from pandas import DataFrame
from medcodes.drugs import atc_classification


def test_df_output():
"""
Check that atc_classification()
returns a pandas.DataFrame.
"""
assert(isinstance(atc_classification('V08AC08'), DataFrame))
assert isinstance(atc_classification("V08AC08"), DataFrame)
assert atc_classification("V08AC08").isnull().sum().sum() == 0


def test_wrong_type_input_error():
"""
Check that atc_classification()
Check that atc_classification()
raises when passed a list.
"""
msg = "ATC code must be a string."
with pytest.raises(ValueError):
atc_classification(['1', 2, '3'])
atc_classification(["1", 2, "3"])