diff --git a/NEWS.md b/NEWS.md index d39f3173..b4cc72b4 100644 --- a/NEWS.md +++ b/NEWS.md @@ -21,6 +21,10 @@ * Improve cumulative flagging to apply first-occurrence logic more effecently. +* Extend documentation for the expected default behavior between the + present-on-admission flags and `flag.method` argument in `comorbidities()` + (re: #28) + # medicalcoder 0.7.0 ## Bug Fixes diff --git a/R/comorbidities.R b/R/comorbidities.R index 69c19b55..ae3d6b5f 100644 --- a/R/comorbidities.R +++ b/R/comorbidities.R @@ -43,6 +43,18 @@ #' have better performance than using the date and will clear up any possible #' issues with non-sequential encounter ids from the source data. #' +#' **Cumulative + POA defaults:** +#' +#' When `flag.method = "cumulative"` and neither +#' `poa` nor `poa.var` is supplied, the first encounter for a condition is +#' treated as `poa = 0`. Subsequent encounters for that condition are flagged as +#' `poa = 1`. +#' +#' When `flag.method = "current"` and neither `poa` nor `poa.var` is supplied, +#' then all codes will be considered present-on-admission. If poa was assumed +#' to be 0, then in this case the only conditions that could be flagged are the +#' Elixhauser conditions which are poa-exempt. +#' #' @return #' #' The return object will be slightly different depending on the value of @@ -552,7 +564,10 @@ comorbidities.data.frame <- function(data, cmrb <- do.call(rbind, foc) - # set poa to 1 and primarydx to 0 for prior conditions + # Carry condition forward after first occurrence: set poa to 1 and + # primarydx to 0 on later encounters so downstream POA filtering keeps + # all post-first-occurrence rows and the first-occurrence row only if poa = + # 1 (via poa.var or poa) for the first-occurrence idx <- cmrb[[encid]] > cmrb[["first_occurrance"]] cmrb[[poa.var]][idx] <- 1L if (!is.null(primarydx.var)) { diff --git a/man/comorbidities.Rd b/man/comorbidities.Rd index 28867701..f890bb50 100644 --- a/man/comorbidities.Rd +++ b/man/comorbidities.Rd @@ -192,6 +192,18 @@ correctly stored. Adding a column \code{enc_seq}, e.g.,\tabular{cccc}{ and calling \code{comorbidities()} with \code{id.vars = c("patid", "enc_seq")} will have better performance than using the date and will clear up any possible issues with non-sequential encounter ids from the source data. + +\strong{Cumulative + POA defaults:} + +When \code{flag.method = "cumulative"} and neither +\code{poa} nor \code{poa.var} is supplied, the first encounter for a condition is +treated as \code{poa = 0}. Subsequent encounters for that condition are flagged as +\code{poa = 1}. + +When \code{flag.method = "current"} and neither \code{poa} nor \code{poa.var} is supplied, +then all codes will be considered present-on-admission. If poa was assumed +to be 0, then in this case the only conditions that could be flagged are the +Elixhauser conditions which are poa-exempt. } \examples{ pccc_v3.1_results <- diff --git a/tests/test-poa-in-cumulative.R b/tests/test-poa-in-cumulative.R new file mode 100644 index 00000000..fb08ba89 --- /dev/null +++ b/tests/test-poa-in-cumulative.R @@ -0,0 +1,53 @@ +library(medicalcoder) + +# Verifies cumulative flagging behavior for Charlson when poa/poa.var is omitted. +# Expected default: first encounter for a condition is NOT flagged (poa defaults +# to 0), but the condition carries forward and is flagged on later encounters +# (poa set to 1 after first occurrence). Explicit poa = 1 should flag all +# encounters. + +df <- data.frame( + patid = c(1L, 1L), + enc = c(1L, 2L), + icdv = c(10L, 10L), + dx = c(1L, 1L), + code = c("I252", "I252"), + stringsAsFactors = FALSE +) + +# Baseline: explicit poa = 1 flags the condition under cumulative logic +explicit_poa <- comorbidities( + data = df, + icd.codes = "code", + id.vars = c("patid", "enc"), + icdv.var = "icdv", + dx.var = "dx", + method = "charlson_quan2011", + flag.method = "cumulative", + poa = 1L, + primarydx = 0L +) + +stopifnot(any(explicit_poa[["cmrb_flag"]])) +stopifnot( + explicit_poa$cmrb_flag[explicit_poa$enc == 1L] == 1L, + explicit_poa$cmrb_flag[explicit_poa$enc == 2L] == 1L +) + +# Without specifying poa/poa.var, encounter 1 should remain unflagged and +# encounter 2 should be flagged. +default_poa <- comorbidities( + data = df, + icd.codes = "code", + id.vars = c("patid", "enc"), + icdv.var = "icdv", + dx.var = "dx", + method = "charlson_quan2011", + flag.method = "cumulative", + primarydx = 0L +) + +stopifnot( + default_poa$cmrb_flag[default_poa$enc == 1L] == 0L, + default_poa$cmrb_flag[default_poa$enc == 2L] == 1L +) diff --git a/vignettes/comorbidities.Rmd b/vignettes/comorbidities.Rmd index 0c3180f0..64188f4a 100644 --- a/vignettes/comorbidities.Rmd +++ b/vignettes/comorbidities.Rmd @@ -304,6 +304,14 @@ tab <- add_header_above(tab, c(" " = 2L, c("POA = 0" = 6L, "POA = 1" = 6L, "poa. tab ``` +### Flag method and POA defaults + +When `flag.method = "cumulative"` and you do *not* supply `poa` or `poa.var`, +`comorbidities()` treats the first encounter where a condition appears as +`poa = 0` and carries that condition forward with `poa = 1` on later encounters. + +When `flag.method = "current"` and you do *not* supply `poa` or `poa.var`, +`comorbidities()` treates all ICD codes as `poa = 1`. # Mapping ICD Codes to Comorbidities