bryand1 / icd10-cm

ICD-10 CM medical classification list by the World Health Organization
MIT License
89 stars 27 forks source link

Bug with zero-only numerical part of ICD codes like A00 #1

Open juzb opened 4 years ago

juzb commented 4 years ago

Hey Bryan,

really appreciate this neat package! When working with ICD codes like A00, A000, or B00 that have zero-only numerical parts, I get ValueErrors due to the lstripping of all zeros in Line 126 of the init.py:

icd10.find('A00').chapter

# Traceback
    124 
    125 def in_chapter(block: str, icd10: str) -> bool:
--> 126     alpha, numeric = ord(icd10[0]), int(icd10[1:3].lstrip('0'))
    127     sblock, eblock = block.split('-')  # A00-B99
    128     salpha, snumeric = ord(sblock[0]), int(sblock[1:].lstrip('0') or 0)

ValueError: invalid literal for int() with base 10: ''

As far as I can tell, it should work fine when changing

alpha, numeric = ord(icd10[0]), int(icd10[1:3].lstrip('0'))

to

alpha, numeric = ord(icd10[0]), int(icd10[1:3].lstrip('0') or 0)

as in the following lines.

Cheers, Julius

vigosser commented 4 years ago

same problem, and it's works for me


def in_chapter(block: str, icd10: str) -> bool:
    temp=icd10[1:3].lstrip('0')
    if temp=='':
        temp='0'
    alpha, numeric = ord(icd10[0]), int(temp)
    sblock, eblock = block.split('-')  # A00-B99
    salpha, snumeric = ord(sblock[0]), int(sblock[1:].lstrip('0') or 0)
    ealpha, enumeric = ord(eblock[0]), int(eblock[1:].lstrip('0') or 0)
    return salpha <= alpha <= ealpha and snumeric <= numeric <= enumeric
Abed-AlRahman commented 3 years ago

Thank you guys I ran into another error for codes such as this one "O9A212". It was not possible to conver '9A' to int. So, the solution was to strip all the capital letters in line 126:

alpha, numeric = ord(icd10[0]), int(icd10[1:3].lstrip('0').strip('ABCDEFGHIJKLMNOPQRSTUVWXYZ') or 0)

Thanks

najarro82 commented 2 years ago

I tried to edit line 126 to solve this issue with "9A" but also got an invalid literal for int() with base 10 error.

Abed-AlRahman commented 2 years ago

I tried to edit line 126 to solve this issue with "9A" but also got an invalid literal for int() with base 10 error.

Could you please show us the ICD10 code which caused the error? @najarro82

najarro82 commented 2 years ago

Here are some code prefixes causing errors for me. R00. Z3A. U07. Z00.

wbazant commented 1 year ago

I wanted to map chapters from the k4m1113/ICD-10-CSV project. I had the same problem - solved with or 0, and then the one @Abed-AlRahman solved with .strip('ABCDEFGHIJKLMNOPQRSTUVWXYZ').

Then 'C00-D48' was not including the code C49 so I changed the bounds check:

        if salpha == ealpha:
            return alpha == salpha and snumeric <= numeric <= enumeric
        else:
            return (salpha <= alpha < ealpha and snumeric <= numeric) or (salpha < alpha <= ealpha and numeric <= enumeric)

Then the chapter definitions still weren't broad enough so I modified a few. After this, I have a data frame!

Full code:

def in_chapter(block: str, icd10: str) -> bool:
    try:
        alpha, numeric = ord(icd10[0]), int(icd10[1:3].lstrip('0').strip('ABCDEFGHIJKLMNOPQRSTUVWXYZ') or 0)
        sblock, eblock = block.split('-')  # A00-B99
        salpha, snumeric = ord(sblock[0]), int(sblock[1:].lstrip('0') or 0)
        ealpha, enumeric = ord(eblock[0]), int(eblock[1:].lstrip('0') or 0)
        if salpha == ealpha:
            return alpha == salpha and snumeric <= numeric <= enumeric
        else:
            return (salpha <= alpha < ealpha and snumeric <= numeric) or (salpha < alpha <= ealpha and numeric <= enumeric)
    except ValueError as e:
        print(e, block, icd10)

# https://en.wikipedia.org/wiki/ICD-10#List
chapters = [
    ('I', 'A00-B99', 'Certain infectious and parasitic diseases'),
    ('II', 'C00-D49', 'Neoplasms'),
    ('III', 'D50-D89', 'Diseases of the blood and blood-forming organs and certain disorders involving the immune mechanism'),
    ('IV', 'E00-E90', 'Endocrine, nutritional and metabolic diseases'),
    ('V', 'F00-F99', 'Mental and behavioural disorders'),
    ('VI', 'G00-G99', 'Diseases of the nervous system'),
    ('VII', 'H00-H59', 'Diseases of the eye and adnexia'),
    ('VIII', 'H60-H95', 'Diseases of the ear and mastoid process'),
    ('IX', 'I00-I99', 'Diseases of the circulatory system'),
    ('X', 'J00-J99', 'Diseases of the respiratory system'),
    ('XI', 'K00-K95', 'Diseases of the digestive system'),
    ('XII', 'L00-L99', 'Diseases of the skin and subcutaneous tissue'),
    ('XIII', 'M00-M99', 'Diseases of the musculoskeletal system and connective tissue'),
    ('XIV', 'N00-N99', 'Diseases of the genitourinary system'),
    ('XV', 'O00-O99', 'Pregnancy, childbirth and the puerperium'),
    ('XVI', 'P00-P96', 'Certain conditions originating in the perinatal period'),
    ('XVII', 'Q00-Q99', 'Congenital malformations, deformations and chromosomal abnormalities'),
    ('XVIII', 'R00-R99', 'Symptoms, signs and abnormal clinical and laboratory findings, not elsewhere classified'),
    ('XIX', 'S00-T98', 'Injury, poisoning and certain other consequences of external causes'),
    ('XX', 'V00-Y99', 'External causes of morbidity and mortality'),
    ('XXI', 'Z00-Z99', 'Factors influencing health status and contact with health services'),
    ('XXII', 'U00-U99', 'Codes for special purposes'),
]

def find_chapter(code):
    for chapter, block, description in chapters:
        if in_chapter(block, code):
            return chapter, block, description
    raise ValueError(code)

import pandas as pd
import requests
from io import StringIO

df = pd.read_csv(StringIO(requests.get("https://raw.githubusercontent.com/k4m1113/ICD-10-CSV/master/codes.csv").text), names=["Category Code", "Diagnosis Code", "Full Code", "Abbreviated Description", "Full Description", "Category Title"], header=None)

df['Chapter'], df['Chapter Block'], df['Chapter Description'] = zip(*df['Category Code'].map(find_chapter))

df