From 2cb4e3c019767665eaba52161085ee6a9d45c046 Mon Sep 17 00:00:00 2001 From: Andrew Bruce Date: Fri, 28 Jun 2024 16:33:45 -0700 Subject: [PATCH] feat: construct_regex --- DESCRIPTION | 2 + NAMESPACE | 2 + R/standards.R | 6 ++- R/utils.R | 66 +++++++++++++++++++++++++++++ man/chr.Rd | 15 +++++++ man/construct_regex.Rd | 22 ++++++++++ man/search_descriptions.Rd | 6 ++- vignettes/articles/columns.Rmd | 12 +++--- vignettes/northstar.Rmd | 76 +++++++++++++++++++++++++++++++--- 9 files changed, 192 insertions(+), 15 deletions(-) create mode 100644 man/chr.Rd create mode 100644 man/construct_regex.Rd diff --git a/DESCRIPTION b/DESCRIPTION index 57a58bd..469e4c9 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -13,12 +13,14 @@ Depends: R (>= 4.1.0) Imports: cli, + collapse, dplyr, fs, kit, pins, purrr, rlang, + strex, stringfish, stringr, tidyr, diff --git a/NAMESPACE b/NAMESPACE index 7e4ea55..7aef8f4 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -4,6 +4,8 @@ S3method(print,northstar) export(assign_adjustments) export(calculate_amounts) export(carc_add_dash) +export(chr) +export(construct_regex) export(data_dict) export(get_example) export(get_pin) diff --git a/R/standards.R b/R/standards.R index bb28d41..34d343b 100644 --- a/R/standards.R +++ b/R/standards.R @@ -17,10 +17,12 @@ #' search_descriptions(hcpcs_code = c("39503", "43116", "33935", "11646")) #' #' search_descriptions( -#' hcpcs_code = dplyr::tibble(code = c("A0021", "V5362", "J9264", "G8916")), +#' hcpcs_code = dplyr::tibble( +#' code = c("A0021", "V5362", "J9264", "G8916")), #' column = "code") #' -#' dplyr::tibble(code = c("A0021", "V5362", "J9264", "G8916")) |> +#' dplyr::tibble( +#' code = c("A0021", "V5362", "J9264", "G8916")) |> #' search_descriptions(column = "code") #' #' @autoglobal diff --git a/R/utils.R b/R/utils.R index 86f072b..6c928d1 100644 --- a/R/utils.R +++ b/R/utils.R @@ -76,6 +76,72 @@ get_example <- function(name = c("report", "practicum")) { } +#' Alias for `as.character()` +#' +#' @param ... arguments to pass to `as.character()` +#' +#' @keywords internal +#' +#' @export +chr <- function(...) { + as.character(...) +} + +#' Construct regex pattern for HCPCS codes +#' +#' @param x `` vector +#' +#' @examples +#' construct_regex(search_descriptions()$hcpcs_code) +#' +#' @returns `` vector +#' +#' @autoglobal +#' +#' @keywords internal +#' +#' @export +construct_regex <- function(x) { + + # TODO: check for equal lengths + + x <- collapse::funique( + collapse::na_rm( + gsub(" ", "", x))) + + x <- stringr::str_split(x, "") |> + purrr::list_transpose() |> + purrr::map(collapse::funique) |> + purrr::map(pos_re) |> + purrr::list_c() |> + paste0(collapse = "") + + paste0("^", x, "$") + +} + +#' Internal function for `construct_regex()` +#' +#' @param x `` vector +#' +#' @returns `` vector +#' +#' @autoglobal +#' +#' @noRd +pos_re <- function(x) { + + sorted <- stringr::str_sort(x, numeric = TRUE) + alphabet <- purrr::list_c(strex::str_extract_non_numerics(sorted)) + numbers <- purrr::list_c(strex::str_extract_numbers(sorted)) + + paste0("[", + fuimus::collapser(alphabet), + fuimus::collapser(numbers), + "]") + +} + #' Apply {gt} Theme #' #' @param gt_object `` A [gt][gt::gt-package] table object diff --git a/man/chr.Rd b/man/chr.Rd new file mode 100644 index 0000000..1360fdb --- /dev/null +++ b/man/chr.Rd @@ -0,0 +1,15 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/utils.R +\name{chr} +\alias{chr} +\title{Alias for \code{as.character()}} +\usage{ +chr(...) +} +\arguments{ +\item{...}{arguments to pass to \code{as.character()}} +} +\description{ +Alias for \code{as.character()} +} +\keyword{internal} diff --git a/man/construct_regex.Rd b/man/construct_regex.Rd new file mode 100644 index 0000000..8782318 --- /dev/null +++ b/man/construct_regex.Rd @@ -0,0 +1,22 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/utils.R +\name{construct_regex} +\alias{construct_regex} +\title{Construct regex pattern for HCPCS codes} +\usage{ +construct_regex(x) +} +\arguments{ +\item{x}{\verb{} vector} +} +\value{ +\verb{} vector +} +\description{ +Construct regex pattern for HCPCS codes +} +\examples{ +construct_regex(search_descriptions()$hcpcs_code) + +} +\keyword{internal} diff --git a/man/search_descriptions.Rd b/man/search_descriptions.Rd index 328d042..87abfd1 100644 --- a/man/search_descriptions.Rd +++ b/man/search_descriptions.Rd @@ -33,10 +33,12 @@ Describe HCPCS Codes search_descriptions(hcpcs_code = c("39503", "43116", "33935", "11646")) search_descriptions( - hcpcs_code = dplyr::tibble(code = c("A0021", "V5362", "J9264", "G8916")), + hcpcs_code = dplyr::tibble( + code = c("A0021", "V5362", "J9264", "G8916")), column = "code") -dplyr::tibble(code = c("A0021", "V5362", "J9264", "G8916")) |> +dplyr::tibble( + code = c("A0021", "V5362", "J9264", "G8916")) |> search_descriptions(column = "code") } diff --git a/vignettes/articles/columns.Rmd b/vignettes/articles/columns.Rmd index 449ceb1..45be500 100644 --- a/vignettes/articles/columns.Rmd +++ b/vignettes/articles/columns.Rmd @@ -159,8 +159,8 @@ This file contains the Geographic Practice Cost Index (GPCI) component for each ```{r echo=FALSE, eval=TRUE} search_gpcis() |> mutate( - counties = NULL, - area = glue::glue("{area}")) |> + # counties = NULL, + locality_name = glue::glue("{locality_name}")) |> distinct() |> gt(rowname_col = "mac", groupname_col = "state", @@ -170,13 +170,15 @@ search_gpcis() |> mac = "MAC", state = "State", locality = "", - area = "", + locality_name = "", gpci_work = md("**GPCI**wk"), gpci_pe = md("**GPCI**pe"), - gpci_mp = md("**GPCI**mp")) |> + gpci_mp = md("**GPCI**mp"), + gpci_gaf = md("**GPCI**gaf") + ) |> fmt_number(decimals = 2, drop_trailing_zeros = TRUE) |> - fmt_markdown(columns = "area") |> + fmt_markdown(columns = "locality_name") |> gt_theme_northstar(no_column_labels = FALSE) |> tab_style( style = cell_text( diff --git a/vignettes/northstar.Rmd b/vignettes/northstar.Rmd index 166bce5..a5fd5f4 100644 --- a/vignettes/northstar.Rmd +++ b/vignettes/northstar.Rmd @@ -24,31 +24,95 @@ library(fuimus) library(dplyr) library(tidyr) library(purrr) +library(collapse) +library(triebeard) +# library(pathologie) library(gt) ``` + + * Calculate Patient Age -> Check ICD/HCPCS for Age Conflicts + * Calculate Provider Lag -> Days between DOS and DOR + * Calculate Balance -> Charges - (Payments + Adjustments) + * Calculate Coinsurance -> Charges - Allowed + + + ## Load Example ```{r} -x <- get_example() - -x +(x <- get_example() |> + dplyr::filter(!hcpcs %in% c("WCPAIN", + "MATERIALCTR", + "MATERIALOFF", + "SPBARIATRIC", + "LETTER")) |> + dplyr::mutate( + # coinsurance = charges - allowed, + balance = charges - (payments + adjustments), + .after = adjustments)) ``` ## Place of Service ```{r} -search_pos(pos_code = x$pos) +pos_trie <- triebeard::trie( + keys = search_pos()$pos_code, + values = chr(search_pos()$pos_type)) + +x_pos <- x |> + dplyr::mutate( + pos_type = triebeard::longest_match(pos_trie, pos), + .after = pos) + +x_pos ``` ## Categorize HCPCS ```{r} -search_descriptions(hcpcs_code = x$hcpcs) +hcpcs_unq <- collapse::funique(x$hcpcs[!x$hcpcs %in% not_hcpcs]) + +search_rbcs(hcpcs_code = hcpcs_unq) |> + dplyr::select(hcpcs_code:rbcs_family) |> + dplyr::left_join( + search_descriptions(hcpcs_code = hcpcs_unq, + hcpcs_desc_type = "Long") |> + dplyr::select(hcpcs_code, hcpcs_description), + by = dplyr::join_by(hcpcs_code)) ``` +## Define Modifiers + ```{r} -search_rbcs(hcpcs_code = x$hcpcs) +mod_unq <- strsplit(toupper(x$mod[!is.na(x$mod)]), "-") |> + list_c() |> + funique() + +search_modifiers(mod_code = mod_unq) +``` + + + +```{r} +x |> + select( + claim_id, + dos, + order, + hcpcs + ) |> + group_by(claim_id) |> + filter(n() > 1) |> + ungroup() +``` + +```{r} +aocs <- search_aocs(hcpcs_code = hcpcs_unq) |> + tidyr::unnest(cols = aoc_complements) + +aocs |> + filter(aoc_type == "Primary") ```