diff --git a/NEWS.md b/NEWS.md index 1e18187e..c2898adb 100644 --- a/NEWS.md +++ b/NEWS.md @@ -16,8 +16,12 @@ namespaces is available, then the return from `comorbidities()` will be a `tibble` (or list of `tibble`s when `subconditions = TRUE`). - The tests were extended to consider the cases of passing in a data.table or - tibble to comorbidities when the associated namespaces are not available. + The tests were extended to consider the cases of passing in a `data.table` or + `tibble` to comorbidities when the associated namespaces are not available. + +## Other Changes + +* Improve formatting of vignettes/articles. # medicalcoder 0.6.0 diff --git a/vignettes/charlson.Rmd b/vignettes/charlson.Rmd index 42b1a22f..fe622729 100644 --- a/vignettes/charlson.Rmd +++ b/vignettes/charlson.Rmd @@ -84,12 +84,10 @@ Call `summary()` on the return object for a list of summary objects. These can used to generate output tables to the end user's liking. ```{r} -str( - summary(mdcr_results) -) +str(summary(mdcr_results)) ``` -```{r, results = "asis"} +```{r echo = FALSE, results = "asis"} x <- summary(mdcr_results)$conditions[, c("condition_description", "count", "percent")] tab <- kableExtra::kbl( @@ -99,6 +97,7 @@ tab <- col.names = c("", "Count", "Percentage"), digits = 3 ) +tab <- kableExtra::kable_styling(tab, bootstrap_options = c("striped"), font_size = 10) tab <- kableExtra::pack_rows(tab, group_label = "Comorbidity", start_row = 1, end_row = 17) tab <- kableExtra::pack_rows(tab, group_label = "Total Comorbidities", start_row = 18, end_row = nrow(x)) tab diff --git a/vignettes/comorbidities.Rmd b/vignettes/comorbidities.Rmd index 36f24686..afe49efe 100644 --- a/vignettes/comorbidities.Rmd +++ b/vignettes/comorbidities.Rmd @@ -126,11 +126,7 @@ head(mdcr_longitudinal) ``` A great level of detail for each of the comorbidity algorithms are provided in -dedicated vignettes: - -```{r label = "other-vignettes", eval = FALSE} -vignette(package = "medicalcoder")$results -``` +dedicated vignettes. # When are conditions flag? @@ -142,7 +138,7 @@ hospitalization. Implementation of Elixhauser comorbidities for 2022 and beyond [@ahrq2025] explicitly define the use of present on admission flags for specific conditions (see the `poa_required` flag reported in the data set returned by -`get_elixhauser_poa`). +`get_elixhauser_poa()`). ```{r} str(get_elixhauser_poa()) ``` @@ -196,35 +192,45 @@ I50.40 intentionally marked as not present on admission. ```{r, label = "example-setup"} lookup_icd_codes(c("C78.4", "I50.40")) -subset(get_pccc_codes(), - subset = full_code %in% c("C78.4", "I50.40"), - select = c("icdv", "dx", "code", "full_code", "condition", "pccc_v3.0")) +codes <- c("C78.4", "I50.40") +cols <- c("icdv", "dx", "code", "full_code", "condition") -subset(get_charlson_codes(), - subset = full_code %in% c("C78.4", "I50.40"), - select = c("icdv", "dx", "code", "full_code", "condition", "charlson_quan2011")) +subset( + get_pccc_codes(), + subset = full_code %in% codes, + select = c(cols, "pccc_v3.0") +) -subset(get_elixhauser_codes(), - subset = full_code %in% c("C78.4", "I50.40") & elixhauser_ahrq2025 == 1L, - select = c("icdv", "dx", "code", "full_code", "condition", "elixhauser_ahrq2025")) +subset( + get_charlson_codes(), + subset = full_code %in% codes, + select = c(cols, "charlson_quan2011") +) + +subset( + get_elixhauser_codes(), + subset = full_code %in% codes & elixhauser_ahrq2025 == 1L, + select = c(cols, "elixhauser_ahrq2025") +) record <- -data.table::fread(text = " -patid | encid | code | poa -A | 1 | NA | NA -A | 2 | C78.4 | 0 -A | 3 | I50.40 | 1 -A | 4 | NA | NA -A | 5 | C78.4 | 1 -A | 5 | I50.40 | 0 -A | 6 | NA | NA -") + structure( + list( + patid = c("A", "A", "A", "A", "A", "A", "A"), + encid = c(1L, 2L, 3L, 4L, 5L, 5L, 6L), + code = c(NA, "C78.4", "I50.40", NA, "C78.4", "I50.40", NA), + poa = c(NA, 0L, 1L, NA, 1L, 0L, NA)), + row.names = c(NA, -7L), + class = "data.frame" + ) ``` -We will call `comorbidities` for the three methods using static POA flags and -dynamic POA flags, and both flag methods. +We will call `comorbidities()` for the three methods using static POA flags and +dynamic POA flags, and both flag methods. Results are shown in the following +table. ```{r, include = FALSE} +data.table::setDT(record) args <- list(data = record, icd.codes = "code", @@ -283,6 +289,7 @@ tab <- rtn, row.names = FALSE, escape = FALSE, + align = rep("c", nrow(rtn)), caption = "Indicators for when a comorbidity is flagged based on the algorithm, present on admission (poa), and flag.method. The two ICD codes,C78.4 and I50.40, map to cancer and cardiovascular disease respectively." ) tab <- @@ -292,6 +299,8 @@ tab <- general = "C78.4 does not need to be POA to count for Elixhauser. I50.40 does need to be POA to count for Elixhauser." ) +tab <- kable_styling(tab, bootstrap_options = c("striped", "bordered"), full_width = FALSE, font_size = 8) +#tab <- scroll_box(tab, height = "600px") tab <- pack_rows(tab, "flag.method = 'current'", 1L, 6L) tab <- pack_rows(tab, "flag.method = 'cumulative'", 7L, 12L) tab <- add_header_above(tab, c(" " = 2L, rep(c("PCCC" = 2L, "Charlson" = 2L, "Elixhauser" = 2L), 3L))) diff --git a/vignettes/elixhauser.Rmd b/vignettes/elixhauser.Rmd index aca3444f..ace75c7d 100644 --- a/vignettes/elixhauser.Rmd +++ b/vignettes/elixhauser.Rmd @@ -129,7 +129,7 @@ tables. summary(mdcr_results) ``` -```{r, results = "asis"} +```{r echo = FALSE, results = "asis"} x <- summary(mdcr_results)$conditions tab <- kableExtra::kbl( @@ -139,7 +139,8 @@ tab <- col.names = c("", "Count", "Percentage"), digits = 3 ) -tab <- kableExtra::pack_rows(tab, group_label = "Comorbidity", start_row = 1, end_row = 39) +tab <- kableExtra::kable_styling(tab, bootstrap_options = c("striped"), font_size = 10) +tab <- kableExtra::pack_rows(tab, group_label = "Comorbidity", start_row = 1, end_row = 38) tab <- kableExtra::pack_rows(tab, group_label = "Total Comorbidities", start_row = 39, end_row = nrow(x)) tab ``` diff --git a/vignettes/icd.Rmd b/vignettes/icd.Rmd index a9be4bf9..940ad6fa 100644 --- a/vignettes/icd.Rmd +++ b/vignettes/icd.Rmd @@ -36,9 +36,6 @@ Centers for Disease Control (CDC) and from the Centers for Medicare & Medicaid Services (CMS). The specific links to the source data sets can be found in the source code for the `medicalcoder` package on [GitHub](https://github.com/dewittpe/medicalcoder). -```{r label = "medicalcoder-url"} -cat(packageDescription('medicalcoder')$URL) -``` End users can get a `data.frame` with ICD-9 diagnostic, ICD-9 procedure, ICD-10 diagnostic, and ICD-10 procedure codes. @@ -96,6 +93,8 @@ d4 * `assignable_end`: The last year the code was assignable. +## with.descriptions + To get the descriptions of the ICD codes call `get_icd_codes()` with `with.descriptions = TRUE`. ```{r, label = "icd-codes-with-descriptions"} @@ -108,28 +107,49 @@ The return has the additional columns: * `desc_end`: the last fiscal_year that the description was documented Over time the descriptions for some ICD codes were modified within sources. -There are also many differences between sources. The table below has several +There are also many differences between sources. The tables below have several examples. ```{r, label = "deltas-in-desc", results = "hide"} delta_in_desc <- - subset(get_icd_codes(with.descriptions = TRUE), - subset = full_code %in% c("Z88.7", "010.93", "V76.49"), - select = c("full_code", "src", "desc", "desc_start", "desc_end")) + subset( + get_icd_codes(with.descriptions = TRUE), + subset = full_code %in% c("Z88.7", "010.93", "V76.49"), + select = c("full_code", "src", "desc", "desc_start", "desc_end") + ) ``` -```{r, label = "deltas-in-desc-show", echo = FALSE, results = "asis"} -knitr::kable(delta_in_desc, row.names = FALSE) +The only difference in the description for 010.93 is a comma. + +```{r, label = "deltas-in-desc-show-010.93", echo = FALSE, results = "asis"} +knitr::kable( + subset(delta_in_desc, subset = full_code == "010.93"), + row.names = FALSE +) ``` -* Z88.7 has differences in the description over time within `cms` source and - between `cms` and `who`. +ICD-10-CM Z88.7 has differences in the description over time within `cms` source +and between `cms` and `who`. -* The only difference in the description for 010.93 is a comma. +```{r, label = "deltas-in-desc-show-Z88.7", echo = FALSE, results = "asis"} +knitr::kable( + subset(delta_in_desc, subset = full_code == "Z88.7"), + row.names = FALSE +) +``` + +ICD-9-CM V79.49 had the description of 'other' which would require exploration +of the header codes to understand. Even when the most verbose description may +still require consideration of the header codes to fullye understand. + +```{r, label = "deltas-in-desc-show-v79.49", echo = FALSE, results = "asis"} +knitr::kable( + subset(delta_in_desc, subset = full_code == "V76.49"), + row.names = FALSE +) +``` -* ICD-9-CM V79.49 had the description of 'other' which would require exploration - of the header codes to understand. Even when the most verbose description may - still require consideration of the header codes to fully understand. +## with.hierarchy Lastly, the `get_icd_codes()` function includes the argument `with.hierarchy` which will provide additional details for the codes. diff --git a/vignettes/pccc.Rmd b/vignettes/pccc.Rmd index 524905eb..4dd8f257 100644 --- a/vignettes/pccc.Rmd +++ b/vignettes/pccc.Rmd @@ -28,7 +28,6 @@ knitr::opts_chunk$set(collapse = TRUE, fig.align = "center") ```{r, label = 'medicalcoder-namespace'} library(medicalcoder) -packageVersion("medicalcoder") ``` # Introduction @@ -44,9 +43,14 @@ data.table::setDT(CNDS) data.table::setkey(CNDS, condition) CNDS <- unique(CNDS) -kbl(CNDS, +tab <- + kbl( + CNDS, caption = "Syntactically valid names for complex chronic conditions", - row.names = TRUE) + row.names = TRUE + ) +tab <- kable_styling(tab, bootstrap_options = c("striped"), full_width = FALSE, font_size = 10) +tab ``` The PCCC system provides a standardized approach to identifying children with @@ -124,9 +128,11 @@ Example: Consider a patient with following four diagnostic and two procedure ICD-9 codes: ```{r, label = "define-pat1"} pat1 <- - data.frame(dx = c(1, 1, 1, 1, 0, 0), - icdv = 9L, - code = c("34590", "78065", "3432", "78065", "9929", "8606")) + data.frame( + dx = c(1, 1, 1, 1, 0, 0), + icdv = 9L, + code = c("34590", "78065", "3432", "78065", "9929", "8606") + ) ``` An inner join between the `pccc_codes` and `pat1` will yield the conditions @@ -146,28 +152,28 @@ device and technology use. ```{r, label = "pat1-pccc-v2"} pat1_pccc_v2.0 <- comorbidities( - data = pat1, - icd.codes = "code", - dx.var = "dx", - icdv = 9, - method = "pccc_v2.0", - flag.method = "current", # default - poa = 1 # default for flag.method = 'current' + data = pat1, + icd.codes = "code", + dx.var = "dx", + icdv = 9, + method = "pccc_v2.0", + flag.method = "current", # default + poa = 1 # default for flag.method = 'current' ) pat1_pccc_v2.1 <- comorbidities( - data = pat1, - icd.codes = "code", - dx.var = "dx", - icdv = 9, - method = "pccc_v2.1", - flag.method = "current", - poa = 1 + data = pat1, + icd.codes = "code", + dx.var = "dx", + icdv = 9, + method = "pccc_v2.1", + flag.method = "current", + poa = 1 ) all.equal(pat1_pccc_v2.0, pat1_pccc_v2.1, check.attributes = FALSE) -pat1_pccc_v2.0 +pat1_pccc_v2.1 ``` Under version 3 of the PCCC, this patient has two conditions: neuromuscular and @@ -176,23 +182,25 @@ not counted in the total number of conditions. ```{r, label = "pat1-pccc-v3"} pat1_pccc_v3.0 <- - comorbidities(data = pat1, - icd.codes = "code", - dx.var = "dx", - icdv = 9, - method = "pccc_v3.0", - flag.method = 'current', - poa = 1 + comorbidities( + data = pat1, + icd.codes = "code", + dx.var = "dx", + icdv = 9, + method = "pccc_v3.0", + flag.method = 'current', + poa = 1 ) pat1_pccc_v3.1 <- - comorbidities(data = pat1, - icd.codes = "code", - dx.var = "dx", - icdv = 9, - method = "pccc_v3.1", - flag.method = 'current', - poa = 1 + comorbidities( + data = pat1, + icd.codes = "code", + dx.var = "dx", + icdv = 9, + method = "pccc_v3.1", + flag.method = 'current', + poa = 1 ) all.equal(pat1_pccc_v3.0, pat1_pccc_v3.1, check.attributes = FALSE) @@ -227,16 +235,28 @@ possible sets. In the case of no conditions, only the `_dxpr_and_tech` columns set to `NA`. When at least one condition is flagged, all the columns will be populated as 0/1. - | `cmrb_flag` | `num_cmrb` | `_dxpr_or_tech` | `_dxpr_only` | `_tech_only | _dxpr_and_tech | _dxpr_or_tech` | - | :---: | :---: | :---: | :---: | :---: | :---: | :---: | - | 0 | 0 | 0 | 0 | 0 | 0 | 0 | - | 1 | 1 | 0 | 0 | 0 | 0 | 1 | - | 1 | 1 | 1 | 1 | 0 | 0 | 0 | - | 1 | 1 | 1 | 1 | 1 | 1 | 0 | - | 1 | >1 | 0 | 0 | 0 | 0 | 1 | - | 1 | >1 | 1 | 0 | 1 | 0 | 1 | - | 1 | >1 | 1 | 1 | 0 | 0 | 1 | - | 1 | >1 | 1 | 1 | 1 | 1 | 1 | +```{r, echo = FALSE, results = "asis"} +tab <- data.table::fread(colClass = character(), text = " +cmrb_flag | num_cmrb | _dxpr_or_tech | _dxpr_only | _tech_only | _dxpr_and_tech | _dxpr_or_tech +0 | 0 | 0 | 0 | 0 | 0 | 0 +1 | 1 | 0 | 0 | 0 | 0 | 1 +1 | 1 | 1 | 1 | 0 | 0 | 0 +1 | 1 | 1 | 1 | 1 | 1 | 0 +1 | >1 | 0 | 0 | 0 | 0 | 1 +1 | >1 | 1 | 0 | 1 | 0 | 1 +1 | >1 | 1 | 1 | 0 | 0 | 1 +1 | >1 | 1 | 1 | 1 | 1 | 1 ") + +tab <- + kbl( + x = tab, + align = rep("c", ncol(tab)), + col.names = c("cmrb flag", "num cmrb", "_dxpr_or_tech", "_dxpr_only", "_tech_only", "_dxpr_and_tech", "_dxpr_or_tech") + ) +tab <- kable_styling(tab, bootstrap_options = c("striped"), font_size = 10) +tab <- add_header_above(tab, c("", "", "" = 4, "" = 1)) +tab +``` Now, consider another patient, pat2, with the same codes as pat1 except for 3432, the code mapping to a neuromuscular condition. @@ -263,6 +283,7 @@ Filter(f = function(x) x > 0, pat2_pccc_v2.1) Under version 3 of the PCCC, this patient will have no conditions. This is because no condition was identified based on non-technology dependent codes and thus the one technology dependent code is ignored. + ```{r, label = "pat2-pccc-v3"} pat2_pccc_v3.1 <- comorbidities( @@ -302,38 +323,49 @@ head(mdcr) str(mdcr) ``` -Applying `pccc_v2.1` and `pccc_v3.1` methods to `mdcr` could be as simple as: +# Assessing PCCC + +## Ignoring ICD Version and diagnostic/procedure codes + +Applying `pccc_v2.1` and `pccc_v3.1` methods to `mdcr` without accounting for +ICD version or the diagnostic/procedure status of the code can be done as follows: + ```{r, label = "mdcr-results-01"} mdcr_results_v2.1_01 <- - comorbidities(data = mdcr, - icd.codes = "code", - id.vars = "patid", - poa = 1, - flag.method = 'current', - method = "pccc_v2.1") + comorbidities( + data = mdcr, + icd.codes = "code", + id.vars = "patid", + poa = 1, + flag.method = 'current', + method = "pccc_v2.1" + ) mdcr_results_v3.1_01 <- - comorbidities(data = mdcr, - icd.codes = "code", - id.vars = "patid", - poa = 1, - flag.method = 'current', - method = "pccc_v3.1") -``` -and a useful summary of the object returned from `comorbidities` is gained by -calling `summary()`. The return is a `data.table` with columns for the count + comorbidities( + data = mdcr, + icd.codes = "code", + id.vars = "patid", + poa = 1, + flag.method = 'current', + method = "pccc_v3.1" + ) +``` + +A useful summary of the object returned from `comorbidities()` is gained by +calling `summary()`. The return is a `data.frame` with columns for the count and percentages. For `pccc_v2.0` and `pccc_v2.1` the condition, label, count, and percentage, are reported. For `pccc_v3.0` and `pccc_v3.1` the columns are -extended to provide the counts and percentages for `dxpr_or_tech`, `dxpr_only`, -`tech_only`, and `dxpr_and_tech`. +extended to provide the counts and percentages for `_dxpr_or_tech`, `_dxpr_only`, +`_tech_only`, and `_dxpr_and_tech`. ```{r, label = "comorbidities-summary-table-str"} str(summary(mdcr_results_v2.1_01)) str(summary(mdcr_results_v3.1_01)) ``` -The summary tables are `data.frame`s and can be manipulated by the end user for -reporting as they want, see the following table. +Since the summary tables are `data.frame`s the end user may manipulate the +results for reporting as they want, see the following table. ```{r, label = "mdcr-results-01-summary"} x <- @@ -355,6 +387,8 @@ tab <- col.names = c("", rep(c("count", "%"), times = 5)), caption = "Summary Table for `mdcr_results_v2.1_01` and `mdcr_results_v3.1_01`." ) +tab <- + kableExtra::kable_styling(tab, bootstrap_options = c("striped"), font_size = 10) tab <- kableExtra::pack_rows(tab, group_label = c("Conditions"), start_row = 1, end_row = 11) tab <- @@ -368,6 +402,8 @@ tab <- tab ``` +## Accounting for Diagnostic/Procedure + There are additional details we should consider with respect to the ICD codes. The ICD version, 9 or 10, and if the code is a diagnostic or a procedure code. For example, code ICD-9 diagnostic code 332.1 has the same compact code as ICD-9 @@ -383,6 +419,7 @@ table(mdcr[mdcr$code == "3321", "dx"]) To account for the diagnostic or procedure status of the codes specify a value for the `dx.var` argument. + ```{r, label = "mdcr-results-02"} mdcr_results_v2.1_02 <- comorbidities( @@ -485,14 +522,17 @@ lookup table. By not accounting for diagnostic and procedure codes, the overlaps between the two coding structures can lead to false positives. ```{r} -merge(x = subset(mdcr, patid == "87420"), - y = pccc_codes, - by.x = c("code"), - by.y = c("code"), - suffixes = c(".mdcr", ".pccc_codes") +merge( + x = subset(mdcr, patid == "87420"), + y = pccc_codes, + by.x = c("code"), + by.y = c("code"), + suffixes = c(".mdcr", ".pccc_codes") ) ``` +## Full and Compact ICD codes + Using full codes can prevent false positives too. Here are several different ways that `comorbidities()` could be called resulting in different outcomes. @@ -500,9 +540,12 @@ Note: this is a good example of how `medicalcoder` can handle full and compact codes within a single record. ```{r} -DF <- data.frame(id = c("full dx", "full pr", "compact dx", "compact pr"), - code = c("564.1", "56.41", "5641", "5641"), - dx = c(1, 0, 1, 0)) +DF <- + data.frame( + id = c("full dx", "full pr", "compact dx", "compact pr"), + code = c("564.1", "56.41", "5641", "5641"), + dx = c(1, 0, 1, 0) + ) # ideal: using the dx/pr status and matching on full and compact codes. comorbidities( @@ -558,6 +601,8 @@ comorbidities( )[, c("id", "cmrb_flag", "renal_dxpr_or_tech")] ``` +## Accounting for ICD Version + Another consideration is the version of ICD, 9 or 10. The record for patid 95471 is a great example of the problem that a compact code @@ -662,6 +707,8 @@ when the ICD code was reported. head(mdcr_longitudinal) ``` +## PCCC V2 + Let's look at the `pccc_v2.1` flags for each patient, using all the information from all the encounters. This can easily by done by specifying `id.vars = c("patid")` such that the `comorbidities` method considers call codes as @@ -669,33 +716,43 @@ occurring on one encounter. ```{r, results = 'asis'} longitudinal_v2_patid <- - comorbidities(data = mdcr_longitudinal, - icd.codes = "code", - id.vars = c("patid"), - icdv.var = "icdv", - method = "pccc_v2.1", - flag.method = "current", - poa = 1 + comorbidities( + data = mdcr_longitudinal, + icd.codes = "code", + id.vars = c("patid"), + icdv.var = "icdv", + method = "pccc_v2.1", + flag.method = "current", + poa = 1 ) -kableExtra::kbl(longitudinal_v2_patid) +tab <- kableExtra::kbl(longitudinal_v2_patid) +tab <- kableExtra::kable_styling(tab, bootstrap_options = c("striped"), font_size = 10) +tab ``` We can look at the conditions flagged at each encounter by specifying the `id.vars = c("patid", "date")`. -```{r, results = 'asis'} +```{r} longitudinal_v2_patid_date <- comorbidities(data = mdcr_longitudinal, - icd.codes = "code", - id.vars = c("patid", "date"), - icdv.var = "icdv", - method = "pccc_v2.1", - flag.method = "current", - poa = 1) -kableExtra::kbl( - subset(longitudinal_v2_patid_date, patid == "9663901"), - row.names = FALSE -) + icd.codes = "code", + id.vars = c("patid", "date"), + icdv.var = "icdv", + method = "pccc_v2.1", + flag.method = "current", + poa = 1 + ) +``` + +```{r, echo = FALSE, results = 'asis'} +tab <- + kableExtra::kbl( + subset(longitudinal_v2_patid_date, patid == "9663901"), + row.names = FALSE + ) +tab <- kableExtra::kable_styling(tab, bootstrap_options = c("striped"), font_size = 10) +tab ``` Looking at patid 9663901 at an encounter level we see that the conditions occur @@ -718,14 +775,19 @@ longitudinal_v2_patid_date_cumulative_poa0 <- flag.method = "cumulative", poa = 0 ) +``` -kableExtra::kbl( - subset(longitudinal_v2_patid_date_cumulative_poa0, patid == "9663901"), - row.names = FALSE -) +```{r, echo = FALSE, results = 'asis'} +tab <- + kableExtra::kbl( + subset(longitudinal_v2_patid_date_cumulative_poa0, patid == "9663901"), + row.names = FALSE + ) +tab <- kableExtra::kable_styling(tab, bootstrap_options = c("striped"), font_size = 10) +tab ``` -```{r, results="asis"} +```{r} longitudinal_v2_patid_date_cumulative_poa1 <- comorbidities( data = mdcr_longitudinal, @@ -736,12 +798,20 @@ longitudinal_v2_patid_date_cumulative_poa1 <- flag.method = "cumulative", poa = 1 ) -kableExtra::kbl( - subset(longitudinal_v2_patid_date_cumulative_poa1, patid == "9663901"), - row.names = FALSE -) ``` +```{r, echo = FALSE, results = 'asis'} +tab <- + kableExtra::kbl( + subset(longitudinal_v2_patid_date_cumulative_poa1, patid == "9663901"), + row.names = FALSE + ) +tab <- kableExtra::kable_styling(tab, bootstrap_options = c("striped"), font_size = 10) +tab +``` + +## PCCC V3 + For `pccc_v3.0` and `pccc_v3.1` a simple carry-forward method would not be easy to use as information about technology dependent codes is omitted when non-technology dependent codes do not exist. @@ -751,6 +821,7 @@ all six possible permutations of the codes. We'll generate a data set with seven encounters and one code appearing on each of encounters 2, 4, and 6. The codes we'll use are: + * H49.811: metabolic (other metabolic disorders), * J84.111: respiratory (chronic respiratory diseases), and * Z96.41: metabolic (device and technology use). @@ -759,7 +830,9 @@ The codes we'll use are: codes <- c("H49.811", "J84.111", "Z96.41") subset(get_pccc_codes(), full_code %in% codes) ``` + The constructed data and permutations are: + ```{r} permutations <- data.table::data.table( @@ -785,6 +858,7 @@ cat(paste("*", permutations[, unique(plabel)]), sep = "\n") We'll apply the `pccc_v3.1` to this code set with `flag.method = "cumulative"` and all codes considered to be present-on-admission. + ```{r} rtn <- comorbidities( @@ -830,6 +904,7 @@ pkbl <- function(permutation = 1) { x, col.names = c("encounter_id", rep(c("dxpr or tech", "dxpr only", "tech only", "dxpr and tech"), times = 2), "ccc flag", "num ccc") ) + tab <- kableExtra::kable_styling(kable_input = tab, bootstrap_options = c("striped"), font_size = 10) tab <- kableExtra::add_header_above(kable_input = tab, header = c("", c("Metabolic" = 4, "Respiratory" = 4), "", "")) tab <- kableExtra::add_header_above(kable_input = tab, header = c("", setNames(10, pl))) tab @@ -918,7 +993,7 @@ implemented flagging for the subconditions. The subconditions for each condition are shown in the next table. -```{r, label = "tbl-syntactically-valid-subconditions", echo = FALSE, results="asis"} +```{r "tbl-syntactically-valid-subconditions", echo = FALSE, results = "asis"} SCNDS <- get_pccc_conditions() data.table::setDT(SCNDS) data.table::setkey(SCNDS, condition, subcondition) @@ -931,6 +1006,10 @@ tab <- ) tab <- kableExtra::pack_rows(tab, index = table(SCNDS$condition)) +tab <- + kableExtra::kable_styling(tab, bootstrap_options = c('striped'), fixed_thead = TRUE, font_size = 10) +tab <- + kableExtra::scroll_box(tab, height = "300px") tab ``` @@ -971,9 +1050,11 @@ of calling `comorbidities()` with `subconditions = FALSE`. ```{r} with_subconditions -all.equal(with_subconditions$conditions, - without_subconditions, - check.attributes = FALSE) +all.equal( + with_subconditions$conditions, + without_subconditions, + check.attributes = FALSE +) ``` The second element of `with_subconditions` is list of `data.frame`s, one for @@ -983,15 +1064,13 @@ A quick and easy way to get a summary of the subconditions is to call `summary()`. ```{r} -str( - summary(with_subconditions) -) +str(summary(with_subconditions)) ``` The subconditions are available for all pccc variants. A summary is presented -in the following table. +in the following tables. -```{r, include = FALSE} +```{r include = FALSE} args <- list( data = mdcr, @@ -1008,7 +1087,7 @@ with_subconditions_v3.0 <- do.call(comorbidities, c(args, list(method = "pccc_v3 with_subconditions_v3.1 <- do.call(comorbidities, c(args, list(method = "pccc_v3.1"))) ``` -```{r, echo = FALSE, results = "asis"} +```{r include = FALSE} rslts <- merge( merge( @@ -1047,40 +1126,106 @@ rslts$lab <- rslts$subcondition_label rslts$lab[is.na(rslts$subcondition)] <- rslts$condition_label[is.na(rslts$subcondition)] rslts <- rslts[order(rslts$idx), ] -tab <- - rslts[, - c( - "lab", - "count_v2.0", - "percent_of_cohort_v2.0", - "percent_of_those_with_condition_v2.0", - "count_v2.1", - "percent_of_cohort_v2.1", - "percent_of_those_with_condition_v2.1", - "count_v3.0", - "percent_of_cohort_v3.0", - "percent_of_those_with_condition_v3.0", - "count_v3.1", - "percent_of_cohort_v3.1", - "percent_of_those_with_condition_v3.1" - ) - ] +rslts <- split(rslts, f = rslts[["condition"]]) + +cols_to_keep <- + c( + "lab", + "count_v2.0", + "percent_of_cohort_v2.0", + "percent_of_those_with_condition_v2.0", + "count_v2.1", + "percent_of_cohort_v2.1", + "percent_of_those_with_condition_v2.1", + "count_v3.0", + "percent_of_cohort_v3.0", + "percent_of_those_with_condition_v3.0", + "count_v3.1", + "percent_of_cohort_v3.1", + "percent_of_those_with_condition_v3.1" + ) -tab <- - kableExtra::kbl( - tab, +tabs <- lapply(rslts, function(x) {x[, cols_to_keep]}) + +tabs <- + lapply(tabs, + kableExtra::kbl, col.names = c("", rep(c("count", "% of cohort", "% of those with condition"), 4)), row.names = FALSE, digits = 1 ) -tab <- kableExtra::column_spec(tab, column = 1, bold = is.na(rslts$subcondition)) -tab <- kableExtra::kable_styling(tab, "striped") -tab <- kableExtra::add_indent(tab, which(!is.na(rslts$subcondition))) -tab <- kableExtra::add_header_above(tab, c("", "v2.0" = 3, "v2.1" = 3, "v3.0" = 3, "v3.1" = 3)) +tabs <- + Map( + f = function(t,r) { + x <- kableExtra::column_spec(t, column = 1, bold = is.na(r$subcondition)) + kableExtra::add_indent(x, which(!is.na(r$subcondition))) + }, + t = tabs, + r = rslts + ) +tabs <- + lapply(tabs, kableExtra::kable_styling, bootstrap_options = "striped", font_size = 10) +tabs <- + lapply(tabs, kableExtra::add_header_above, header = c("", "v2.0" = 3, "v2.1" = 3, "v3.0" = 3, "v3.1" = 3)) +tabs +``` -tab +## Congenital or Genetic +```{r echo = FALSE, results = "asis"} +tabs[["congeni_genetic"]] +``` + +## Cardiovascular +```{r echo = FALSE, results = "asis"} +tabs[["cvd"]] +``` + +## Gastrointestinal +```{r echo = FALSE, results = "asis"} +tabs[["gi"]] +``` + +## Hematologic +```{r echo = FALSE, results = "asis"} +tabs[["hemato_immu"]] ``` +## Malignancy +```{r echo = FALSE, results = "asis"} +tabs[["malignancy"]] +``` + +## Metabolic +```{r echo = FALSE, results = "asis"} +tabs[["metabolic"]] +``` + +## Miscellaneous +```{r echo = FALSE, results = "asis"} +tabs[["misc"]] +``` + +## Neonatal +```{r echo = FALSE, results = "asis"} +tabs[["neonatal"]] +``` + +## Neuromuscular +```{r echo = FALSE, results = "asis"} +tabs[["neuromusc"]] +``` + +## Renal +```{r echo = FALSE, results = "asis"} +tabs[["renal"]] +``` + +## Respiratory +```{r echo = FALSE, results = "asis"} +tabs[["respiratory"]] +``` + +## Longitudinal The longitudinal assessment for subconditions work as well. Using the same `permutations` data set from above we will look at the metabolic and respiratory conditions and subconditions. @@ -1099,6 +1244,7 @@ rslts <- subconditions = TRUE ) ``` + Let's start by looking at the respiratory results. The only subcondition that should be, and is, flagged is chronic respiratory diseases. A reminder: the `data.frame` for a subcondition only report rows for when the primary condition @@ -1127,6 +1273,7 @@ scnd <- by = .(plabel) ] ``` + ```{r, echo = FALSE, results = "asis"} tab <- kableExtra::kbl( @@ -1134,6 +1281,7 @@ tab <- caption = "Encounters flagging for respiratory condition and the chronic respiratory disease subcondition.", col.names = c("", "Condition", "Subcondition") ) +tab <- kableExtra::kable_styling(tab, bootstrap_options = c("striped"), font_size = 10) tab <- kableExtra::add_header_above(tab, c("", "Encounters" = 2)) tab ``` @@ -1182,12 +1330,12 @@ tab <- caption = "Encounters flagging for a metabolic condition and the encounters flagging for subconidtions device and technology use and/or other metabolic disorders.", col.names = c("", "Condition", "Device and Technology Use", "Other Metabolic Disorders") ) +tab <- kableExtra::kable_styling(tab, bootstrap_options = c("striped"), font_size = 10) tab <- kableExtra::add_header_above(tab, c("", "Encounters" = 3)) tab ``` - # References