Skip to content

Commit ce12662

Browse files
committed
update medicalcoder-vs-mimic.Rmd
1 parent 73a479c commit ce12662

1 file changed

Lines changed: 82 additions & 61 deletions

File tree

vignettes/articles/medicalcoder-vs-mimic.Rmd

Lines changed: 82 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,13 @@ The SQL file used here is vendored from
4545
[`mimic-code` commit `278df75ec30991ff3a6f5ceb6d2221635a085e9f`](https://raw.githubusercontent.com/MIT-LCP/mimic-code/278df75ec30991ff3a6f5ceb6d2221635a085e9f/mimic-iv/concepts/comorbidity/charlson.sql)
4646
so this article does not depend on network access during rendering.
4747

48+
The manuscript supplement uses the same commit as the published comparator and
49+
then harmonizes output conventions before assessing agreement. The SQL relies
50+
on string comparisons in the source query, whereas _medicalcoder_ maps input
51+
codes to known ICD codes through method-specific lookup tables. That
52+
precomputed map is what allows the same `comorbidities()` interface to support
53+
full and compact codes, mixed ICD versions, and multiple comorbidity families.
54+
4855
```{r}
4956
mimic_charson_query <-
5057
scan(
@@ -58,26 +65,25 @@ mimic_charson_query <-
5865
)
5966
6067
# modify the query to work in SQLite
61-
mimic_charson_query <-
62-
gsub(pattern = "physionet-data.mimiciv_hosp.admissions",
63-
replacement = "admissions",
64-
x = mimic_charson_query,
65-
fixed = TRUE)
66-
mimic_charson_query <-
67-
gsub(pattern = "physionet-data.mimiciv_hosp.diagnoses_icd",
68-
replacement = "diagnoses",
69-
x = mimic_charson_query,
70-
fixed = TRUE)
71-
mimic_charson_query <-
72-
gsub(pattern = "physionet-data.mimiciv_derived.age",
73-
replacement = "ages",
74-
x = mimic_charson_query,
75-
fixed = TRUE)
76-
mimic_charson_query <-
77-
gsub(pattern = "GREATEST",
78-
replacement = "MAX",
79-
x = mimic_charson_query,
80-
fixed = TRUE)
68+
# replace Google Big Query table names with table names to be using in
69+
# the local RSQLite in memory database. Three table names need to be
70+
# changed and one function call: GBQ GREATEST needs to be replaced by MAX
71+
prs <-
72+
c(
73+
"physionet-data.mimiciv_hosp.admissions" = "admissions",
74+
"physionet-data.mimiciv_hosp.diagnoses_icd" = "diagnoses",
75+
"physionet-data.mimiciv_derived.age" = "ages",
76+
"GREATEST" = "MAX"
77+
)
78+
for(i in seq_len(length(prs))) {
79+
mimic_charson_query <-
80+
gsub(
81+
pattern = names(prs)[i],
82+
replacement = prs[i],
83+
x = mimic_charson_query,
84+
fixed = TRUE
85+
)
86+
}
8187
8288
mimic_charson_query <- paste(mimic_charson_query, collapse = "\n")
8389
```
@@ -98,7 +104,6 @@ setnames(
98104
mdcr_for_mimic[, hadm_id := paste0(subject_id, "e1")]
99105
mdcr_for_mimic[, seq_num := 1L:.N, by = .(subject_id, hadm_id)]
100106
mdcr_for_mimic[, age := as.integer(substr(as.character(subject_id), 1L, 2L))]
101-
102107
```
103108

104109
```{r}
@@ -109,9 +114,23 @@ library(RSQLite)
109114
con <- dbConnect(drv = RSQLite::SQLite(), dbname = ":memory:")
110115
111116
# add data to the data base
112-
dbWriteTable(conn = con, name = "diagnoses", value = mdcr_for_mimic[dx == 1L])
113-
dbWriteTable(conn = con, name = "admissions", value = mdcr_for_mimic[, unique(.SD), .SDcols = c("subject_id", "hadm_id")])
114-
dbWriteTable(conn = con, name = "ages", value = mdcr_for_mimic[, unique(.SD), .SDcols = c("hadm_id", "age")])
117+
dbWriteTable(
118+
conn = con,
119+
name = "diagnoses",
120+
value = mdcr_for_mimic[dx == 1L]
121+
)
122+
123+
dbWriteTable(
124+
conn = con,
125+
name = "admissions",
126+
value = mdcr_for_mimic[, unique(.SD), .SDcols = c("subject_id", "hadm_id")]
127+
)
128+
129+
dbWriteTable(
130+
conn = con,
131+
name = "ages",
132+
value = mdcr_for_mimic[, unique(.SD), .SDcols = c("hadm_id", "age")]
133+
)
115134
116135
# get the charlson results via MIMIC-IV
117136
mimic_charlson_results <- dbGetQuery(con, mimic_charson_query)
@@ -121,7 +140,8 @@ dbDisconnect(conn = con)
121140
122141
setDT(mimic_charlson_results)
123142
```
124-
143+
To get the same results as the MIMIC-IV Code form
144+
`medicalcoder::comorbidities()` use `method = charlson_mimicivcode`.
125145
```{r}
126146
medicalcoder_charlson_results <-
127147
comorbidities(
@@ -131,14 +151,14 @@ medicalcoder_charlson_results <-
131151
icdv.var = "icd_version",
132152
dx.var = "dx",
133153
age.var = "age",
134-
method = "charlson_quan2005",
154+
method = "charlson_mimicivcode",
135155
full.codes = FALSE,
136156
flag.method = "current",
137157
poa = 1L,
138158
primarydx = 0L
139159
)
140160
```
141-
161+
Let's compare the results:
142162
```{r}
143163
delta <-
144164
merge(
@@ -149,29 +169,24 @@ delta <-
149169
)
150170
```
151171

152-
153-
```{r}
154-
uniqueN(mdcr_for_mimic$hadm_id)
155-
nrow(mimic_charlson_results)
156-
nrow(medicalcoder_charlson_results)
172+
```{r, include = FALSE}
173+
# sanity check
174+
stopifnot(
175+
uniqueN(mdcr_for_mimic$hadm_id) == nrow(mimic_charlson_results),
176+
uniqueN(mdcr_for_mimic$hadm_id) == nrow(medicalcoder_charlson_results)
177+
)
157178
```
158179

159-
Conditions with multiple severity levels, and the metastatic cancer flags differ
160-
between the two methods.
180+
Conditions with multiple severity levels differ between the two methods.
161181
```{r}
162182
dcolumns <- fread(text = "
163183
medicalcoder | mimic
164184
aidshiv | aids
165-
mal | malignant_cancer
166185
cebvd | cerebrovascular_disease
167186
copd | chronic_pulmonary_disease
168187
chf | congestive_heart_failure
169188
dem | dementia
170-
dmc | diabetes_with_cc
171-
dm | diabetes_without_cc
172189
hp | paraplegia
173-
mld | mild_liver_disease
174-
msld | severe_liver_disease
175190
mi | myocardial_infarct
176191
pud | peptic_ulcer_disease
177192
pvd | peripheral_vascular_disease
@@ -190,10 +205,10 @@ for (i in seq_len(nrow(dcolumns))) {
190205
print(e)
191206
r <- eval(e)
192207
print(r)
193-
#if (r) {
194-
# delta[[x]] <- NULL
195-
# delta[[y]] <- NULL
196-
#}
208+
if (r) {
209+
delta[[x]] <- NULL
210+
delta[[y]] <- NULL
211+
}
197212
}
198213
```
199214

@@ -202,6 +217,17 @@ There are three comorbidities where there are different levels of severity.
202217
0 when the more severe condition is flagged. Both methods only consider the
203218
more severe case in the index scoring.
204219

220+
```{r}
221+
# medicalcoder | mimic
222+
# dmc | diabetes_with_cc
223+
# dm | diabetes_without_cc
224+
# mld | mild_liver_disease
225+
# msld | severe_liver_disease
226+
# mal | malignant_cancer
227+
# mst | metastatic_solid_tumor
228+
str(delta)
229+
```
230+
205231
Diabetes - `medicalcoder::comorbidities()` sets the flag for diabetes without
206232
complication to 0 when diabetes with complication is present. MIMIC code
207233
retains the non-complex case.
@@ -240,25 +266,7 @@ delta[mal == 0L & mst == 0L, .N > 0L & all(malignant_cancer == 0L) & all(metasta
240266
delta[mal == 1L & mst == 0L, .N > 0L & all(malignant_cancer == 1L) & all(metastatic_solid_tumor == 0L)]
241267
delta[mal == 0L & mst == 1L, .N > 0L & all(metastatic_solid_tumor == 1L)]
242268
delta[mal == 1L & mst == 1L, .N == 0L]
243-
```
244-
Additionally, ICD-10 codes from CMS of the form C7A.x are not mapped by the
245-
MIMIC codes to metastatic_solid_tumor, but medicalcoder does map these codes to
246-
that comorbidity.
247-
```{r}
248-
subset(
249-
merge(
250-
x = mdcr_for_mimic,
251-
y = subset(delta, mst == 1 & metastatic_solid_tumor == 0, select = c("subject_id", "hadm_id")),
252-
all = FALSE,
253-
by = c("subject_id", "hadm_id")
254-
),
255-
grepl("^C7[A-Z]", icd_code)
256-
)
257-
subset(medicalcoder::get_icd_codes(with.descriptions = TRUE),
258-
full_code %in% c("C7A.098", "C7A.8", "C7B.8"))
259-
```
260269
261-
```{r}
262270
delta[, mal := NULL]
263271
delta[, mst := NULL]
264272
delta[, malignant_cancer := NULL]
@@ -293,10 +301,23 @@ All that is left in the `delta` `data.frame` are the id.vars and the
293301
`medicalcoder::comorbidities()` and report the number of comorbidities flagged
294302
and indicator for any comorbidity.
295303

304+
```{r, include = FALSE}
305+
# sanity check
306+
stopifnot(
307+
identical(
308+
names(delta),
309+
c("subject_id", "hadm_id", "num_cmrb", "cmrb_flag")
310+
)
311+
)
312+
```
313+
296314
```{r}
297315
str(delta)
298316
```
299317

318+
After accounting for naming conventions and severity-suppression conventions,
319+
the remaining columns are _medicalcoder_-specific summaries.
320+
300321
# References
301322

302323
<!-- ----------------------------------------------------------------------- -->

0 commit comments

Comments
 (0)