diff --git a/DESCRIPTION b/DESCRIPTION index 2455f2ba..698b2833 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -3,8 +3,8 @@ Package: provider Title: Access Public Healthcare Provider Data Version: 0.0.1 Authors@R: - person("Andrew", "Bruce", , "andrew.bruce@northstarrevenueintegrity.com", role = c("aut", "cre", "cph")) -Maintainer: Andrew Bruce + person("Andrew", "Bruce", , "andrewallenbruce@gmail.com", role = c("aut", "cre", "cph")) +Maintainer: Andrew Bruce Description: Provides various features to facilitate easy access to publicly available healthcare provider data. Includes functions to tidy the data being accessed, whether for reporting purposes or @@ -75,7 +75,6 @@ Remotes: github::andrewallenbruce/fuimus, github::anthonynorth/roxyglobals, github::nt-williams/rxnorm, - github::rstudio/gt, github::yutannihilation/ggsflabel Config/roxyglobals/filename: generated-globals.R Config/roxyglobals/unique: TRUE @@ -86,4 +85,4 @@ Language: en-US LazyData: true Roxygen: list(markdown = TRUE, roclets = c("collate", "namespace", "rd", "roxyglobals::global_roclet")) -RoxygenNote: 7.3.1 +RoxygenNote: 7.3.2 diff --git a/NAMESPACE b/NAMESPACE index e3fb4d89..7474b7df 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -5,13 +5,10 @@ export(affiliations) export(bene_years) export(beneficiaries) export(betos) -export(cc_years) export(change) export(chg) export(clinicians) -export(compare_conditions) export(compare_hcpcs) -export(conditions) export(df2chr) export(display_long) export(duration_vec) diff --git a/R/cms.R b/R/cms.R index ee7b5ffa..07d747bc 100644 --- a/R/cms.R +++ b/R/cms.R @@ -1,12 +1,18 @@ #' Update CMS.gov API distribution IDs +#' #' @param api name of the api +#' #' @param check `"base"`, `"id"`, or `"years"`, default is `"id"` +#' #' @return A [tibble()] containing the updated ids. +#' #' @examplesIf interactive() #' cms_update("Provider of Services File - Clinical Laboratories", "base") #' cms_update("Provider of Services File - Clinical Laboratories", "id") #' cms_update("Provider of Services File - Clinical Laboratories", "years") +#' #' @autoglobal +#' #' @noRd cms_update <- function(api, check = "id") { @@ -239,8 +245,8 @@ api_years <- function(fn) { "rxp" ~ "Medicare Part D Prescribers - by Provider", "outps" ~ "Medicare Outpatient Hospitals - by Provider and Service", "outgs" ~ "Medicare Outpatient Hospitals - by Geography and Service", - "scc" ~ "Specific Chronic Conditions", - "mcc" ~ "Multiple Chronic Conditions", + # "scc" ~ "Specific Chronic Conditions", + # "mcc" ~ "Multiple Chronic Conditions", "qpp" ~ "Quality Payment Program Experience", .default = NULL) diff --git a/R/compare.R b/R/compare.R index a45018a1..f9bb711e 100644 --- a/R/compare.R +++ b/R/compare.R @@ -1,26 +1,15 @@ #' Compare Provider Performance #' -#' @description -#' -#' + `compare_hcpcs()` allows the user to compare a provider's yearly HCPCS +#' `compare_hcpcs()` allows the user to compare a provider's yearly HCPCS #' utilization data to state and national averages #' -#' + `compare_conditions()` allows the user to compare the average yearly -#' prevalence of chronic conditions among a provider's patient mix to state and -#' national averages -#' -#' @return A [tibble][tibble::tibble-package] containing: -#' + `compare_hcpcs()` -#' + `compare_conditions()` -#' @name compare -NULL - #' @param df < *tbl_df* > // **required** #' -#' [tibble()] returned from `utilization(type = "Service")` +#' [tibble][tibble::tibble-package] returned from `utilization(type = "Service")` #' -#' @examplesIf interactive() +#' @returns A [tibble][tibble::tibble-package] #' +#' @examplesIf interactive() #' compare_hcpcs(utilization(year = 2018, #' type = "Service", #' npi = 1023076643)) @@ -30,8 +19,8 @@ NULL #' type = "Service")) |> #' compare_hcpcs() #' -#' @rdname compare #' @autoglobal +#' #' @export compare_hcpcs <- function(df) { @@ -91,93 +80,3 @@ hcpcs_cols <- function(df) { df |> dplyr::select(dplyr::any_of(cols)) } - -#' @param df < *tbl_df* > // **required** [tibble()] returned from `utilization(type = "Provider")` -#' -#' @param pivot < *boolean* > // __default:__ `FALSE` Pivot output -#' -#' @rdname compare -#' -#' @examplesIf interactive() -#' -#' compare_conditions(utilization(year = 2018, -#' type = "Provider", -#' npi = 1023076643)) -#' -#' map_dfr(util_years(), ~utilization(year = .x, -#' npi = 1023076643, -#' type = "Provider")) |> -#' compare_conditions() -#' -#' @autoglobal -#' @export -compare_conditions <- function(df, pivot = FALSE) { - - if (!inherits(df, "utilization_provider")) { - cli::cli_abort(c( - "{.var df} must be of class {.cls 'utilization_provider'}.", - "x" = "{.var df} is of class {.cls {class(df)}}.")) - } -######################### - x <- dplyr::select(df, year, sublevel = state, conditions) |> - tidyr::unnest(conditions) |> - dplyr::mutate(hcc_risk_avg = NULL, level = "Provider", .after = year) |> - cnd_rename() |> - tidyr::pivot_longer(cols = !c(year, level, sublevel), - names_to = "condition", - values_to = "prevalence") |> - dplyr::filter(!is.na(prevalence), year %in% cc_years()) - - y <- dplyr::select(x, year, condition, sublevel) - - y$set <- "Specific" - y$demo <- "All" - y$subdemo <- "All" - y$age <- "All" - y - state <- y - national <- y - national$sublevel <- "National" - - req <- vctrs::vec_rbind(state, national) - - res <- furrr::future_pmap_dfr(req, conditions, - .options = furrr::furrr_options(seed = NULL)) - - res <- dplyr::select(res, year, level, condition, prevalence) - x$sublevel <- NULL - results <- vctrs::vec_rbind(x, res) - results$level <- fct_level(results$level) - results$condition <- fct_cc(results$condition) -####################### - if (pivot) { - results <- tidyr::pivot_wider(results, - names_from = c(year, level), - values_from = prevalence) - } - return(results) -} - -#' @param df data frame -#' @autoglobal -#' @noRd -cnd_rename <- function(df) { - cols <- c('Atrial Fibrillation' = 'cc_af', - "Alzheimer's Disease/Dementia" = 'cc_alz', - 'Asthma' = 'cc_asth', - 'Cancer' = 'cc_canc', - 'Heart Failure' = 'cc_chf', - 'Chronic Kidney Disease' = 'cc_ckd', - 'COPD' = 'cc_copd', - 'Depression' = 'cc_dep', - 'Diabetes' = 'cc_diab', - 'Hyperlipidemia' = 'cc_hplip', - 'Hypertension' = 'cc_hpten', - 'Ischemic Heart Disease' = 'cc_ihd', - 'Osteoporosis' = 'cc_opo', - 'Arthritis' = 'cc_raoa', - 'Schizophrenia and Other Psychotic Disorders' = 'cc_sz', - 'Stroke' = 'cc_strk') - - df |> dplyr::rename(dplyr::any_of(cols)) -} diff --git a/R/generated-globals.R b/R/generated-globals.R index 7f3dd109..3e395fce 100644 --- a/R/generated-globals.R +++ b/R/generated-globals.R @@ -134,8 +134,6 @@ utils::globalVariables(c( "cola", # "collection_type", - # - "condition", # "confirmed", # @@ -164,8 +162,6 @@ utils::globalVariables(c( "definition", # "Definition", - # - "demographic", # "describedBy", # @@ -225,7 +221,6 @@ utils::globalVariables(c( # # "distribution_title", - # # # # @@ -323,7 +318,6 @@ utils::globalVariables(c( # "landingPage", # - # # # # @@ -414,8 +408,6 @@ utils::globalVariables(c( "pos", # "pr", - # - "prevalence", # "prf_rate", # @@ -481,7 +473,6 @@ utils::globalVariables(c( # "state", # - # # # # @@ -507,8 +498,6 @@ utils::globalVariables(c( "subgroup_general", # "subgroup_other", - # - "sublevel", # "subtotal", # @@ -569,7 +558,6 @@ utils::globalVariables(c( # # # - # # # # @@ -592,7 +580,6 @@ utils::globalVariables(c( # # # - # # # "year", diff --git a/R/utilization.R b/R/utilization.R index 50a320cb..a61d8e6b 100644 --- a/R/utilization.R +++ b/R/utilization.R @@ -80,49 +80,79 @@ #' @name utilization NULL -#' @param year < *integer* > // **required** Year data was reported, in `YYYY` -#' format. Run [util_years()] to return a vector of the years currently available. -#' @param type < *character* > // **required** dataset to query, `"Provider"`, -#' `"Service"`, `"Geography"` -#' @param npi < *integer* > 10-digit national provider identifier -#' @param first,last,organization < *character* > Individual/Organizational -#' provider's name -#' @param credential < *character* > Individual provider's credentials -#' @param gender < *character* > Individual provider's gender; `"F"` (Female), -#' `"M"` (Male) -#' @param entype < *character* > Provider entity type; `"I"` (Individual), -#' `"O"` (Organization) -#' @param city < *character* > City where provider is located -#' @param state < *character* > State where provider is located -#' @param fips < *character* > Provider's state's FIPS code -#' @param zip < *character* > Provider’s zip code -#' @param ruca < *character* > Provider’s RUCA code -#' @param country < *character* > Country where provider is located -#' @param specialty < *character* > Provider specialty code reported on the -#' largest number of claims submitted -#' @param par < *boolean* > Identifies whether the provider participates in -#' Medicare and/or accepts assignment of Medicare allowed amounts -#' @param hcpcs < *character* > HCPCS code used to identify the specific -#' medical service furnished by the provider -#' @param drug < *boolean* > Identifies whether the HCPCS code is listed in the -#' Medicare Part B Drug Average Sales Price (ASP) File -#' @param pos < *character* > Identifies whether the Place of Service (POS) -#' submitted on the claims is a: -#' + Facility (`"F"`): Hospital, Skilled Nursing Facility, etc. -#' + Non-facility (`"O"`): Office, Home, etc. -#' @param level < *character* > Geographic level by which the data will be -#' aggregated: -#' + `"State"`: Data is aggregated for each state -#' + `"National"`: Data is aggregated across all states for a given HCPCS Code -#' @param tidy < *boolean* > // __default:__ `TRUE` Tidy output -#' @param rbcs < *boolean* > // __default:__ `TRUE` Add Restructured BETOS -#' Classifications to HCPCS codes -#' @param nest < *boolean* > // __default:__ `TRUE` Nest `performance`, `demographics` and `conditions` -#' @param detailed < *boolean* > // __default:__ `FALSE` Include nested `medical` and `drug` columns -#' @param na.rm < *boolean* > // __default:__ `TRUE` Remove empty rows and columns -#' @param ... Empty +#' @param year `` // **required** Year data was reported, in `YYYY` format. +#' Run [util_years()] to return a vector of the years currently available. +#' +#' @param type `` // **required** dataset to query, `"Provider"`, +#' `"Service"`, `"Geography"` +#' +#' @param npi `` 10-digit national provider identifier +#' +#' @param first,last,organization `` Individual/Organizational provider's +#' name +#' +#' @param credential `` Individual provider's credentials +#' +#' @param gender `` Individual provider's gender; `"F"` (Female), `"M"` +#' (Male) +#' +#' @param entype `` Provider entity type; `"I"` (Individual), `"O"` +#' (Organization) +#' +#' @param city `` City where provider is located +#' +#' @param state `` State where provider is located +#' +#' @param fips `` Provider's state's FIPS code +#' +#' @param zip `` Provider’s zip code +#' +#' @param ruca `` Provider’s RUCA code +#' +#' @param country `` Country where provider is located +#' +#' @param specialty `` Provider specialty code reported on the largest +#' number of claims submitted +#' +#' @param par `` Identifies whether the provider participates in Medicare +#' and/or accepts assignment of Medicare allowed amounts +#' +#' @param hcpcs `` HCPCS code used to identify the specific medical service +#' furnished by the provider +#' +#' @param drug `` Identifies whether the HCPCS code is listed in the +#' Medicare Part B Drug Average Sales Price (ASP) File +#' +#' @param pos `` Identifies whether the Place of Service (POS) submitted on +#' the claims is a: +#' +#' + Facility (`"F"`): Hospital, Skilled Nursing Facility, etc. +#' + Non-facility (`"O"`): Office, Home, etc. +#' +#' @param level `` Geographic level by which the data will be aggregated: +#' +#' + `"State"`: Data is aggregated for each state +#' + `"National"`: Data is aggregated across all states for a given HCPCS Code +#' +#' @param tidy `` // __default:__ `TRUE` Tidy output +#' +#' @param rbcs `` // __default:__ `TRUE` Add Restructured BETOS +#' Classifications to HCPCS codes +#' +#' @param nest `` // __default:__ `TRUE` Nest `performance`, `demographics` +#' and `conditions` columns +#' +#' @param detailed `` // __default:__ `FALSE` Include nested `medical` and +#' `drug` columns +#' +#' @param na.rm `` // __default:__ `TRUE` Remove empty rows and columns +#' +#' @param ... Empty dots +#' #' @rdname utilization +#' #' @autoglobal +#' #' @export utilization <- function(year, type, @@ -154,15 +184,15 @@ utilization <- function(year, rlang::check_required(year) year <- as.character(year) - year <- rlang::arg_match(year, as.character(util_years())) - type <- rlang::arg_match(type, c('Provider', 'Service', 'Geography')) + year <- rlang::arg_match0(year, as.character(util_years())) + type <- rlang::arg_match0(type, c('Provider', 'Service', 'Geography')) if (type != 'Provider') c(nest, detailed) %<-% c(FALSE, FALSE) if (type == 'Provider') c(rbcs, hcpcs = NULL, pos = NULL, drug = NULL) %<-% c(FALSE) # nolint if (type != 'Geography') { param_state <- 'Rndrng_Prvdr_State_Abrvtn' - param_fips <- 'Rndrng_Prvdr_State_FIPS' - level <- NULL + param_fips <- 'Rndrng_Prvdr_State_FIPS' + level <- NULL } if (type == 'Geography') { @@ -181,7 +211,7 @@ utilization <- function(year, country <- NULL specialty <- NULL par <- NULL # nolint - level <- level %nn% rlang::arg_match(level, c('National', 'State')) + level <- level %nn% rlang::arg_match0(level, c('National', 'State')) if (!is.null(state) && (state %in% state.abb)) state <- abb2full(state) } @@ -192,7 +222,7 @@ utilization <- function(year, par <- par %nn% tf_2_yn(par) # nolint hcpcs <- hcpcs %nn% as.character(hcpcs) drug <- drug %nn% tf_2_yn(drug) - pos <- pos %nn% rlang::arg_match(pos, c("F", "O")) + pos <- pos %nn% rlang::arg_match0(pos, c("F", "O")) args <- dplyr::tribble( ~param, ~arg, @@ -221,10 +251,18 @@ utilization <- function(year, 'Service' = api_years('srv'), 'Geography' = api_years('geo')) - id <- dplyr::filter(yr, year == {{ year }}) |> dplyr::pull(distro) + id <- dplyr::filter( + yr, + year == {{ year }} + ) |> + dplyr::pull(distro) - url <- paste0("https://data.cms.gov/data-api/v1/dataset/", - id, "/data.json?", encode_param(args)) + url <- paste0( + "https://data.cms.gov/data-api/v1/dataset/", + id, + "/data.json?", + + encode_param(args)) response <- httr2::request(url) |> httr2::req_perform() @@ -277,51 +315,70 @@ utilization <- function(year, } #' Parallelized [utilization()] -#' @param year < *integer* > // **required** Year data was reported, in `YYYY` -#' format. Run [util_years()] to return a vector of the years currently available. +#' +#' @param year `` // **required** Year data was reported, in `YYYY` format. +#' Run [util_years()] to return a vector of the years currently available. +#' #' @param ... Pass arguments to [utilization()]. +#' #' @rdname utilization +#' #' @autoglobal +#' #' @export utilization_ <- function(year = util_years(), ...) { - furrr::future_map_dfr(year, utilization, ..., - .options = furrr::furrr_options(seed = NULL)) - + furrr::future_map_dfr( + year, + utilization, + ..., + .options = furrr::furrr_options(seed = NULL)) } #' @param results data frame from [utilization(type = "Provider")] -#' @param nest < *boolean* > Nest `demographics` and `conditions` -#' @param detailed < *boolean* > Include `detailed` column +#' +#' @param nest `` Nest `demographics` and `conditions` +#' +#' @param detailed `` Include `detailed` column +#' #' @autoglobal +#' #' @noRd tidyup_provider.util <- function(results, nest, detailed) { results <- janitor::clean_names(results) |> cols_util("Provider") |> - tidyup(yn = "par", - int = c("year", "_hcpcs", "bene", "_srvcs"), - dbl = c("pay", "pymt", "charges", "allowed", "cc_", "hcc"), - cred = "credential", - zip = 'rndrng_prvdr_zip5') |> - combine(address, c('rndrng_prvdr_st1', 'rndrng_prvdr_st2')) |> - dplyr::mutate(specialty = correct_specialty(specialty), - .copay_deduct = tot_allowed - tot_payment, - .srvcs_per_bene = tot_srvcs / tot_benes, - .pymt_per_bene = tot_payment / tot_benes, - .pymt_per_srvc = tot_payment / tot_srvcs, - entity_type = fct_ent(entity_type), - gender = fct_gen(gender), - state = fct_stabb(state)) |> - dplyr::mutate(bene_race_nonwht = tot_benes - bene_race_wht, - .after = bene_race_wht) + tidyup( + yn = "par", + int = c("year", "_hcpcs", "bene", "_srvcs"), + dbl = c("pay", "pymt", "charges", "allowed", "cc_", "hcc"), + cred = "credential", + zip = 'rndrng_prvdr_zip5') |> + combine( + address, + c('rndrng_prvdr_st1', 'rndrng_prvdr_st2') + ) |> + dplyr::mutate( + specialty = correct_specialty(specialty), + .copay_deduct = tot_allowed - tot_payment, + .srvcs_per_bene = tot_srvcs / tot_benes, + .pymt_per_bene = tot_payment / tot_benes, + .pymt_per_srvc = tot_payment / tot_srvcs, + entity_type = fct_ent(entity_type), + gender = fct_gen(gender), + state = fct_stabb(state) + ) |> + dplyr::mutate( + bene_race_nonwht = tot_benes - bene_race_wht, + .after = bene_race_wht) if (nest) { - race_cols <- c('bene_race_blk', - 'bene_race_api', - 'bene_race_hisp', - 'bene_race_nat', - 'bene_race_oth') + race_cols <- c( + 'bene_race_blk', + 'bene_race_api', + 'bene_race_hisp', + 'bene_race_nat', + 'bene_race_oth') results <- tidyr::nest( results, @@ -329,26 +386,37 @@ tidyup_provider.util <- function(results, nest, detailed) { results <- tidyr::nest( results, - performance = c(dplyr::starts_with("tot_"), dplyr::starts_with(".")), - demographics = c(dplyr::starts_with("bene_"), bene_race_detailed), - conditions = c(hcc_risk_avg, dplyr::starts_with("cc_"))) + performance = c(dplyr::starts_with("tot_"), dplyr::starts_with(".")), + demographics = c(dplyr::starts_with("bene_"), bene_race_detailed), + conditions = c(hcc_risk_avg, dplyr::starts_with("cc_"))) } if (detailed) { - results <- tidyr::nest(results, medical = dplyr::starts_with("med_"), - drug = dplyr::starts_with("drug_")) |> - tidyr::nest(results, detailed = c(medical, drug)) + results <- tidyr::nest( + results, + medical = dplyr::starts_with("med_"), + drug = dplyr::starts_with("drug_") + ) |> + tidyr::nest( + results, + detailed = c(medical, drug)) } else { - results <- dplyr::select(results, - -dplyr::starts_with("med_"), - -dplyr::starts_with("drug_")) + results <- dplyr::select( + results, + -dplyr::starts_with("med_"), + -dplyr::starts_with("drug_")) } + class(results) <- c("utilization_provider", class(results)) + return(results) } #' @param results data frame from [utilization(type = "Service")] -#' @param rbcs < *boolean* > Add Restructured BETOS Classifications to HCPCS codes +#' +#' @param rbcs `` Add Restructured BETOS Classifications to HCPCS codes +#' #' @autoglobal +#' #' @noRd tidyup_service.util <- function(results, rbcs) { @@ -376,8 +444,11 @@ tidyup_service.util <- function(results, rbcs) { } #' @param results data frame from [utilization(type = "Geography")] -#' @param rbcs < *boolean* > Add Restructured BETOS Classifications to HCPCS codes +#' +#' @param rbcs `` Add Restructured BETOS Classifications to HCPCS codes +#' #' @autoglobal +#' #' @noRd tidyup_geography.util <- function(results, rbcs) { @@ -393,12 +464,16 @@ tidyup_geography.util <- function(results, rbcs) { if (rbcs) results <- rbcs_util(results) class(results) <- c("utilization_geography", class(results)) + return(results) } #' @param df data frame +#' #' @param type 'Provider', 'Service', 'Geography' or 'rbcs' +#' #' @autoglobal +#' #' @noRd cols_util <- function(df, type) { @@ -578,7 +653,9 @@ cols_util <- function(df, type) { } #' @param x vector +#' #' @autoglobal +#' #' @noRd correct_specialty <- function(x) { dplyr::case_match(x, diff --git a/R/utils-fct.R b/R/utils-fct.R index 02b6a31e..1a2914c1 100644 --- a/R/utils-fct.R +++ b/R/utils-fct.R @@ -149,17 +149,6 @@ fct_subdemo <- function(x) { "non-Hispanic White")) } -#' Convert multiple chronic condition groups to labelled, ordered factor -#' @param x vector -#' @autoglobal -#' @noRd -fct_mcc <- function(x) { - factor(x, - levels = c("0 to 1", "2 to 3", "4 to 5", "6+"), - labels = c("0-1", "2-3", "4-5", "6+"), - ordered = TRUE) -} - #' Convert QPP participation types to unordered factor #' @param x vector #' @autoglobal diff --git a/R/years.R b/R/years.R index ee331384..bf2b3ddc 100644 --- a/R/years.R +++ b/R/years.R @@ -94,22 +94,6 @@ util_years <- function() { ) } -#' @rdname years -#' -#' @keywords internal -#' -#' @autoglobal -#' -#' @export -cc_years <- function() { - as.integer( - cms_update( - "Specific Chronic Conditions", - "years" - ) - ) -} - #' @rdname years #' #' @keywords internal diff --git a/README.Rmd b/README.Rmd index 94cd41b7..b435860f 100644 --- a/README.Rmd +++ b/README.Rmd @@ -63,11 +63,11 @@ affiliations(npi = 1023630738, ### `beneficiaries()` ```{r} -beneficiaries(year = 2023, - period = "Year", +beneficiaries(year = 2024, + period = "Month", level = "County", state = "GA", - county = "Lowndes") |> + county = "Lowndes County") |> glimpse() ``` @@ -78,29 +78,6 @@ clinicians(npi = 1932365699) |> glimpse() ``` -### `conditions()` - -```{r} -conditions(year = 2018, - set = "Multiple", - level = "National", - age = "All", - demo = "All", - mcc = "6+") |> - glimpse() -``` - - -```{r} -conditions(year = 2018, - set = "Specific", - level = "National", - age = "All", - demo = "All", - condition = "Arthritis") |> - glimpse() -``` - ### `hospitals()` ```{r} @@ -250,7 +227,7 @@ reassignments(npi = 1932365699, ```{r} utilization(year = 2021, npi = 1932365699, - type = "provider") |> + type = "Provider") |> glimpse() ``` @@ -259,7 +236,7 @@ utilization(year = 2021, ```{r} p <- utilization(year = 2021, npi = 1932365699, - type = "provider") + type = "Provider") select(p, year, performance) |> unnest(performance) |> @@ -286,7 +263,7 @@ select(p, year, conditions) |> utilization(year = 2021, npi = 1932365699, hcpcs = "99214", - type = "service") |> + type = "Service") |> glimpse() ``` @@ -296,7 +273,7 @@ utilization(year = 2021, hcpcs = "99205", level = "National", pos = "F", - type = "geography") |> + type = "Geography") |> glimpse() ``` diff --git a/README.md b/README.md index cb5dc3c9..1d0d3dc2 100644 --- a/README.md +++ b/README.md @@ -59,42 +59,42 @@ affiliations(npi = 1023630738, ### `beneficiaries()` ``` r -beneficiaries(year = 2023, - period = "Year", +beneficiaries(year = 2024, + period = "Month", level = "County", state = "GA", - county = "Lowndes") |> + county = "Lowndes County") |> glimpse() ``` - #> Rows: 1 + #> Rows: 3 #> Columns: 26 - #> $ year 2023 - #> $ period Year - #> $ level County - #> $ state GA - #> $ state_name Georgia - #> $ county "Lowndes" - #> $ fips "13185" - #> $ bene_total 20515 - #> $ bene_orig 11098 - #> $ bene_ma_oth 9418 - #> $ bene_total_aged 17046 - #> $ bene_aged_esrd 124 - #> $ bene_aged_no_esrd 16923 - #> $ bene_total_dsb 3469 - #> $ bene_dsb_esrd 145 - #> $ bene_dsb_no_esrd 3325 - #> $ bene_total_ab 19038 - #> $ bene_ab_orig 9635 - #> $ bene_ab_ma_oth 9403 - #> $ bene_total_rx 14850 - #> $ bene_rx_pdp 5940 - #> $ bene_rx_mapd 8910 - #> $ bene_rx_lis_elig 5561 - #> $ bene_rx_lis_full 456 - #> $ bene_rx_lis_part 133 - #> $ bene_rx_lis_no 8701 + #> $ year 2024, 2024, 2024 + #> $ period January, February, March + #> $ level County, County, County + #> $ state GA, GA, GA + #> $ state_name Georgia, Georgia, Georgia + #> $ county "Lowndes County", "Lowndes County", "Lowndes County" + #> $ fips "13185", "13185", "13185" + #> $ bene_total 20848, 20854, 20874 + #> $ bene_orig 10648, 10609, 10579 + #> $ bene_ma_oth 10200, 10245, 10295 + #> $ bene_total_aged 17556, 17561, 17581 + #> $ bene_aged_esrd 118, 114, 112 + #> $ bene_aged_no_esrd 17438, 17447, 17469 + #> $ bene_total_dsb 3292, 3293, 3293 + #> $ bene_dsb_esrd 144, 144, 142 + #> $ bene_dsb_no_esrd 3148, 3149, 3151 + #> $ bene_total_ab 19357, 19403, 19424 + #> $ bene_ab_orig 9172, 9173, 9148 + #> $ bene_ab_ma_oth 10185, 10230, 10276 + #> $ bene_total_rx 15492, 15512, 15529 + #> $ bene_rx_pdp 5868, 5835, 5809 + #> $ bene_rx_mapd 9624, 9677, 9720 + #> $ bene_rx_lis_elig 5669, 5675, 5678 + #> $ bene_rx_lis_full 600, 595, 601 + #> $ bene_rx_lis_part 23, 23, 22 + #> $ bene_rx_lis_no 9200, 9219, 9228 ### `clinicians()` @@ -104,7 +104,7 @@ clinicians(npi = 1932365699) |> ``` #> Rows: 1 - #> Columns: 18 + #> Columns: 19 #> $ npi "1932365699" #> $ pac "0042370496" #> $ enid "I20171107000894" @@ -112,6 +112,7 @@ clinicians(npi = 1932365699) |> #> $ middle "MICHAEL" #> $ last "SMITH" #> $ gender Male + #> $ credential "OD" #> $ school "ILLINOIS COLLEGE OF OPTOMETRY AT CHICAGO" #> $ grad_year 2008 #> $ specialty "OPTOMETRY" @@ -124,58 +125,6 @@ clinicians(npi = 1932365699) |> #> $ zip_org "81303" #> $ phone_org "9702478762" -### `conditions()` - -``` r -conditions(year = 2018, - set = "Multiple", - level = "National", - age = "All", - demo = "All", - mcc = "6+") |> - glimpse() -``` - - #> Rows: 1 - #> Columns: 12 - #> $ year 2018 - #> $ level National - #> $ sublevel National - #> $ age All - #> $ demographic All - #> $ subdemo All - #> $ mcc 6+ - #> $ prevalence 0.177 - #> $ tot_pymt_percap 32475.26 - #> $ tot_std_pymt_percap 30118.69 - #> $ hosp_readmit_rate 0.227 - #> $ er_visits_per_1k 1922.216 - -``` r -conditions(year = 2018, - set = "Specific", - level = "National", - age = "All", - demo = "All", - condition = "Arthritis") |> - glimpse() -``` - - #> Rows: 1 - #> Columns: 12 - #> $ year 2018 - #> $ level National - #> $ sublevel National - #> $ age All - #> $ demographic All - #> $ subdemo All - #> $ condition Arthritis - #> $ prevalence 0.3347 - #> $ tot_pymt_percap 16890.05 - #> $ tot_std_pymt_percap 16006.14 - #> $ hosp_readmit_rate 0.1843 - #> $ er_visits_per_1k 1013.535 - ### `hospitals()` ``` r @@ -303,7 +252,7 @@ open_payments(year = 2021, #> $ license_state OK #> $ physician_ownership FALSE #> $ third_party_payment "No Third Party Payment" - #> $ publish_date 2024-01-18 + #> $ publish_date 2024-06-28 #> $ publish_delay FALSE #> $ publish_dispute FALSE #> $ related_product TRUE @@ -414,35 +363,7 @@ prescribers(year = 2021, glimpse() ``` - #> Rows: 1 - #> Columns: 27 - #> $ year 2021 - #> $ npi "1003000423" - #> $ entity_type Individual - #> $ first "Jennifer" - #> $ middle "A" - #> $ last "Velotta" - #> $ gender Female - #> $ credential "MD" - #> $ specialty "Obstetrics & Gynecology" - #> $ source Medicare Specialty Code - #> $ address "11100 Euclid Ave" - #> $ city "Cleveland" - #> $ state OH - #> $ zip "44106" - #> $ fips "39" - #> $ ruca "1" - #> $ country "US" - #> $ tot_claims 206 - #> $ tot_fills 378.2667 - #> $ tot_cost 20757.65 - #> $ tot_supply 10231 - #> $ tot_benes 66 - #> $ rx_rate_opioid 0 - #> $ hcc_risk_avg 0.8011638 - #> $ detailed [] - #> $ demographics [] - #> $ gte_65 [] + #> Error in readBin(body, character()): R character strings are limited to 2^31-1 bytes ``` r prescribers(year = 2019, @@ -453,7 +374,7 @@ prescribers(year = 2019, ``` #> Rows: 1 - #> Columns: 18 + #> Columns: 17 #> $ year 2019 #> $ npi "1003000126" #> $ last "Enkeshafi" @@ -462,7 +383,6 @@ prescribers(year = 2019, #> $ state MD #> $ fips "24" #> $ specialty "Internal Medicine" - #> $ source Medicare Specialty Code #> $ brand_name "Atorvastatin Calcium" #> $ generic_name "Atorvastatin Calcium" #> $ tot_claims 41 @@ -693,33 +613,57 @@ reassignments(npi = 1932365699, ``` r utilization(year = 2021, npi = 1932365699, - type = "provider") |> + type = "Provider") |> glimpse() ``` - #> Error in `utilization()`: - #> ! `type` must be one of "Provider", "Service", or "Geography", not - #> "provider". - #> ℹ Did you mean "Provider"? + #> Rows: 1 + #> Columns: 20 + #> $ year 2021 + #> $ npi "1932365699" + #> $ entity_type Individual + #> $ first "Stefan" + #> $ middle "M" + #> $ last "Smith" + #> $ gender Male + #> $ credential "OD" + #> $ specialty "Optometry" + #> $ address "724 St. Louis Road" + #> $ city "Collinsville" + #> $ state IL + #> $ zip "62234" + #> $ fips "17" + #> $ ruca "1" + #> $ country "US" + #> $ par TRUE + #> $ performance [] + #> $ demographics [] + #> $ conditions [] ``` r p <- utilization(year = 2021, npi = 1932365699, - type = "provider") -``` + type = "Provider") - #> Error in `utilization()`: - #> ! `type` must be one of "Provider", "Service", or "Geography", not - #> "provider". - #> ℹ Did you mean "Provider"? - -``` r select(p, year, performance) |> unnest(performance) |> glimpse() ``` - #> Error in eval(expr, envir, enclos): object 'p' not found + #> Rows: 1 + #> Columns: 12 + #> $ year 2021 + #> $ tot_hcpcs 19 + #> $ tot_benes 279 + #> $ tot_srvcs 475 + #> $ tot_charges 57098.8 + #> $ tot_allowed 48345.19 + #> $ tot_payment 31966.13 + #> $ tot_std_pymt 31316.51 + #> $ .copay_deduct 16379.06 + #> $ .srvcs_per_bene 1.702509 + #> $ .pymt_per_bene 114.5739 + #> $ .pymt_per_srvc 67.29712 ``` r select(p, year, demographics) |> @@ -727,7 +671,21 @@ select(p, year, demographics) |> glimpse() ``` - #> Error in eval(expr, envir, enclos): object 'p' not found + #> Rows: 1 + #> Columns: 13 + #> $ year 2021 + #> $ bene_age_avg 72 + #> $ bene_age_lt65 16 + #> $ bene_age_65_74 181 + #> $ bene_age_75_84 63 + #> $ bene_age_gt84 19 + #> $ bene_gen_female 157 + #> $ bene_gen_male 122 + #> $ bene_race_wht 245 + #> $ bene_race_nonwht 34 + #> $ bene_dual 40 + #> $ bene_ndual 239 + #> $ bene_race_detailed [] ``` r select(p, year, conditions) |> @@ -735,34 +693,84 @@ select(p, year, conditions) |> glimpse() ``` - #> Error in eval(expr, envir, enclos): object 'p' not found + #> Rows: 1 + #> Columns: 2 + #> $ year 2021 + #> $ hcc_risk_avg 0.7719 ``` r utilization(year = 2021, npi = 1932365699, hcpcs = "99214", - type = "service") |> + type = "Service") |> glimpse() ``` - #> Error in `utilization()`: - #> ! `type` must be one of "Provider", "Service", or "Geography", not - #> "service". - #> ℹ Did you mean "Service"? + #> Rows: 1 + #> Columns: 32 + #> $ year 2021 + #> $ npi "1932365699" + #> $ level Provider + #> $ first "Stefan" + #> $ middle "M" + #> $ last "Smith" + #> $ gender Male + #> $ credential "O.D." + #> $ specialty "Optometry" + #> $ address "724 St. Louis Road" + #> $ city "Collinsville" + #> $ state IL + #> $ zip "62234" + #> $ fips "17" + #> $ ruca "1" + #> $ country "US" + #> $ par TRUE + #> $ hcpcs "99214" + #> $ hcpcs_desc "Established patient outpatient visit, total time 30-39 m… + #> $ category "E&M" + #> $ subcategory "Office/Outpatient Services" + #> $ family "Office E&M - Established" + #> $ procedure Non-procedure + #> $ drug FALSE + #> $ pos Non-facility + #> $ tot_benes 24 + #> $ tot_srvcs 27 + #> $ tot_day 27 + #> $ avg_charge 134.7407 + #> $ avg_allowed 132.7281 + #> $ avg_payment 102.7159 + #> $ avg_std_pymt 99.46074 ``` r utilization(year = 2021, hcpcs = "99205", level = "National", pos = "F", - type = "geography") |> + type = "Geography") |> glimpse() ``` - #> Error in `utilization()`: - #> ! `type` must be one of "Provider", "Service", or "Geography", not - #> "geography". - #> ℹ Did you mean "Geography"? + #> Rows: 1 + #> Columns: 19 + #> $ year 2021 + #> $ level National + #> $ state National + #> $ hcpcs "99205" + #> $ hcpcs_desc "New patient outpatient visit, total time 60-74 minutes" + #> $ category "E&M" + #> $ subcategory "Office/Outpatient Services" + #> $ family "Office E&M - New" + #> $ procedure Non-procedure + #> $ drug FALSE + #> $ pos Facility + #> $ tot_provs 65502 + #> $ tot_benes 574426 + #> $ tot_srvcs 653339 + #> $ tot_day 653311 + #> $ avg_charge 493.5003 + #> $ avg_allowed 186.2096 + #> $ avg_payment 143.4408 + #> $ avg_std_pymt 139.6115 ------------------------------------------------------------------------ diff --git a/R/conditions.R b/data-raw/deprecated/chronic_conditions.R similarity index 57% rename from R/conditions.R rename to data-raw/deprecated/chronic_conditions.R index 0dfec13e..e7040a94 100644 --- a/R/conditions.R +++ b/data-raw/deprecated/chronic_conditions.R @@ -1,3 +1,19 @@ +#' @rdname years +#' +#' @keywords internal +#' +#' @autoglobal +#' +#' @export +cc_years <- function() { + as.integer( + cms_update( + "Specific Chronic Conditions", + "years" + ) + ) +} + #' Chronic Conditions Prevalence #' #' @description @@ -111,10 +127,7 @@ #' @returns A [tibble][tibble::tibble-package] with the following columns: #' #' @examplesIf interactive() -#' conditions(year = 2018, -#' set = "Specific", -#' sublevel = "CA", -#' demo = "All") +#' conditions(year = 2018, set = "Specific", sublevel = "CA", demo = "All") #' #' conditions(year = 2018, #' set = "Specific", @@ -156,7 +169,7 @@ conditions <- function(year, rlang::check_required(year) rlang::check_required(set) year <- as.character(year) - year <- rlang::arg_match(year, as.character(cc_years())) + # year <- rlang::arg_match(year, as.character(cc_years())) set <- rlang::arg_match(set, c("Multiple", "Specific")) if (!is.null(mcc)) { @@ -244,10 +257,10 @@ conditions <- function(year, demographic = fct_demo(demographic), subdemo = fct_subdemo(subdemo)) - if (set == "Multiple") results$mcc <- fct_mcc(results$mcc) - if (set == "Specific") results$condition <- fct_cc(results$condition) - if (na.rm) results <- narm(results) - } + if (set == "Multiple") results$mcc <- fct_mcc(results$mcc) + if (set == "Specific") results$condition <- fct_cc(results$condition) + if (na.rm) results <- narm(results) + } return(results) } @@ -376,3 +389,227 @@ fct_cc <- function(x) { 'Stroke'), ordered = TRUE) } + +#' Convert multiple chronic condition groups to labelled, ordered factor +#' @param x vector +#' @autoglobal +#' @noRd +fct_mcc <- function(x) { + factor(x, + levels = c("0 to 1", "2 to 3", "4 to 5", "6+"), + labels = c("0-1", "2-3", "4-5", "6+"), + ordered = TRUE) +} + +test_that("fct_mcc() works", { + x <- c("0 to 1", "2 to 3", "4 to 5", "6+") + y <- ordered(c("0-1", "2-3", "4-5", "6+")) + expect_equal(fct_mcc(x), y) +}) + +test_that("fct_cc() works", { + x <- c( + "All", "Alcohol Abuse", "Alzheimer's Disease/Dementia", "Arthritis", + "Asthma", "Atrial Fibrillation", "Autism Spectrum Disorders", "Cancer", + "Chronic Kidney Disease", "COPD", "Depression", "Diabetes", + "Drug Abuse/Substance Abuse", "Heart Failure", + "Hepatitis (Chronic Viral B & C)", "HIV/AIDS", "Hyperlipidemia", + "Hypertension", "Ischemic Heart Disease", "Osteoporosis", + "Schizophrenia and Other Psychotic Disorders", "Stroke") + expect_equal(fct_cc(x), ordered(x, levels = x)) +}) + +httptest2::without_internet({ + test_that("conditions(set = 'Specific') returns correct request URL", { + httptest2::expect_GET( + conditions(year = 2018, + set = "Specific", + level = "State", + sublevel = "CA", + demo = "Sex", + subdemo = "Female", + age = "65+", + condition = "Asthma", + fips = "06"), + 'https://data.cms.gov/data.json') + }) +}) + +test_that("cols_cc() works", { + x <- dplyr::tibble( + year = 1, + bene_geo_lvl = 1, + bene_geo_desc = 1, + bene_geo_cd = 1, + bene_age_lvl = 1, + bene_demo_lvl = 1, + bene_demo_desc = 1, + bene_mcc = 1, + bene_cond = 1, + prvlnc = 1, + tot_mdcr_pymt_pc = 1, + tot_mdcr_stdzd_pymt_pc = 1, + hosp_readmsn_rate = 1, + er_visits_per_1000_benes = 1) + + y <- dplyr::tibble( + year = 1, + level = 1, + sublevel = 1, + fips = 1, + age = 1, + demographic = 1, + subdemo = 1, + mcc = 1, + condition = 1, + prevalence = 1, + tot_pymt_percap = 1, + tot_std_pymt_percap = 1, + hosp_readmit_rate = 1, + er_visits_per_1k = 1) + expect_equal(cols_cc(x), y) +}) + +test_that("lookup() works", {expect_equal(lookup( + c("0-1" = "0 to 1"), "0-1"), "0 to 1")}) +test_that("levels() works", {expect_equal(levels(), + c("National", "State", "County"))}) +test_that("ages() works", {expect_equal(ages(), + c("All", "<65", "65+"))}) +test_that("demo() works", {expect_equal(demo(), + c("All", "Dual Status", "Sex", "Race"))}) + +test_that("mcc() works", { + expect_equal(mcc(), c("0-1" = "0 to 1", + "2-3" = "2 to 3", + "4-5" = "4 to 5", + "6+" = "6+")) +}) + +test_that("subdemo() works", { + expect_equal(subdemo(), c("All" = "All", + "Nondual" = "Medicare Only", + "Dual" = "Medicare and Medicaid", + "Female" = "Female", + "Male" = "Male", + "Island" = "Asian Pacific Islander", + "Hispanic" = "Hispanic", + "Native" = "Native American", + "Black" = "non-Hispanic Black", + "White" = "non-Hispanic White")) +}) + +test_that("spec_cond() works", { + expect_equal(spec_cond(), c('All' = 'All', + 'Alcohol Abuse' = 'Alcohol Abuse', + "Alzheimer's Disease/Dementia" = "Alzheimer's Disease%2FDementia", + 'Arthritis' = 'Arthritis', + 'Asthma' = 'Asthma', + 'Atrial Fibrillation' = 'Atrial Fibrillation', + 'Autism Spectrum Disorders' = 'Autism Spectrum Disorders', + 'Cancer' = 'Cancer', + 'Chronic Kidney Disease' = 'Chronic Kidney Disease', + 'COPD' = 'COPD', + 'Depression' = 'Depression', + 'Diabetes' = 'Diabetes', + 'Drug Abuse/Substance Abuse' = 'Drug Abuse%2FSubstance Abuse', + 'Heart Failure' = 'Heart Failure', + 'Hepatitis (Chronic Viral B & C)' = 'Hepatitis (Chronic Viral B %26 C)', + 'HIV/AIDS' = 'HIV%2FAIDS', + 'Hyperlipidemia' = 'Hyperlipidemia', + 'Hypertension' = 'Hypertension', + 'Ischemic Heart Disease' = 'Ischemic Heart Disease', + 'Osteoporosis' = 'Osteoporosis', + 'Schizophrenia and Other Psychotic Disorders' = 'Schizophrenia and Other Psychotic Disorders', + 'Stroke' = 'Stroke')) +}) + +#' @param df < *tbl_df* > // **required** [tibble()] returned from `utilization(type = "Provider")` +#' +#' @param pivot < *boolean* > // __default:__ `FALSE` Pivot output +#' +#' @rdname compare +#' +#' @examplesIf interactive() +#' +#' compare_conditions(utilization(year = 2018, +#' type = "Provider", +#' npi = 1023076643)) +#' +#' map_dfr(util_years(), ~utilization(year = .x, +#' npi = 1023076643, +#' type = "Provider")) |> +#' compare_conditions() +#' +#' @autoglobal +#' @export +compare_conditions <- function(df, pivot = FALSE) { + + if (!inherits(df, "utilization_provider")) { + cli::cli_abort(c( + "{.var df} must be of class {.cls 'utilization_provider'}.", + "x" = "{.var df} is of class {.cls {class(df)}}.")) + } + ######################### + x <- dplyr::select(df, year, sublevel = state, conditions) |> + tidyr::unnest(conditions) |> + dplyr::mutate(hcc_risk_avg = NULL, level = "Provider", .after = year) |> + cnd_rename() |> + tidyr::pivot_longer(cols = !c(year, level, sublevel), + names_to = "condition", + values_to = "prevalence") |> + dplyr::filter(!is.na(prevalence), year %in% cc_years()) + + y <- dplyr::select(x, year, condition, sublevel) + + y$set <- "Specific" + y$demo <- "All" + y$subdemo <- "All" + y$age <- "All" + y + state <- y + national <- y + national$sublevel <- "National" + + req <- vctrs::vec_rbind(state, national) + + res <- furrr::future_pmap_dfr(req, conditions, + .options = furrr::furrr_options(seed = NULL)) + + res <- dplyr::select(res, year, level, condition, prevalence) + x$sublevel <- NULL + results <- vctrs::vec_rbind(x, res) + results$level <- fct_level(results$level) + results$condition <- fct_cc(results$condition) + ####################### + if (pivot) { + results <- tidyr::pivot_wider(results, + names_from = c(year, level), + values_from = prevalence) + } + return(results) +} + +#' @param df data frame +#' @autoglobal +#' @noRd +cnd_rename <- function(df) { + cols <- c('Atrial Fibrillation' = 'cc_af', + "Alzheimer's Disease/Dementia" = 'cc_alz', + 'Asthma' = 'cc_asth', + 'Cancer' = 'cc_canc', + 'Heart Failure' = 'cc_chf', + 'Chronic Kidney Disease' = 'cc_ckd', + 'COPD' = 'cc_copd', + 'Depression' = 'cc_dep', + 'Diabetes' = 'cc_diab', + 'Hyperlipidemia' = 'cc_hplip', + 'Hypertension' = 'cc_hpten', + 'Ischemic Heart Disease' = 'cc_ihd', + 'Osteoporosis' = 'cc_opo', + 'Arthritis' = 'cc_raoa', + 'Schizophrenia and Other Psychotic Disorders' = 'cc_sz', + 'Stroke' = 'cc_strk') + + df |> dplyr::rename(dplyr::any_of(cols)) +} diff --git a/man/compare.Rd b/man/compare.Rd deleted file mode 100644 index 5615f0af..00000000 --- a/man/compare.Rd +++ /dev/null @@ -1,57 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/compare.R -\name{compare} -\alias{compare} -\alias{compare_hcpcs} -\alias{compare_conditions} -\title{Compare Provider Performance} -\usage{ -compare_hcpcs(df) - -compare_conditions(df, pivot = FALSE) -} -\arguments{ -\item{df}{< \emph{tbl_df} > // \strong{required} \code{\link[=tibble]{tibble()}} returned from \code{utilization(type = "Provider")}} - -\item{pivot}{< \emph{boolean} > // \strong{default:} \code{FALSE} Pivot output} -} -\value{ -A \link[tibble:tibble-package]{tibble} containing: -\itemize{ -\item \code{compare_hcpcs()} -\item \code{compare_conditions()} -} -} -\description{ -\itemize{ -\item \code{compare_hcpcs()} allows the user to compare a provider's yearly HCPCS -utilization data to state and national averages -\item \code{compare_conditions()} allows the user to compare the average yearly -prevalence of chronic conditions among a provider's patient mix to state and -national averages -} -} -\examples{ -\dontshow{if (interactive()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} - -compare_hcpcs(utilization(year = 2018, - type = "Service", - npi = 1023076643)) - -map_dfr(util_years(), ~utilization(year = .x, - npi = 1023076643, - type = "Service")) |> -compare_hcpcs() -\dontshow{\}) # examplesIf} -\dontshow{if (interactive()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} - -compare_conditions(utilization(year = 2018, - type = "Provider", - npi = 1023076643)) - -map_dfr(util_years(), ~utilization(year = .x, - npi = 1023076643, - type = "Provider")) |> -compare_conditions() -\dontshow{\}) # examplesIf} -} diff --git a/man/compare_hcpcs.Rd b/man/compare_hcpcs.Rd new file mode 100644 index 00000000..0004ae0b --- /dev/null +++ b/man/compare_hcpcs.Rd @@ -0,0 +1,32 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/compare.R +\name{compare_hcpcs} +\alias{compare_hcpcs} +\title{Compare Provider Performance} +\usage{ +compare_hcpcs(df) +} +\arguments{ +\item{df}{< \emph{tbl_df} > // \strong{required} + +\link[tibble:tibble-package]{tibble} returned from \code{utilization(type = "Service")}} +} +\value{ +A \link[tibble:tibble-package]{tibble} +} +\description{ +\code{compare_hcpcs()} allows the user to compare a provider's yearly HCPCS +utilization data to state and national averages +} +\examples{ +\dontshow{if (interactive()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} +compare_hcpcs(utilization(year = 2018, + type = "Service", + npi = 1023076643)) + +map_dfr(util_years(), ~utilization(year = .x, + npi = 1023076643, + type = "Service")) |> +compare_hcpcs() +\dontshow{\}) # examplesIf} +} diff --git a/man/conditions.Rd b/man/conditions.Rd deleted file mode 100644 index e56dfc14..00000000 --- a/man/conditions.Rd +++ /dev/null @@ -1,190 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/conditions.R -\name{conditions} -\alias{conditions} -\title{Chronic Conditions Prevalence} -\usage{ -conditions( - year, - condition = NULL, - sublevel = NULL, - set = c("Multiple", "Specific"), - level = NULL, - fips = NULL, - age = NULL, - demo = NULL, - subdemo = NULL, - mcc = NULL, - tidy = TRUE, - na.rm = TRUE, - ... -) -} -\arguments{ -\item{year}{< \emph{integer} > Calendar year of Medicare enrollment, in \code{YYYY} -format. Run \code{\link[=cc_years]{cc_years()}} to return a vector of currently available years.} - -\item{condition}{< \emph{character} > Chronic condition for which the prevalence -and utilization is compiled (see details for list of conditions)} - -\item{sublevel}{< \emph{character} > Beneficiary's state or county} - -\item{set}{< \emph{character} > // \strong{required} \code{"Multiple"} or \code{"Specific"}} - -\item{level}{< \emph{character} > Geographic level of aggregation: \code{"National"}, \code{"State"}, or \code{"County"}} - -\item{fips}{< \emph{character} > Beneficiary's state or county FIPS code} - -\item{age}{< \emph{character} > Age level of aggregation: \code{"All"}, \code{"<65"}, or \code{"65+"}} - -\item{demo, subdemo}{< \emph{character} > Demographic/subdemographic level of aggregation:\tabular{ll}{ - \strong{\code{demo}} \tab \strong{\code{subdemo}} \cr - \code{'All'} \tab \code{'All'} \cr - \code{'Sex'} \tab \code{'Male'} \cr - '' \tab \code{'Female'} \cr - \code{'Race'} \tab \code{'White'} \cr - '' \tab \code{'Black'} \cr - '' \tab \code{'Island'} \cr - '' \tab \code{'Hispanic'} \cr - '' \tab \code{'Native'} \cr - \code{'Dual Status'} \tab \code{'Dual'} (Medicare & Medicaid) \cr - '' \tab \code{'Nondual'} (Medicare only) \cr -}} - -\item{mcc}{< \emph{character} > Number of chronic conditions: \code{"0-1"}, \code{"2-3"}, \code{"4-5"}, \code{"6+"}} - -\item{tidy}{< \emph{boolean} > // \strong{default:} \code{TRUE} Tidy output} - -\item{na.rm}{< \emph{boolean} > // \strong{default:} \code{TRUE} Remove empty rows and columns} - -\item{...}{Empty} -} -\value{ -A \link[tibble:tibble-package]{tibble} with the following columns: -} -\description{ -\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}} - -\code{\link[=conditions]{conditions()}} allows the user access to data concerning chronic conditions -among Original Medicare (or fee-for-service) beneficiaries. -} -\section{Specific Conditions}{ - - -The \emph{Specific} Chronic Conditions(\code{set = "Specific"}) dataset provides -information on prevalence, use and spending organized by geography and 21 -distinct chronic conditions: -\enumerate{ -\item Alcohol Abuse -\item Alzheimer's Disease/Dementia -\item Arthritis -\item Asthma -\item Atrial Fibrillation -\item Autism Spectrum Disorders -\item Cancer -\item Chronic Kidney Disease -\item COPD -\item Depression -\item Diabetes -\item Drug Abuse/Substance Abuse -\item Heart Failure -\item Hepatitis (Chronic Viral B & C) -\item HIV/AIDS -\item Hyperlipidemia -\item Hypertension -\item Ischemic Heart Disease -\item Osteoporosis -\item Schizophrenia and Other Psychotic Disorders -\item Stroke -} -} - -\section{Multiple Conditions}{ - - -The \emph{Multiple} Chronic Conditions(\code{set = "Multiple"}) dataset provides -information on prevalence, use and spending organized by geography and the -count of chronic conditions from the set of select 21 chronic conditions. -The count of conditions is binned into four categories: -\enumerate{ -\item \strong{0-1} -\item \strong{2-3} -\item \strong{4-5} -\item \strong{6 or More} -} -} - -\section{Prevalence}{ - - -Prevalence estimates are calculated by taking the beneficiaries within the -MCC category divided by the total number of beneficiaries in the -fee-for-service population, expressed as a percentage. -} - -\section{Hospital Readmission Rates}{ - - -Hospital readmissions are expressed as a percentage of all admissions. A -30-day readmission is defined as an admission to an acute care hospital for -any cause within 30 days of discharge from an acute care hospital. Except -when the patient died during the stay, each inpatient stay is classified as -an index admission, a readmission, or both. -} - -\section{Emergency Department Visits}{ - - -Emergency department visits are presented as the number of visits per 1,000 -beneficiaries. ED visits include visits where the beneficiary was released -from the outpatient setting and where the beneficiary was admitted to an -inpatient setting. -} - -\section{Payment Per Capita}{ - - -Medicare spending includes total Medicare payments for all covered services -in Parts A and B and is presented per beneficiary (i.e. per capita). -Standardized payments are presented to allow for comparisons across -geographic areas in health care use among beneficiaries. -} - -\section{Links}{ - -\itemize{ -\item \href{https://data.cms.gov/medicare-chronic-conditions/multiple-chronic-conditions}{Medicare Multiple Chronic Conditions} -\item \href{https://data.cms.gov/medicare-chronic-conditions/specific-chronic-conditions}{Medicare Specific Chronic Conditions} -} -} - -\examples{ -\dontshow{if (interactive()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} -conditions(year = 2018, - set = "Specific", - sublevel = "CA", - demo = "All") - -conditions(year = 2018, - set = "Specific", - sublevel = "CA", - subdemo = "Female", - age = "All") - -conditions(year = 2018, - set = "Multiple", - sublevel = "California", - subdemo = "Female") - -conditions(year = 2007, - set = "Specific", - level = "National", - demo = "Race", - condition = "Alzheimer's Disease/Dementia") - -conditions(year = 2007, - set = "Multiple", - level = "National", - demo = "Race") -\dontshow{\}) # examplesIf} -} diff --git a/man/provider-package.Rd b/man/provider-package.Rd index 65c29db2..0234ef4b 100644 --- a/man/provider-package.Rd +++ b/man/provider-package.Rd @@ -18,7 +18,7 @@ Useful links: } \author{ -\strong{Maintainer}: Andrew Bruce \email{andrew.bruce@northstarrevenueintegrity.com} [copyright holder] +\strong{Maintainer}: Andrew Bruce \email{andrewallenbruce@gmail.com} [copyright holder] } \keyword{internal} diff --git a/man/utilization.Rd b/man/utilization.Rd index b690b133..d9f0774f 100644 --- a/man/utilization.Rd +++ b/man/utilization.Rd @@ -38,73 +38,74 @@ utilization( utilization_(year = util_years(), ...) } \arguments{ -\item{year}{< \emph{integer} > // \strong{required} Year data was reported, in \code{YYYY} -format. Run \code{\link[=util_years]{util_years()}} to return a vector of the years currently available.} +\item{year}{\verb{} // \strong{required} Year data was reported, in \code{YYYY} format. +Run \code{\link[=util_years]{util_years()}} to return a vector of the years currently available.} -\item{type}{< \emph{character} > // \strong{required} dataset to query, \code{"Provider"}, +\item{type}{\verb{} // \strong{required} dataset to query, \code{"Provider"}, \code{"Service"}, \code{"Geography"}} -\item{npi}{< \emph{integer} > 10-digit national provider identifier} +\item{npi}{\verb{} 10-digit national provider identifier} -\item{first, last, organization}{< \emph{character} > Individual/Organizational -provider's name} +\item{first, last, organization}{\verb{} Individual/Organizational provider's +name} -\item{credential}{< \emph{character} > Individual provider's credentials} +\item{credential}{\verb{} Individual provider's credentials} -\item{gender}{< \emph{character} > Individual provider's gender; \code{"F"} (Female), -\code{"M"} (Male)} +\item{gender}{\verb{} Individual provider's gender; \code{"F"} (Female), \code{"M"} +(Male)} -\item{entype}{< \emph{character} > Provider entity type; \code{"I"} (Individual), -\code{"O"} (Organization)} +\item{entype}{\verb{} Provider entity type; \code{"I"} (Individual), \code{"O"} +(Organization)} -\item{city}{< \emph{character} > City where provider is located} +\item{city}{\verb{} City where provider is located} -\item{state}{< \emph{character} > State where provider is located} +\item{state}{\verb{} State where provider is located} -\item{zip}{< \emph{character} > Provider’s zip code} +\item{zip}{\verb{} Provider’s zip code} -\item{fips}{< \emph{character} > Provider's state's FIPS code} +\item{fips}{\verb{} Provider's state's FIPS code} -\item{ruca}{< \emph{character} > Provider’s RUCA code} +\item{ruca}{\verb{} Provider’s RUCA code} -\item{country}{< \emph{character} > Country where provider is located} +\item{country}{\verb{} Country where provider is located} -\item{specialty}{< \emph{character} > Provider specialty code reported on the -largest number of claims submitted} +\item{specialty}{\verb{} Provider specialty code reported on the largest +number of claims submitted} -\item{par}{< \emph{boolean} > Identifies whether the provider participates in -Medicare and/or accepts assignment of Medicare allowed amounts} +\item{par}{\verb{} Identifies whether the provider participates in Medicare +and/or accepts assignment of Medicare allowed amounts} -\item{level}{< \emph{character} > Geographic level by which the data will be -aggregated: +\item{level}{\verb{} Geographic level by which the data will be aggregated: \itemize{ \item \code{"State"}: Data is aggregated for each state \item \code{"National"}: Data is aggregated across all states for a given HCPCS Code }} -\item{hcpcs}{< \emph{character} > HCPCS code used to identify the specific -medical service furnished by the provider} +\item{hcpcs}{\verb{} HCPCS code used to identify the specific medical service +furnished by the provider} -\item{drug}{< \emph{boolean} > Identifies whether the HCPCS code is listed in the +\item{drug}{\verb{} Identifies whether the HCPCS code is listed in the Medicare Part B Drug Average Sales Price (ASP) File} -\item{pos}{< \emph{character} > Identifies whether the Place of Service (POS) -submitted on the claims is a: +\item{pos}{\verb{} Identifies whether the Place of Service (POS) submitted on +the claims is a: \itemize{ \item Facility (\code{"F"}): Hospital, Skilled Nursing Facility, etc. \item Non-facility (\code{"O"}): Office, Home, etc. }} -\item{tidy}{< \emph{boolean} > // \strong{default:} \code{TRUE} Tidy output} +\item{tidy}{\verb{} // \strong{default:} \code{TRUE} Tidy output} -\item{nest}{< \emph{boolean} > // \strong{default:} \code{TRUE} Nest \code{performance}, \code{demographics} and \code{conditions}} +\item{nest}{\verb{} // \strong{default:} \code{TRUE} Nest \code{performance}, \code{demographics} +and \code{conditions} columns} -\item{detailed}{< \emph{boolean} > // \strong{default:} \code{FALSE} Include nested \code{medical} and \code{drug} columns} +\item{detailed}{\verb{} // \strong{default:} \code{FALSE} Include nested \code{medical} and +\code{drug} columns} -\item{rbcs}{< \emph{boolean} > // \strong{default:} \code{TRUE} Add Restructured BETOS +\item{rbcs}{\verb{} // \strong{default:} \code{TRUE} Add Restructured BETOS Classifications to HCPCS codes} -\item{na.rm}{< \emph{boolean} > // \strong{default:} \code{TRUE} Remove empty rows and columns} +\item{na.rm}{\verb{} // \strong{default:} \code{TRUE} Remove empty rows and columns} \item{...}{Pass arguments to \code{\link[=utilization]{utilization()}}.} } diff --git a/man/years.Rd b/man/years.Rd index 5b40fdcf..4a58eb34 100644 --- a/man/years.Rd +++ b/man/years.Rd @@ -6,7 +6,6 @@ \alias{out_years} \alias{rx_years} \alias{util_years} -\alias{cc_years} \alias{qpp_years} \alias{bene_years} \title{Years Currently Searchable for APIs} @@ -19,8 +18,6 @@ rx_years() util_years() -cc_years() - qpp_years() bene_years(period = c("year", "month")) diff --git a/tests/testthat/_snaps/utils.md b/tests/testthat/_snaps/utils.md index 422a065d..cc581846 100644 --- a/tests/testthat/_snaps/utils.md +++ b/tests/testthat/_snaps/utils.md @@ -44,14 +44,14 @@ Code file_url(fn = "c", args = args, offset = 0L) Output - [1] "https://data.cms.gov/provider-data/api/1/datastore/sql?query=%5BSELECT%20%2A%20FROM%20e0a27e9f-abcc-5fe6-b86e-2dad63125545%5D%5BWHERE%20NPI%20=%20%221144544834%22%5D%5BLIMIT%2010000%20OFFSET%200%5D;&show_db_columns" + [1] "https://data.cms.gov/provider-data/api/1/datastore/sql?query=%5BSELECT%20%2A%20FROM%20fd3842af-b247-5cd5-8229-923a0d1f87a3%5D%5BWHERE%20NPI%20=%20%221144544834%22%5D%5BLIMIT%2010000%20OFFSET%200%5D;&show_db_columns" --- Code file_url(fn = "a", args = args, offset = 0L) Output - [1] "https://data.cms.gov/provider-data/api/1/datastore/sql?query=%5BSELECT%20%2A%20FROM%20f91c3db8-f570-5e7e-9607-c170950f26fc%5D%5BWHERE%20NPI%20=%20%221144544834%22%5D%5BLIMIT%2010000%20OFFSET%200%5D;&show_db_columns" + [1] "https://data.cms.gov/provider-data/api/1/datastore/sql?query=%5BSELECT%20%2A%20FROM%20cc079864-b9c6-5df5-bd7f-4cdd873c2d56%5D%5BWHERE%20NPI%20=%20%221144544834%22%5D%5BLIMIT%2010000%20OFFSET%200%5D;&show_db_columns" # format_cli() works diff --git a/tests/testthat/test-conditions.R b/tests/testthat/test-conditions.R deleted file mode 100644 index 5d118233..00000000 --- a/tests/testthat/test-conditions.R +++ /dev/null @@ -1,104 +0,0 @@ -httptest2::without_internet({ - test_that("conditions(set = 'Specific') returns correct request URL", { - httptest2::expect_GET( - conditions(year = 2018, - set = "Specific", - level = "State", - sublevel = "CA", - demo = "Sex", - subdemo = "Female", - age = "65+", - condition = "Asthma", - fips = "06"), - 'https://data.cms.gov/data.json') - }) -}) - -test_that("cols_cc() works", { - x <- dplyr::tibble( - year = 1, - bene_geo_lvl = 1, - bene_geo_desc = 1, - bene_geo_cd = 1, - bene_age_lvl = 1, - bene_demo_lvl = 1, - bene_demo_desc = 1, - bene_mcc = 1, - bene_cond = 1, - prvlnc = 1, - tot_mdcr_pymt_pc = 1, - tot_mdcr_stdzd_pymt_pc = 1, - hosp_readmsn_rate = 1, - er_visits_per_1000_benes = 1) - - y <- dplyr::tibble( - year = 1, - level = 1, - sublevel = 1, - fips = 1, - age = 1, - demographic = 1, - subdemo = 1, - mcc = 1, - condition = 1, - prevalence = 1, - tot_pymt_percap = 1, - tot_std_pymt_percap = 1, - hosp_readmit_rate = 1, - er_visits_per_1k = 1) - expect_equal(cols_cc(x), y) -}) - -test_that("lookup() works", {expect_equal(lookup( - c("0-1" = "0 to 1"), "0-1"), "0 to 1")}) -test_that("levels() works", {expect_equal(levels(), - c("National", "State", "County"))}) -test_that("ages() works", {expect_equal(ages(), - c("All", "<65", "65+"))}) -test_that("demo() works", {expect_equal(demo(), - c("All", "Dual Status", "Sex", "Race"))}) - -test_that("mcc() works", { - expect_equal(mcc(), c("0-1" = "0 to 1", - "2-3" = "2 to 3", - "4-5" = "4 to 5", - "6+" = "6+")) - }) - -test_that("subdemo() works", { - expect_equal(subdemo(), c("All" = "All", - "Nondual" = "Medicare Only", - "Dual" = "Medicare and Medicaid", - "Female" = "Female", - "Male" = "Male", - "Island" = "Asian Pacific Islander", - "Hispanic" = "Hispanic", - "Native" = "Native American", - "Black" = "non-Hispanic Black", - "White" = "non-Hispanic White")) -}) - -test_that("spec_cond() works", { - expect_equal(spec_cond(), c('All' = 'All', - 'Alcohol Abuse' = 'Alcohol Abuse', - "Alzheimer's Disease/Dementia" = "Alzheimer's Disease%2FDementia", - 'Arthritis' = 'Arthritis', - 'Asthma' = 'Asthma', - 'Atrial Fibrillation' = 'Atrial Fibrillation', - 'Autism Spectrum Disorders' = 'Autism Spectrum Disorders', - 'Cancer' = 'Cancer', - 'Chronic Kidney Disease' = 'Chronic Kidney Disease', - 'COPD' = 'COPD', - 'Depression' = 'Depression', - 'Diabetes' = 'Diabetes', - 'Drug Abuse/Substance Abuse' = 'Drug Abuse%2FSubstance Abuse', - 'Heart Failure' = 'Heart Failure', - 'Hepatitis (Chronic Viral B & C)' = 'Hepatitis (Chronic Viral B %26 C)', - 'HIV/AIDS' = 'HIV%2FAIDS', - 'Hyperlipidemia' = 'Hyperlipidemia', - 'Hypertension' = 'Hypertension', - 'Ischemic Heart Disease' = 'Ischemic Heart Disease', - 'Osteoporosis' = 'Osteoporosis', - 'Schizophrenia and Other Psychotic Disorders' = 'Schizophrenia and Other Psychotic Disorders', - 'Stroke' = 'Stroke')) -}) diff --git a/tests/testthat/test-fct.R b/tests/testthat/test-fct.R index f950e24e..5953255f 100644 --- a/tests/testthat/test-fct.R +++ b/tests/testthat/test-fct.R @@ -83,12 +83,6 @@ test_that("fct_subdemo() works", { expect_equal(fct_subdemo(x), y) }) -test_that("fct_mcc() works", { - x <- c("0 to 1", "2 to 3", "4 to 5", "6+") - y <- ordered(c("0-1", "2-3", "4-5", "6+")) - expect_equal(fct_mcc(x), y) -}) - test_that("fct_part() works", { x <- c("Group", "Individual", "MIPS APM") y <- factor(c("Group", "Individual", "MIPS APM")) @@ -259,17 +253,6 @@ test_that("fct_maj() works", { expect_equal(fct_maj(x), factor(y, levels = y)) }) -test_that("fct_cc() works", { - x <- c( - "All", "Alcohol Abuse", "Alzheimer's Disease/Dementia", "Arthritis", - "Asthma", "Atrial Fibrillation", "Autism Spectrum Disorders", "Cancer", - "Chronic Kidney Disease", "COPD", "Depression", "Diabetes", - "Drug Abuse/Substance Abuse", "Heart Failure", - "Hepatitis (Chronic Viral B & C)", "HIV/AIDS", "Hyperlipidemia", - "Hypertension", "Ischemic Heart Disease", "Osteoporosis", - "Schizophrenia and Other Psychotic Disorders", "Stroke") - expect_equal(fct_cc(x), ordered(x, levels = x)) -}) test_that("fct_record() works", { x <- c("Physician Assistant", "Reassignment") diff --git a/tests/testthat/test-years.R b/tests/testthat/test-years.R index 58f715d9..d59cc59c 100644 --- a/tests/testthat/test-years.R +++ b/tests/testthat/test-years.R @@ -31,14 +31,6 @@ test_that("rx_years() works", { }) -# test_that("cc_years() works", { -# -# cc <- cc_years() -# expect_equal(cc, 2007:2018) -# expect_vector(cc, ptype = integer(), size = 12) -# -# }) - test_that("qpp_years() works", { qpp <- qpp_years() diff --git a/vignettes/articles/partb-stats.Rmd b/vignettes/articles/partb-stats.Rmd index c4c23047..c058c6b5 100644 --- a/vignettes/articles/partb-stats.Rmd +++ b/vignettes/articles/partb-stats.Rmd @@ -43,9 +43,6 @@ future::plan(multisession, workers = 4) ind <- utilization_(npi = 1043477615, type = "Provider") # Retrieve provider's utilization data by HCPCS srvc <- utilization_(npi = 1023076643, type = "Service") - -# Retrieve state & national chronic condition data to compare with -chronic <- compare_conditions(ind) # Retrieve state & national HCPCS data to compare with hcpcs <- compare_hcpcs(srvc) @@ -286,35 +283,3 @@ ind |>
- -### Comparison: Chronic Conditions - - -```{r} -chronic |> - # filter(prevalence > 0) - # filter(!if_any(contains("20"), ~ . <= 0)) |> - pivot_wider(names_from = year, - values_from = prevalence) |> - gt(rowname_col = "level") |> - fmt_percent(columns = contains('0'), decimals = 0) |> - opt_table_font(font = google_font(name = "JetBrains Mono")) |> - sub_missing(missing_text = "") |> - cols_nanoplot( - columns = starts_with("20"), - plot_type = "bar", - new_col_name = "change", - new_col_label = "change", - missing_vals = "remove", - options = nanoplot_options( - show_data_line = FALSE, - show_data_area = FALSE, - data_bar_stroke_color = "transparent" - ) - ) -``` - - - - -