diff --git a/.Rbuildignore b/.Rbuildignore index 35d9d81..602c105 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -1,14 +1,16 @@ -^nhp_reskit[.]Rproj$ -^[.]Rproj[.]user$ -^LICENSE[.]md$ -^CODEOWNERS$ -^[.]github$ -^nhp_reskit[.]code-workspace$ -^CODEOWNERS$ -^[.]vscode$ -^air[.]toml$ -^[.]Renviron[.]example$ -^inst/a_.*$ -^test_results[.]rds$ -^[.]lintr$ -^jarl[.]toml$ +^nhp_reskit[.]Rproj$ +^[.]Rproj[.]user$ +^LICENSE[.]md$ +^CODEOWNERS$ +^[.]github$ +^nhp_reskit[.]code-workspace$ +^CODEOWNERS$ +^[.]vscode$ +^air[.]toml$ +^[.]Renviron[.]example$ +^inst/a_.*$ +^test_results[.]rds$ +^[.]lintr$ +^jarl[.]toml$ +^vignettes/\.quarto$ +^vignettes/*_files$ diff --git a/.Renviron.example b/.Renviron.example index 2ec62af..1fb6340 100644 --- a/.Renviron.example +++ b/.Renviron.example @@ -4,3 +4,7 @@ # might be more appropriately kept as project-specific values.) # Contact a member of SU Data Science to get the required values for these. AZ_STORAGE_EP = +AZ_TABLE_EP = +RESKIT_GITHUB_APP_PAT= +RESKIT_GITHUB_APP_PRIVATE_KEY= +RESKIT_GITHUB_APP_ID= diff --git a/.gitignore b/.gitignore index 4056b96..4bd5bef 100644 --- a/.gitignore +++ b/.gitignore @@ -1,97 +1,99 @@ -# History files -.Rhistory -.Rapp.history - -# Session Data files -.RData -.RDataTmp - -# User-specific files -.Ruserdata - -# Example code in package build process -*-Ex.R - -# Output files from R CMD build -/*.tar.gz - -# Output files from R CMD check -/*.Rcheck/ - -# RStudio files -.Rproj.user/ - -# produced vignettes -vignettes/*.html -vignettes/*.pdf - -# OAuth2 token, see https://github.com/hadley/httr/releases/tag/v0.3 -.httr-oauth - -# knitr and R markdown default cache directories -*_cache/ -/cache/ - -# Temporary files created by R markdown -*.utf8.md -*.knit.md - -# Quarto rendered files and artefacts -*.files/ - -# R Environment Variables -.Renviron - -# pkgdown site -docs/ - -# translation temp files -po/*~ - -# RStudio Connect folder -rsconnect/ - -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] -*$py.class - -# Unit test / coverage reports -htmlcov/ -.tox/ -.nox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*.cover -*.py,cover -.hypothesis/ -.pytest_cache/ -cover/ - -# Jupyter Notebook -.ipynb_checkpoints - -# IPython -profile_default/ -ipython_config.py - -# Environments -.env -.venv -env/ -venv/ -ENV/ -env.bak/ -venv.bak/ -/.quarto/ - -# VSCode extensions/settings -/.vscode/ - -inst/a_sort* -!inst/a_sort*.qmd - -*.rds +# History files +.Rhistory +.Rapp.history + +# Session Data files +.RData +.RDataTmp + +# User-specific files +.Ruserdata + +# Example code in package build process +*-Ex.R + +# Output files from R CMD build +/*.tar.gz + +# Output files from R CMD check +/*.Rcheck/ + +# RStudio files +.Rproj.user/ + +# produced vignettes +vignettes/*.html +vignettes/*.pdf + +# OAuth2 token, see https://github.com/hadley/httr/releases/tag/v0.3 +.httr-oauth + +# knitr and R markdown default cache directories +*_cache/ +/cache/ + +# Temporary files created by R markdown +*.utf8.md +*.knit.md + +# Quarto rendered files and artefacts +*.files/ + +# R Environment Variables +.Renviron + +# pkgdown site +docs/ + +# translation temp files +po/*~ + +# RStudio Connect folder +rsconnect/ + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ +/.quarto/ + +# VSCode extensions/settings +/.vscode/ + +inst/a_sort* +!inst/a_sort*.qmd + +*.rds +inst/doc +**/.quarto/ diff --git a/DESCRIPTION b/DESCRIPTION index f27e81b..57f2e1c 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: reskit Title: Nice selection box of goodies for hobnobbing with NHP model results -Version: 1.0.2 +Version: 1.1.0 Authors@R: c(person( "Fran", "Barton", @@ -27,7 +27,7 @@ Roxygen: list(markdown = TRUE) Config/testthat/edition: 3 Depends: R (>= 4.5.0) Imports: - azkit (>= 0.3.0), + azkit (>= 0.3.2), base64enc, dplyr, forcats, @@ -48,8 +48,11 @@ Remotes: The-Strategy-Unit/azkit Suggests: here, + knitr, + quarto, readr, testthat (>= 3.0.0), tibble, withr Config/roxygen2/version: 8.0.0 +VignetteBuilder: quarto diff --git a/R/demo_results_tables.R b/R/demo_results_tables.R new file mode 100644 index 0000000..0261d6f --- /dev/null +++ b/R/demo_results_tables.R @@ -0,0 +1,369 @@ +#' Function to create a "default" table with synthetic values +#' +#' The table contains synthetic (randomly created) values for a selection of +#' PODs and measures, across 2 "sites", as if created by 64 model runs +#' @param seed integer, for reproducibility of outputs, a seed value to be used +#' @keywords internal +create_demo_default_tbl <- function(seed) { + init_tbl1 <- create_base_tbl_with_sitetret("site1") + init_tbl2 <- create_base_tbl_with_sitetret("site2") + baseline_tbl1 <- add_baseline_values(init_tbl1, c(5e3L, 85e3L), 1e3L, seed) + baseline_tbl2 <- add_baseline_values(init_tbl2, c(3e3L, 45e3L), 1e3L, seed) + initial_means <- get_full_initial_means(0.8, 0.9, 1) + horizon_tbl1 <- add_horizon_values(baseline_tbl1, initial_means, seed) + horizon_tbl2 <- add_horizon_values(baseline_tbl2, initial_means, seed) + dplyr::bind_rows(horizon_tbl1, horizon_tbl2) |> + dplyr::arrange(dplyr::pick(c("pod", "sitetret", "measure", "model_run"))) +} + + +#' Function to create a "tretspef + LoS group" table with synthetic values +#' The table contains synthetic (randomly created) values for a selection of +#' PODs, tretspefs, LoS groups and measures, across 2 "sites", as if created +#' by 64 model runs +#' @inheritParams create_demo_default_tbl +#' @keywords internal +create_demo_tretspef_losgroup_tbl <- function(seed) { + tretspef_codes <- sort(sample(get_tretspef_lookup()[["code"]], 25)) |> + withr::with_seed(seed = seed) + los_groups <- paste0( + c("0", "1", "2", "3", "4-7", "8-14", "15-21", "22+"), + " days" + ) |> + sub("^1 days$", "1 day", x = _) + init_tbl1 <- create_ip_base_tbl() |> + dplyr::mutate( + sitetret = "site1", + tretspef = list(tretspef_codes), + los_group = list(los_groups), + .after = "pod" + ) |> + tidyr::unnest_longer("tretspef") |> + tidyr::unnest_longer("los_group") |> + tidyr::expand( + tidyr::nesting(pod, measure, sitetret), + tretspef, + los_group + ) |> + dplyr::relocate("measure", .after = dplyr::last_col()) + init_tbl2 <- dplyr::mutate(init_tbl1, sitetret = "site2") + baseline_tbl1 <- add_baseline_values(init_tbl1, c(100L, 5e3L), 100L, seed) + baseline_tbl2 <- add_baseline_values(init_tbl2, c(100L, 2e3L), 100L, seed) + horizon_tbl1 <- add_horizon_values(baseline_tbl1, 0.85, seed) + horizon_tbl2 <- add_horizon_values(baseline_tbl2, 0.85, seed) + dplyr::bind_rows(horizon_tbl1, horizon_tbl2) |> + dplyr::arrange(dplyr::pick(c( + "pod", + "sitetret", + "tretspef", + "los_group", + "measure", + "model_run" + ))) +} + + +#' Function to create a "tretspef + age group" table with synthetic values +#' The table contains synthetic (randomly created) values for a selection of +#' PODs, tretspefs, age groups and measures, across 2 "sites", as if created +#' by 64 model runs +#' @inheritParams create_demo_default_tbl +#' @keywords internal +create_demo_sex_agegroup_tbl <- function(seed) { + # fmt: skip + age_groups <- c( + "0", "1-4", "10-15", "16-17", "18-34", "35-49", "5-9", + "50-64", "65-74", "75-84", "85+" + ) + init_tbl1 <- create_base_tbl_with_sitetret("site1") |> + dplyr::mutate( + sex = list(seq(2)), + age_group = list(age_groups), + .after = "sitetret" + ) |> + tidyr::unnest_longer("sex") |> + tidyr::unnest_longer("age_group") |> + tidyr::expand(tidyr::nesting(pod, measure, sitetret), sex, age_group) |> + dplyr::relocate("measure", .after = dplyr::last_col()) + init_tbl2 <- dplyr::mutate(init_tbl1, sitetret = "site2") + baseline_tbl1 <- add_baseline_values(init_tbl1, c(2e3L, 5e4L), 100L, seed) + baseline_tbl2 <- add_baseline_values(init_tbl2, c(1e3L, 2e4L), 100L, seed) + multip <- length(seq(2)) * length(age_groups) + initial_values <- rep(get_full_initial_means(0.9, 0.85, 0.8), each = multip) + horizon_tbl1 <- add_horizon_values(baseline_tbl1, initial_values, seed) + horizon_tbl2 <- add_horizon_values(baseline_tbl2, initial_values, seed) + dplyr::bind_rows(horizon_tbl1, horizon_tbl2) |> + dplyr::arrange(dplyr::pick(c( + "pod", + "sitetret", + "sex", + "age_group", + "measure", + "model_run" + ))) +} + + +#' Function to create a "sex + tretspef_grouped" table with synthetic values +#' The table contains synthetic (randomly created) values for 2 sexes, a +#' selection of tretspef group codes, and measures, across 2 "sites", as if +#' created by 64 model runs +#' @inheritParams create_demo_default_tbl +#' @keywords internal +create_demo_sex_tretspef_tbl <- function(seed) { + # fmt: skip + tretspef_groups <- c( + "100", "101", "110", "120", "130", "140", "150", "160", "170", + "300", "301", "320", "330", "340", "400", "410", "430", "Other" + ) + init_tbl1 <- list(create_ip_base_tbl(), create_op_base_tbl()) |> + purrr::list_rbind() |> + dplyr::mutate( + sitetret = "site1", + sex = list(seq(2)), + tretspef_grouped = list(tretspef_groups), + .after = "pod" + ) |> + tidyr::unnest_longer("sex") |> + tidyr::unnest_longer("tretspef_grouped") + init_tbl2 <- dplyr::mutate(init_tbl1, sitetret = "site2") + baseline_tbl1 <- add_baseline_values(init_tbl1, c(500L, 4.5e3L), 100L, seed) + baseline_tbl2 <- add_baseline_values(init_tbl2, c(100L, 2.2e3L), 100L, seed) + multip <- length(seq(2)) * length(tretspef_groups) + initial_values <- rep(get_ipop_initial_means(0.8, 0.85), each = multip) + horizon_tbl1 <- add_horizon_values(baseline_tbl1, initial_values, seed) + horizon_tbl2 <- add_horizon_values(baseline_tbl2, initial_values, seed) + dplyr::bind_rows(horizon_tbl1, horizon_tbl2) |> + dplyr::arrange(dplyr::pick(c( + "pod", + "sitetret", + "sex", + "tretspef_grouped", + "measure", + "model_run" + ))) +} + + +#' Function to create a "step_counts" table with synthetic values +#' The table contains synthetic (randomly created) values for a selection of +#' 64 model runs, providing random baselines, random sizes of mitigated +#' activity across a subset of TPMAs, and random values for demographic growth +#' @inheritParams create_demo_default_tbl +#' @keywords internal +create_demo_stepcounts_tbl <- function(seed) { + tpma_lookup <- get_tpma_label_lookup() + # for this demo table, we can just include a subset of all strategies + n_strategies <- 40 + strategies <- dplyr::slice_sample(tpma_lookup, n = n_strategies) |> + withr::with_seed(seed = seed) |> + dplyr::select(!"tpma_label") + core_cols <- c("sitetret", "pod", "measure") + init_tbl1 <- create_base_tbl_with_sitetret("site1") |> + dplyr::mutate(dplyr::across("measure", \(x) { + dplyr::if_else(x %in% c("walk-in", "ambulance"), "arrivals", x) + })) |> + dplyr::distinct() |> + dplyr::filter_out(.data[["measure"]] == "procedures") |> + get_activity_type_from_pod() |> + dplyr::inner_join( + strategies, + by = "activity_type", + relationship = "many-to-many" + ) |> + dplyr::filter_out( + dplyr::when_any( + .data[["measure"]] == "tele_attendances" & + grepl("^convert_to_tele", .data[["strategy"]]) + ) + ) |> + tidyr::nest(.by = c("activity_type", tidyselect::all_of(core_cols))) + init_tbl2 <- dplyr::mutate(init_tbl1, sitetret = "site2") + init_tbl <- dplyr::bind_rows(init_tbl1, init_tbl2) + demo_data <- create_demo_default_tbl(seed) |> + dplyr::mutate(dplyr::across("measure", \(x) { + dplyr::if_else(x %in% c("walk-in", "ambulance"), "arrivals", x) + })) |> + dplyr::summarise(dplyr::across("value", sum), .by = !"value") + baseline_data <- demo_data |> + dplyr::filter(.data[["model_run"]] == 0L) |> + dplyr::select(!"model_run") |> + dplyr::rename(baseline = "value") + horizon_data <- demo_data |> + dplyr::filter(.data[["model_run"]] > 0L) |> + dplyr::rename(horizon = "value") + baseline_tbl <- init_tbl |> + dplyr::left_join(baseline_data, core_cols) |> + dplyr::left_join(horizon_data, core_cols) |> + dplyr::mutate(mitigation = .data[["baseline"]] - .data[["horizon"]]) + dgf_values <- withr::with_seed(seed, rnorm(nrow(baseline_tbl), 1, 0.1)) + dgf_values <- dgf_values * (baseline_tbl[["baseline"]] * 0.1) + impact_tbl <- baseline_tbl |> + dplyr::mutate( + demographic_adjustment = dgf_values, + impact_data = purrr::map2( + .data[["data"]], + .data[["mitigation"]], + \(x, y) create_sample_impacts(x, y, seed) + ) + ) + cfs <- c("baseline", "demographic_adjustment", "model_interaction_term") + id_cols <- c("activity_type", core_cols, "model_run", "change_factor") + impact_tbl |> + dplyr::select(!c("data")) |> + tidyr::nest( + horizon_data = c( + "model_run", + "horizon", + "mitigation", + "demographic_adjustment" + ) + ) |> + dplyr::mutate(dplyr::across("horizon_data", \(x) { + purrr::map2(x, .data[["impact_data"]], \(x, y) { + dplyr::inner_join(x, y, "model_run") + }) + })) |> + dplyr::select(!"impact_data") |> + tidyr::unnest("horizon_data") |> + dplyr::mutate( + total_mitigation = sum(.data[["value"]]), + model_interaction_term = .data[["mitigation"]] - + (.data[["total_mitigation"]] - .data[["demographic_adjustment"]]), + .by = tidyselect::all_of(c(core_cols, "model_run")) + ) |> + dplyr::select(!c("horizon", "mitigation", "total_mitigation")) |> + tidyr::pivot_wider(names_from = "strategy") |> + tidyr::pivot_longer( + !tidyselect::all_of(id_cols), + names_to = "strategy", + values_drop_na = TRUE + ) |> + dplyr::mutate( + dplyr::across("change_factor", \(x) { + dplyr::if_else(.data[["strategy"]] %in% cfs, .data[["strategy"]], x) + }), + dplyr::across("strategy", \(x) dplyr::if_else(x %in% cfs, "-", x)) + ) +} + + +#' Helper function +#' @keywords internal +create_sample_impacts <- function(dat, mitigation, seed, picks = 64) { + n_rows <- nrow(dat) + n_zeros <- round(0.2 * n_rows * picks) + n_picks <- (n_rows * picks) - n_zeros + mitigation_mean <- abs(mitigation) / n_rows + mitigation_dist <- withr::with_seed(seed, rnorm(n_picks, 1, 0.1)) + mitigation_dist <- mitigation_dist * mitigation_mean + + impacts <- sample(c(rep(0, n_zeros), mitigation_dist), n_rows * picks) |> + withr::with_seed(seed = seed) + impacts_tbl <- tibble::tibble( + rn = rep(seq(n_rows), each = picks), + model_run = rep(seq(picks), n_rows), + value = impacts + ) + dat |> + dplyr::mutate(rn = dplyr::row_number()) |> + dplyr::left_join(impacts_tbl, "rn") |> + dplyr::select(!"rn") |> + dplyr::mutate(dplyr::across("value", \(x) abs(x) * -1)) +} + + +#' Helper function +#' @param site A string giving the name/code of an imaginary site +#' @keywords internal +create_base_tbl_with_sitetret <- function(site) { + list(create_ae_base_tbl(), create_ip_base_tbl(), create_op_base_tbl()) |> + purrr::list_rbind() |> + dplyr::mutate(sitetret = {{ site }}, .after = "pod") +} + + +#' Helper function +#' @keywords internal +add_baseline_values <- function(base_tbl, baseline_range, step = 100L, seed) { + stopifnot(length(baseline_range) == 2) + baseline_range <- as.integer(baseline_range) + step <- as.integer(step) + poss_baselines <- seq(min(baseline_range), max(baseline_range), step) + baseline_values <- sample(poss_baselines, nrow(base_tbl), TRUE) |> + withr::with_seed(seed = seed) + dplyr::mutate(base_tbl, model_run = 0L, value = baseline_values) +} + + +#' Helper function +#' @keywords internal +add_horizon_values <- function(tbl_with_baseline, initial_means, seed) { + distrib_values <- rnorm(nrow(tbl_with_baseline), 1, 0.1) |> + withr::with_seed(seed = seed) + mitigations <- distrib_values * initial_means + ghv_partial <- purrr::partial(generate_horizon_values, seed = seed) + horizons_tbl <- tbl_with_baseline |> + dplyr::select(!"model_run") |> + dplyr::mutate( + dplyr::across("value", \(x) purrr::map2(x, mitigations, ghv_partial)) + ) |> + tidyr::unnest_longer("value", indices_to = "model_run") |> + dplyr::mutate(dplyr::across("value", \(x) as.integer(round(x)))) + dplyr::bind_rows(tbl_with_baseline, horizons_tbl) +} + +#' Helper function +#' @keywords internal +generate_horizon_values <- function(baseline, mitigation, seed, picks = 64) { + distr <- withr::with_seed(seed, rnorm(picks, 1, 0.1)) + as.integer(round(distr * mitigation * baseline)) +} + + +#' Helper function +#' @keywords internal +create_ae_base_tbl <- function() { + ae_pods <- paste0("aae_type-0", seq(5)) + ae_measures <- c("ambulance", "walk-in") + tidyr::expand_grid(pod = ae_pods, measure = ae_measures) +} + +#' Helper function +#' @keywords internal +create_ip_base_tbl <- function() { + ip_pods <- c( + paste0("ip_", c("elective", "maternity", "non-elective"), "_admission"), + paste0("ip_regular_", c("night", "day"), "_attender") + ) + ip_measures <- c("admissions", "beddays", "procedures") + tidyr::expand_grid(pod = ip_pods, measure = ip_measures) +} + +#' Helper function +#' @keywords internal +create_op_base_tbl <- function() { + op_pods <- paste0("op_", c("first", "follow-up", "procedure")) + op_measures <- paste0(c("", "tele_"), "attendances") + tidyr::expand_grid(pod = op_pods, measure = op_measures) +} + +#' Helper function +#' @keywords internal +get_full_initial_means <- function(ae_mean, ip_mean, op_mean) { + c( + rep(ae_mean, nrow(create_ae_base_tbl())), + rep(ip_mean, nrow(create_ip_base_tbl())), + rep(op_mean, nrow(create_op_base_tbl())) + ) +} + + +#' Helper function +#' @keywords internal +get_ipop_initial_means <- function(ip_mean, op_mean) { + c( + rep(ip_mean, nrow(create_ip_base_tbl())), + rep(op_mean, nrow(create_op_base_tbl())) + ) +} diff --git a/R/distribution_plots.R b/R/distribution_plots.R index 1e0cb43..c5ff046 100644 --- a/R/distribution_plots.R +++ b/R/distribution_plots.R @@ -80,7 +80,7 @@ make_cumulative_distrib_plot <- function(distrib_plot_data, show_zero = FALSE) { x_end = rep(c(x_quantiles, principal_value), 2), y_start = c(quantiles, principal_pct, rep(0, 3)), y_end = rep(c(quantiles, principal_pct), 2), - colour = rep(c(rep(plot_red, 2), plot_blue), 2) + colour = rep(c(rep(plot_blue, 2), plot_red), 2) ) interim_plot <- tibble::tibble(x = x_vals, y = y_vals) |> ggplot2::ggplot(ggplot2::aes(.data[["x"]], .data[["y"]])) + diff --git a/R/get_github_file.R b/R/get_github_file.R index ef8eebe..8f10699 100644 --- a/R/get_github_file.R +++ b/R/get_github_file.R @@ -1,48 +1,42 @@ -#' Read in a file from the NHP Outputs app GitHub repo +#' Get the direct URL to a file in the NHP Outputs GitHub repo #' -#' @param file string. The name of the file to read in -#' @param folder string. The folder where the file is located. `"inst"` by -#' default. Set to `""` to use the root folder of the repo. -#' @returns The file contents as a stream, to be passed to a reader function +#' @param ... Pass the name of the file in via `...` #' @keywords internal -get_outputs_gh_file <- function(file, folder = "inst") { - httr2::request("https://api.github.com") |> - httr2::req_url_path_append("repos") |> - httr2::req_url_path_append("The-Strategy-Unit") |> - httr2::req_url_path_append("nhp_outputs") |> - httr2::req_url_path_append("contents") |> - httr2::req_url_path_append(folder) |> - httr2::req_url_path_append(file) |> - httr2::req_perform() |> - httr2::resp_check_status() |> - httr2::resp_body_json() |> - purrr::pluck("content") |> - base64enc::base64decode() +get_outputs_gh_url <- function(...) { + purrr::partial(get_su_gh_file, repo = "nhp_outputs", folder = "inst")(...) } - -#' Read in a file from the TPMAs GitHub repo +#' Get the direct URL to a file in the TPMAs GitHub repo #' -#' @param file string. The name of the file to read in -#' @param folder string. The folder where the file is located. `"reference"` by -#' default. Set to `""` to use the root folder of the repo. -#' @returns The file contents as a stream, to be passed to a reader function +#' @inheritParams get_outputs_gh_url #' @keywords internal -get_tpmas_gh_file <- function(file, folder = "reference") { - httr2::request("https://api.github.com") |> - httr2::req_url_path_append("repos") |> - httr2::req_url_path_append("The-Strategy-Unit") |> - httr2::req_url_path_append("TPMAs") |> - httr2::req_url_path_append("contents") |> - httr2::req_url_path_append(folder) |> - httr2::req_url_path_append(file) |> - httr2::req_perform() |> - httr2::resp_check_status() |> - httr2::resp_body_json() |> - purrr::pluck("content") |> - base64enc::base64decode() +get_tpmas_gh_url <- function(...) { + purrr::partial(get_su_gh_file, repo = "TPMAs", folder = "reference")(...) } +#' Read the pods lookup table from a YAML file in the NHP Outputs repo +read_pods_lookup <- function(file = "golem-config.yml") { + yaml12::parse_yaml(readr::read_lines(get_outputs_gh_url(file))) +} +possibly_read_pods_lookup <- \(...) purrr::possibly(read_pods_lookup)(...) + +#' Read the TPMAs lookup table from a CSV file in the TPMAs repo +read_tpmas_lookup <- function(file = "tpma-lookup.csv") { + readr::read_csv(get_tpmas_gh_url(file), col_types = "-ccccc---c") +} +possibly_read_tpmas_lookup <- \(...) purrr::possibly(read_tpmas_lookup)(...) -possibly_get_outputs_gh_file <- \(...) purrr::possibly(get_outputs_gh_file)(...) -possibly_get_tpmas_gh_file <- \(...) purrr::possibly(get_tpmas_gh_file)(...) + +#' Read in a file from a Strategy Unit GitHub repo +#' +#' @param repo string. The name of the repository in which to find the file +#' @param folder string. The folder where the file is located. Set to `""` to +#' use the root folder of the repo. +#' @param file string. The name of the file to read in +#' @returns The URL to the raw file contents, to be passed to a reader function +#' @keywords internal +get_su_gh_file <- function(repo, folder, file) { + raw_base_url <- "https://raw.githubusercontent.com" + su <- "The-Strategy-Unit" + file.path(raw_base_url, su, repo, "refs", "heads", "main", folder, file) +} diff --git a/R/get_principal_pods.R b/R/get_principal_pods.R index 0adb092..6e8b315 100644 --- a/R/get_principal_pods.R +++ b/R/get_principal_pods.R @@ -1,35 +1,19 @@ #' Prepare a lookup table with activity type labels and PoD labels for each PoD #' -#' @param use_local logical. Whether to use a local file (internal to the -#' reskit package) or attempt to pull the lookup file from GitHub. Default is -#' `FALSE`, meaning it will use the GitHub route. If you want to always use a -#' local file (for example, for fully offline working), you can set the -#' `reskit.local.lookups` option to `TRUE` using -#' `options(reskit.local.lookups = TRUE)` or `withr::with_options()` #' @returns A tibble #' @export -get_detailed_pods <- function(use_local = FALSE) { - use_local <- getOption("reskit.local.lookups") %||% use_local - yaml_data <- system.file("pod_measures.yml", package = "reskit") |> - yaml12::read_yaml() - yaml_data_from_gh <- NULL - if (!use_local) { - yaml_raw <- possibly_get_outputs_gh_file("golem-config.yml") - if (!is.null(yaml_raw)) { - yaml_data_from_gh <- yaml12::parse_yaml(readr::read_lines(yaml_raw)) |> - purrr::pluck("default") - } - } - yaml_data <- yaml_data_from_gh %||% yaml_data +get_detailed_pods <- function() { + yaml_data <- possibly_read_pods_lookup() + msg <- "Unable to read POD lookup file from GitHub" + azkit::check_that(yaml_data, is_not_null, msg) yaml_data |> - purrr::pluck("pod_measures") |> + purrr::pluck("default", "pod_measures") |> purrr::map(list_to_tbl) |> purrr::list_rbind() |> dplyr::mutate( dplyr::across("pod_label", forcats::fct_inorder), - dplyr::across("activity_type_label", \(x) sub("patients$", "patient", x)), dplyr::across("activity_type_label", \(x) { - forcats::fct(x, levels = c("Inpatient", "Outpatient", "A&E")) + forcats::fct(x, levels = c("Inpatients", "Outpatients", "A&E")) }) ) } @@ -38,12 +22,12 @@ get_detailed_pods <- function(use_local = FALSE) { #' Prepare a lookup table with activity type labels and PoD labels for each PoD #' #' This function condenses all A&E activity to a single category - compare -#' `get_detailed_pods()` which _keeps_ all A&E categories +#' [get_detailed_pods] which _keeps_ all A&E categories #' @rdname get_detailed_pods #' @returns A tibble #' @export -get_principal_pods <- function(use_local = FALSE) { - get_detailed_pods(use_local) |> +get_principal_pods <- function() { + get_detailed_pods() |> dplyr::filter(dplyr::if_any("activity_type_label", \(x) x != "A&E")) |> dplyr::add_row( activity_type_label = "A&E", @@ -53,7 +37,7 @@ get_principal_pods <- function(use_local = FALSE) { dplyr::mutate( dplyr::across("pod_label", forcats::fct_inorder), dplyr::across("activity_type_label", \(x) { - forcats::fct(x, levels = c("Inpatient", "Outpatient", "A&E")) + forcats::fct(x, levels = c("Inpatients", "Outpatients", "A&E")) }) ) } diff --git a/R/helpers.R b/R/helpers.R index 30b29c9..ab2ee47 100644 --- a/R/helpers.R +++ b/R/helpers.R @@ -120,6 +120,7 @@ relabel_ip_activity_types <- function(tbl) { tbl |> dplyr::mutate( dplyr::across("activity_type_label", \(x) { + x <- sub("s$", "", x) dplyr::if_else( x == "Inpatient", paste0(x, " ", uppercase_init(.data[["measure"]])), @@ -177,36 +178,37 @@ get_tretspef_lookup <- function() { #' Prepare a lookup table for all current TPMAs #' -#' @param use_local logical. Whether to use a local file (internal to the -#' reskit package) or attempt to pull the lookup file from GitHub. Default is -#' `FALSE`, meaning it will use the GitHub route. If you want to always use a -#' local file (for example, for fully offline working), you can set the -#' `reskit.local.lookups` option to `TRUE` using -#' `options(reskit.local.lookups = TRUE)` or `withr::with_options()` -#' @returns A 4-column tibble, with columns `activity_type`, `change_factor`, -#' `strategy` and `tpma_label` +#' @returns A 4-column tibble, with columns `strategy`, `activity_type`, +#' `change_factor` and `tpma_label` #' @export -get_tpma_label_lookup <- function(use_local = FALSE) { - read_cols <- "cccc----c" - use_local <- getOption("reskit.local.lookups") %||% use_local - csv_data <- system.file("mitigator-lookup.csv", package = "reskit") |> - readr::read_csv(col_types = read_cols) - csv_data_from_gh <- NULL - if (!use_local) { - csv_data_raw <- possibly_get_tpmas_gh_file("mitigator-lookup.csv") - if (!is.null(csv_data_raw)) { - csv_data_from_gh <- readr::read_csv(csv_data_raw, col_types = read_cols) - } - } - csv_data <- csv_data_from_gh %||% csv_data +get_tpma_label_lookup <- function() { + csv_data <- possibly_read_tpmas_lookup() + msg <- "Unable to read TPMA lookup table from GitHub" + azkit::check_that(csv_data, is_not_null, msg) csv_data |> dplyr::filter(dplyr::if_any("active_to", is.na)) |> dplyr::select(!"active_to") |> - dplyr::rename( - change_factor = "mitigator_type", - strategy = "mitigator_variable", - tpma_label = "mitigator_name" - ) + dplyr::mutate( + tpma_label = glue::glue("{tpma_name} ({tpma_subtype})"), + dplyr::across("tpma_type", \(x) tolower(sub(" ", "_", x))), + dplyr::across("activity_type", convert_activity_type), + .keep = "unused" + ) |> + dplyr::rename(change_factor = "tpma_type", strategy = "tpma_variable") +} + + +#' Converts "In|Outpatients", "A&E" strings to "ip", "op" and "aae" +#' @param x A character vector +#' @returns A character vector +#' @keywords internal +convert_activity_type <- function(x) { + dplyr::recode_values( + x, + "A&E" ~ "aae", + "Inpatients" ~ "ip", + "Outpatients" ~ "op" + ) } @@ -216,3 +218,5 @@ get_tpma_label_lookup <- function(use_local = FALSE) { #' @returns A character vector: all values of x that match the regex in rx #' @keywords internal gregv <- \(x, rx, g = parent.frame()) grepv(glue::glue_data(g, rx), x) + +is_not_null <- \(x) !is.null(x) diff --git a/R/tables.R b/R/tables.R index 823e0a9..88d30b9 100644 --- a/R/tables.R +++ b/R/tables.R @@ -28,7 +28,7 @@ make_principal_los_table <- function(principal_los_data) { } -#' Create a gt table with data from compile_detailed_activity_data() +#' Create a gt table with data from [compile_detailed_activity_data] #' #' @param detailed_activity_data A suitable tibble #' @param final_year string. The horizon year eg "2042/43" @@ -50,7 +50,7 @@ make_detailed_activity_table <- function(detailed_activity_data, final_year) { } -#' Create a gt table with data from compile_distribution_summary_data() +#' Create a gt table with data from [compile_distribution_summary_data] #' #' @param distr_summary_data A suitable tibble #' @returns A gt table diff --git a/inst/a_sort_of_quarto_test_document.qmd b/inst/a_sort_of_quarto_test_document.qmd index 4f843d6..2ca4b58 100644 --- a/inst/a_sort_of_quarto_test_document.qmd +++ b/inst/a_sort_of_quarto_test_document.qmd @@ -9,14 +9,12 @@ knitr: ### Load the package ```{r} - devtools::load_all(here::here()) - ``` ### Get some results data -```{r results path} +```{r results-path} #| eval: false res_con <- get_results_container() @@ -34,7 +32,6 @@ identical(res_path1, res_path2) results <- read_results_parquet_files(res_path1, container = res_con) readr::write_rds(results, here::here("test_results.rds")) - ``` Yay that worked. @@ -46,10 +43,9 @@ for `read_results_parquet_files()`). And let's have a peek at the `default` results table. -```{r results in} +```{r results-in} results <- readr::read_rds(here::here("test_results.rds")) tibble::glimpse(results[["default"]]) - ``` @@ -104,20 +100,17 @@ need for our reporting. This is `mod_principal_summary_data()` in nhp_outputs. -```{r main pod table process} +```{r main-pod-table-process} results |> purrr::pluck("default") |> compile_principal_pod_data() |> make_principal_pod_table() - ``` ```{r sites} - sites <- get_trust_sites(results[["default"]]) - ``` @@ -131,23 +124,21 @@ different inputs: `summary_los_data_beddays()` and -```{r make los summary table 1} +```{r make-los-summary-table-1} results |> purrr::pluck("tretspef+los_group") |> compile_principal_los_data(measure = "beddays") |> make_principal_los_table() - ``` ### Admissions summary by length of stay and point of delivery -```{r make los summary table 2} +```{r make-los-summary-table-2} results |> purrr::pluck("tretspef+los_group") |> compile_principal_los_data(measure = "admissions") |> make_principal_los_table() - ``` @@ -155,7 +146,7 @@ results |> #### Overall ("waterfall") 1 -```{r change factors plot 1} +```{r change-factors-plot-1} selected_pods <- c( "ip_elective_daycase", "ip_maternity_admission", @@ -175,7 +166,7 @@ results |> #### Overall 2 (no baseline) -```{r change factors plot 2} +```{r change-factors-plot-2} results |> purrr::pluck("step_counts") |> compile_change_factor_data( @@ -190,8 +181,7 @@ results |> #### Individual -```{r change factors plot 3} - +```{r change-factors-plot-3} measure <- "arrivals" results |> @@ -201,14 +191,12 @@ results |> activity_type = "aae" ) |> make_individual_cf_plot(x_axis_label = measure) - ``` ## Activity in detail table -```{r activity in detail table 1} - +```{r detailed-activity-table-1} aggregation <- "age_group" results |> @@ -218,11 +206,9 @@ results |> aggregation = aggregation ) |> make_detailed_activity_table("2041/42") - ``` -```{r activity in detail table 2} - +```{r detailed-activity-table-2} aggregation <- "tretspef" results |> @@ -232,12 +218,10 @@ results |> aggregation = aggregation ) |> make_detailed_activity_table("2041/42") - ``` -```{r activity in detail table 3} - +```{r detailed-activity-table-3} aggregation <- "tretspef" results |> @@ -247,12 +231,10 @@ results |> aggregation = aggregation ) |> make_detailed_activity_table("2041/42") - ``` -```{r activity in detail table 4} - +```{r detailed-activity-table-4} aggregation <- "tretspef" results |> @@ -262,7 +244,6 @@ results |> aggregation = aggregation ) |> make_detailed_activity_table("2041/42") - ``` @@ -270,30 +251,27 @@ results |> Median -```{r distrib_tbl median} +```{r distribution-table-by-median} results |> purrr::pluck("default") |> compile_distribution_summary_data() |> make_distribution_summary_table() - ``` Principal (aka mean) -```{r distrib_tbl principal} - +```{r distribution-table-by-principal} results |> purrr::pluck("default") |> compile_distribution_summary_data("principal") |> make_distribution_summary_table() - ``` ### Distribution plots: beeswarm -```{r beeswarm1} +```{r beeswarm-plot-1} results |> purrr::pluck("default") |> compile_distribution_plot_data(measure = "beddays", activity_type = "ip") |> @@ -302,7 +280,7 @@ results |> show zero -```{r beeswarm2} +```{r beeswarm-plot-2} results |> purrr::pluck("default") |> compile_distribution_plot_data(measure = "beddays", activity_type = "ip") |> @@ -312,7 +290,7 @@ results |> ### Distribution plots: cumulative -```{r ecdf1} +```{r ecdf-plot-1} results |> purrr::pluck("default") |> compile_distribution_plot_data(measure = "beddays", activity_type = "ip") |> @@ -321,7 +299,7 @@ results |> show zero -```{r ecdf2} +```{r ecdf-plot-2} results |> purrr::pluck("default") |> compile_distribution_plot_data(measure = "beddays", activity_type = "ip") |> diff --git a/inst/mitigator-lookup.csv b/inst/mitigator-lookup.csv deleted file mode 100644 index 22ae295..0000000 --- a/inst/mitigator-lookup.csv +++ /dev/null @@ -1,97 +0,0 @@ -activity_type,mitigator_type,mitigator_variable,mitigator_name,mitigator_code,mitigator_subset,mitigator_grouping,active_from,active_to -aae,activity_avoidance,discharged_no_treatment_adult_ambulance,"A&E Discharged No Investigation or Treatment (Adult, Ambulance Conveyed)",AE-AA-001,Discharged No Treatment,Emergency department and acute medicine activity,v0.6.3,NA -aae,activity_avoidance,discharged_no_treatment_adult_walk-in,"A&E Discharged No Investigation or Treatment (Adult, Walk-in)",AE-AA-002,Discharged No Treatment,Emergency department and acute medicine activity,v0.6.3,NA -aae,activity_avoidance,discharged_no_treatment_child_ambulance,"A&E Discharged No Investigation or Treatment (Children, Ambulance Conveyed)",AE-AA-003,Discharged No Treatment,Emergency department and acute medicine activity,v0.6.3,NA -aae,activity_avoidance,discharged_no_treatment_child_walk-in,"A&E Discharged No Investigation or Treatment (Children, Walk-in)",AE-AA-004,Discharged No Treatment,Emergency department and acute medicine activity,v0.6.3,NA -aae,activity_avoidance,frequent_attenders_adult_ambulance,"A&E Frequent Attenders (Adult, Ambulance Conveyed)",AE-AA-005,Frequent Attenders,Emergency department and acute medicine activity,v0.6.0,NA -aae,activity_avoidance,frequent_attenders_adult_walk-in,"A&E Frequent Attenders (Adult, Walk-in)",AE-AA-006,Frequent Attenders,Emergency department and acute medicine activity,v0.6.0,NA -aae,activity_avoidance,frequent_attenders_child_ambulance,"A&E Frequent Attenders (Children, Ambulance Conveyed)",AE-AA-007,Frequent Attenders,Emergency department and acute medicine activity,v0.6.0,NA -aae,activity_avoidance,frequent_attenders_child_walk-in,"A&E Frequent Attenders (Children, Walk-in)",AE-AA-008,Frequent Attenders,Emergency department and acute medicine activity,v0.6.0,NA -aae,activity_avoidance,left_before_seen_adult_ambulance,"A&E Patients Left Before Being Treated (Adult, Ambulance Conveyed)",AE-AA-009,Left Before Seen,Emergency department and acute medicine activity,v0.6.0,NA -aae,activity_avoidance,left_before_seen_adult_walk-in,"A&E Patients Left Before Being Treated (Adult, Walk-in)",AE-AA-010,Left Before Seen,Emergency department and acute medicine activity,v0.6.0,NA -aae,activity_avoidance,left_before_seen_child_ambulance,"A&E Patients Left Before Being Treated (Children, Ambulance Conveyed)",AE-AA-011,Left Before Seen,Emergency department and acute medicine activity,v0.6.0,NA -aae,activity_avoidance,left_before_seen_child_walk-in,"A&E Patients Left Before Being Treated (Children, Walk-in)",AE-AA-012,Left Before Seen,Emergency department and acute medicine activity,v0.6.0,NA -aae,activity_avoidance,low_cost_discharged_adult_ambulance,"A&E Low Cost Discharged Attendances (Adult, Ambulance Conveyed)",AE-AA-013,Low-cost Discharged,Emergency department and acute medicine activity,v0.6.0,NA -aae,activity_avoidance,low_cost_discharged_adult_walk-in,"A&E Low Cost Discharged Attendances (Adult, Walk-in)",AE-AA-014,Low-cost Discharged,Emergency department and acute medicine activity,v0.6.0,NA -aae,activity_avoidance,low_cost_discharged_child_ambulance,"A&E Low Cost Discharged Attendances (Children, Ambulance Conveyed)",AE-AA-015,Low-cost Discharged,Emergency department and acute medicine activity,v0.6.0,NA -aae,activity_avoidance,low_cost_discharged_child_walk-in,"A&E Low Cost Discharged Attendances (Children, Walk-in)",AE-AA-016,Low-cost Discharged,Emergency department and acute medicine activity,v0.6.0,NA -ip,activity_avoidance,alcohol_partially_attributable_acute,Alcohol Related Admissions (Acute Conditions - Partially Attributable),IP-AA-001,Admission Avoidance,Hospital activity amenable to public health interventions,v0.6.0,NA -ip,activity_avoidance,alcohol_partially_attributable_chronic,Alcohol Related Admissions (Chronic Conditions - Partially Attributable),IP-AA-002,Admission Avoidance,Hospital activity amenable to public health interventions,v0.6.0,NA -ip,activity_avoidance,alcohol_wholly_attributable,Alcohol Related Admissions (Wholly Attributable),IP-AA-003,Admission Avoidance,Hospital activity amenable to public health interventions,v0.6.0,NA -ip,activity_avoidance,ambulatory_care_conditions_acute,Ambulatory Care Sensitive Admissions (Acute Conditions),IP-AA-004,Admission Avoidance,Hospital activity amenable to primary care and community interventions,v0.6.0,NA -ip,activity_avoidance,ambulatory_care_conditions_chronic,Ambulatory Care Sensitive Admissions (Chronic Conditions),IP-AA-005,Admission Avoidance,Hospital activity amenable to primary care and community interventions,v0.6.0,NA -ip,activity_avoidance,ambulatory_care_conditions_vaccine_preventable,Ambulatory Care Sensitive Admissions (Vaccine Preventable),IP-AA-006,Admission Avoidance,Hospital activity amenable to primary care and community interventions,v0.6.0,NA -ip,activity_avoidance,cancelled_operations,Cancelled Operations,IP-AA-007,Admission Avoidance,Planned surgical activity (adult),v0.6.0,NA -ip,activity_avoidance,eol_care_2_days,End of Life Care Admissions (died within 2 days),IP-AA-008,Admission Avoidance,Hospital activity amenable to primary care and community interventions,v0.6.0,NA -ip,activity_avoidance,eol_care_3_to_14_days,End of Life Care Admissions (died within 3-14 days),IP-AA-009,Admission Avoidance,Hospital activity amenable to primary care and community interventions,v0.6.0,NA -ip,activity_avoidance,evidence_based_interventions_ent,Interventions with Limited Evidence (ENT),IP-AA-010,Admission Avoidance,Planned surgical activity (adult),v0.6.0,NA -ip,activity_avoidance,evidence_based_interventions_general_surgery,Interventions with Limited Evidence (General Surgery),IP-AA-011,Admission Avoidance,Planned surgical activity (adult),v0.6.0,NA -ip,activity_avoidance,evidence_based_interventions_gi_surgical,Interventions with Limited Evidence (GI Surgical),IP-AA-012,Admission Avoidance,Planned surgical activity (adult),v0.6.0,NA -ip,activity_avoidance,evidence_based_interventions_msk,Interventions with Limited Evidence (MSK),IP-AA-013,Admission Avoidance,Planned surgical activity (adult),v0.6.0,NA -ip,activity_avoidance,evidence_based_interventions_urology,Interventions with Limited Evidence (Urology),IP-AA-014,Admission Avoidance,Planned surgical activity (adult),v0.6.0,NA -ip,activity_avoidance,evidence_based_interventions_vascular_varicose_veins,Interventions with Limited Evidence (Vascular Varicose Veins),IP-AA-015,Admission Avoidance,Planned surgical activity (adult),v0.6.0,NA -ip,activity_avoidance,falls_related_admissions,Falls Related Admissions,IP-AA-016,Admission Avoidance,Hospital activity amenable to public health interventions,v0.6.0,NA -ip,activity_avoidance,frail_elderly_high,Older People with Frailty Admissions (High Frailty Risk),IP-AA-017,Admission Avoidance,Hospital activity amenable to primary care and community interventions,v0.6.0,NA -ip,activity_avoidance,frail_elderly_intermediate,Older People with Frailty Admissions (Intermediate Frailty Risk),IP-AA-018,Admission Avoidance,Hospital activity amenable to primary care and community interventions,v0.6.0,NA -ip,activity_avoidance,intentional_self_harm,Intentional Self Harm Admissions,IP-AA-019,Admission Avoidance,Hospital activity amenable to psychiatric liaison and community psychiatry,v0.6.0,NA -ip,activity_avoidance,medically_unexplained_related_admissions,Medically Unexplained Symptoms Admissions,IP-AA-020,Admission Avoidance,Hospital activity amenable to psychiatric liaison and community psychiatry,v0.6.0,NA -ip,activity_avoidance,medicines_related_admissions_explicit,Medicines Related Admissions (Explicit),IP-AA-021,Admission Avoidance,Hospital activity amenable to medicines management,v0.6.0,NA -ip,activity_avoidance,medicines_related_admissions_implicit_anti-diabetics,Medicines Related Admissions (Implicit - Anti-Diabetics),IP-AA-022,Admission Avoidance,Hospital activity amenable to medicines management,v0.6.0,NA -ip,activity_avoidance,medicines_related_admissions_implicit_benzodiasepines,Medicines Related Admissions (Implicit - Benzodiazepines),IP-AA-023,Admission Avoidance,Hospital activity amenable to medicines management,v0.6.0,NA -ip,activity_avoidance,medicines_related_admissions_implicit_diurectics,Medicines Related Admissions (Implicit - Diuretics),IP-AA-024,Admission Avoidance,Hospital activity amenable to medicines management,v0.6.0,NA -ip,activity_avoidance,medicines_related_admissions_implicit_nsaids,Medicines Related Admissions (Implicit - NSAIDs),IP-AA-025,Admission Avoidance,Hospital activity amenable to medicines management,v0.6.0,NA -ip,activity_avoidance,obesity_related_admissions,Obesity Related Admissions,IP-AA-026,Admission Avoidance,Hospital activity amenable to public health interventions,v0.6.0,NA -ip,activity_avoidance,raid_ae,Mental Health Admissions via Emergency Department,IP-AA-027,Admission Avoidance,Hospital activity amenable to psychiatric liaison and community psychiatry,v0.6.0,NA -ip,activity_avoidance,readmission_within_28_days,Emergency Readmissions Within 28 Days,IP-AA-028,Admission Avoidance,Hospital activity amenable to primary care and community interventions,v0.6.0,NA -ip,activity_avoidance,smoking,Smoking Related Admissions,IP-AA-029,Admission Avoidance,Hospital activity amenable to public health interventions,v0.6.0,NA -ip,activity_avoidance,virtual_wards_activity_avoidance_ari,Virtual Wards Admission Avoidance (Acute Respiratory Infection),IP-AA-030,Admission Avoidance,Hospital activity amenable to primary care and community interventions,v1.1.0,NA -ip,activity_avoidance,virtual_wards_activity_avoidance_heart_failure,Virtual Wards Admission Avoidance (Heart Failure),IP-AA-031,Admission Avoidance,Hospital activity amenable to primary care and community interventions,v1.1.0,NA -ip,activity_avoidance,zero_los_no_procedure_adult,Admission With No Overnight Stay and No Procedure (Adults),IP-AA-032,Admission Avoidance,Hospital activity amenable to primary care and community interventions,v0.6.0,NA -ip,activity_avoidance,zero_los_no_procedure_child,Admission With No Overnight Stay and No Procedure (Children),IP-AA-033,Admission Avoidance,Hospital activity amenable to primary care and community interventions,v0.6.0,NA -ip,efficiencies,ambulatory_emergency_care_high,Ambulatory Emergency Care (High Potential),IP-EF-001,Ambulatory Emergency Care Length of Stay Reduction,Emergency department and acute medicine activity,v0.6.0,v3.3.0 -ip,efficiencies,ambulatory_emergency_care_low,Ambulatory Emergency Care (Low Potential),IP-EF-002,Ambulatory Emergency Care Length of Stay Reduction,Emergency department and acute medicine activity,v0.6.0,v3.3.0 -ip,efficiencies,ambulatory_emergency_care_moderate,Ambulatory Emergency Care (Moderate Potential),IP-EF-003,Ambulatory Emergency Care Length of Stay Reduction,Emergency department and acute medicine activity,v0.6.0,v3.3.0 -ip,efficiencies,ambulatory_emergency_care_very_high,Ambulatory Emergency Care (Very High Potential),IP-EF-004,Ambulatory Emergency Care Length of Stay Reduction,Emergency department and acute medicine activity,v0.6.0,v3.3.0 -ip,efficiencies,day_procedures_occasionally_dc,Day Procedures: Occasionally performed as a Daycase,IP-EF-005,Day Procedures: Daycase,Planned surgical activity (adult),v1.1.0,NA -ip,efficiencies,day_procedures_occasionally_op,Day Procedures: Occasionally performed in Outpatients,IP-EF-006,Day Procedures: Outpatients,Planned surgical activity (adult),v1.1.0,NA -ip,efficiencies,day_procedures_usually_dc,Day Procedures: Usually performed as a Daycase,IP-EF-007,Day Procedures: Daycase,Planned surgical activity (adult),v1.1.0,NA -ip,efficiencies,day_procedures_usually_op,Day Procedures: Usually performed in Outpatients,IP-EF-008,Day Procedures: Outpatients,Planned surgical activity (adult),v1.1.0,NA -ip,efficiencies,emergency_elderly,Emergency Admission of Older People,IP-EF-009,Mean Length of Stay Reduction,Hospital activity amenable to primary care and community interventions,v0.6.0,NA -ip,efficiencies,enhanced_recovery_bladder,Enhanced Recovery (Bladder),IP-EF-010,Mean Length of Stay Reduction,Planned surgical activity (adult),v0.6.0,NA -ip,efficiencies,enhanced_recovery_breast,Enhanced Recovery (Breast),IP-EF-011,Mean Length of Stay Reduction,Planned surgical activity (adult),v0.6.0,NA -ip,efficiencies,enhanced_recovery_colectomy,Enhanced Recovery (Colectomy),IP-EF-012,Mean Length of Stay Reduction,Planned surgical activity (adult),v0.6.0,NA -ip,efficiencies,enhanced_recovery_hip,Enhanced Recovery (Hip),IP-EF-013,Mean Length of Stay Reduction,Planned surgical activity (adult),v0.6.0,NA -ip,efficiencies,enhanced_recovery_hysterectomy,Enhanced Recovery (Hysterectomy),IP-EF-014,Mean Length of Stay Reduction,Planned surgical activity (adult),v0.6.0,NA -ip,efficiencies,enhanced_recovery_knee,Enhanced Recovery (Knee),IP-EF-015,Mean Length of Stay Reduction,Planned surgical activity (adult),v0.6.0,NA -ip,efficiencies,enhanced_recovery_prostate,Enhanced Recovery (Prostate),IP-EF-016,Mean Length of Stay Reduction,Planned surgical activity (adult),v0.6.0,NA -ip,efficiencies,enhanced_recovery_rectum,Enhanced Recovery (Rectum),IP-EF-017,Mean Length of Stay Reduction,Planned surgical activity (adult),v0.6.0,NA -ip,efficiencies,excess_beddays_elective,Excess Beddays (Elective Admissions),IP-EF-018,Mean Length of Stay Reduction,Hospital activity amenable to primary care and community interventions,v0.6.0,NA -ip,efficiencies,excess_beddays_emergency,Excess Beddays (Emergency Admissions),IP-EF-019,Mean Length of Stay Reduction,Hospital activity amenable to primary care and community interventions,v0.6.0,NA -ip,efficiencies,general_los_reduction_elective,General LoS Reduction: Elective Admissions,IP-EF-020,Mean Length of Stay Reduction,Hospital activity amenable to primary care and community interventions,v0.6.0,NA -ip,efficiencies,general_los_reduction_emergency,General LoS Reduction: Emergency Admissions,IP-EF-021,Mean Length of Stay Reduction,Hospital activity amenable to primary care and community interventions,v0.6.0,NA -ip,efficiencies,pre-op_los_1-day,Pre-op Length of Stay of 1 day,IP-EF-022,Pre-op Length of Stay Reduction,Planned surgical activity (adult),v0.6.0,NA -ip,efficiencies,pre-op_los_2-day,Pre-op Length of Stay of 2 days,IP-EF-023,Pre-op Length of Stay Reduction,Planned surgical activity (adult),v0.6.0,NA -ip,efficiencies,raid_ip,Admissions with Mental Health Comorbidities,IP-EF-024,Mean Length of Stay Reduction,Hospital activity amenable to psychiatric liaison and community psychiatry,v0.6.0,NA -ip,efficiencies,stroke_early_supported_discharge,Stroke Early Supported Discharge,IP-EF-025,Mean Length of Stay Reduction,Hospital activity amenable to primary care and community interventions,v0.6.0,NA -ip,efficiencies,virtual_wards_efficiencies_ari,Virtual Wards LoS Reduction (Acute Respiratory Infection),IP-EF-026,Mean Length of Stay Reduction,Hospital activity amenable to primary care and community interventions,v1.1.0,NA -ip,efficiencies,virtual_wards_efficiencies_heart_failure,Virtual Wards LoS Reduction (Heart Failure),IP-EF-027,Mean Length of Stay Reduction,Hospital activity amenable to primary care and community interventions,v1.1.0,NA -ip,efficiencies,same_day_emergency_care_low,Same Day Emergency Care (Low Potential),IP-EF-028,Same Day Emergency Care Conversion,Emergency department and acute medicine activity,v3.4.0,NA -ip,efficiencies,same_day_emergency_care_moderate,Same Day Emergency Care (Moderate Potential),IP-EF-029,Same Day Emergency Care Conversion,Emergency department and acute medicine activity,v3.4.0,NA -ip,efficiencies,same_day_emergency_care_high,Same Day Emergency Care (High Potential),IP-EF-030,Same Day Emergency Care Conversion,Emergency department and acute medicine activity,v3.4.0,NA -ip,efficiencies,same_day_emergency_care_very_high,Same Day Emergency Care (Very High Potential),IP-EF-031,Same Day Emergency Care Conversion,Emergency department and acute medicine activity,v3.4.0,NA -op,activity_avoidance,consultant_to_consultant_reduction_adult_non-surgical,"Outpatient Consultant to Consultant Referrals (Adult, Non-Surgical)",OP-AA-001,Consultant Referrals,Planned medical activity (adult),v0.6.0,NA -op,activity_avoidance,consultant_to_consultant_reduction_adult_surgical,"Outpatient Consultant to Consultant Referrals (Adult, Surgical)",OP-AA-002,Consultant Referrals,Planned surgical activity (adult),v0.6.0,NA -op,activity_avoidance,consultant_to_consultant_reduction_child_non-surgical,"Outpatient Consultant to Consultant Referrals (Children, Non-Surgical)",OP-AA-003,Consultant Referrals,Planned medical activity (paediatric),v0.6.0,NA -op,activity_avoidance,consultant_to_consultant_reduction_child_surgical,"Outpatient Consultant to Consultant Referrals (Children, Surgical)",OP-AA-004,Consultant Referrals,Planned surgical activity (paediatric),v0.6.0,NA -op,activity_avoidance,followup_reduction_adult_non-surgical,"Outpatient Followup Appointment Reduction (Adult, Non-Surgical)",OP-AA-005,Follow-up Reduction,Planned medical activity (adult),v0.6.0,NA -op,activity_avoidance,followup_reduction_adult_surgical,"Outpatient Followup Appointment Reduction (Adult, Surgical)",OP-AA-006,Follow-up Reduction,Planned surgical activity (adult),v0.6.0,NA -op,activity_avoidance,followup_reduction_child_non-surgical,"Outpatient Followup Appointment Reduction (Children, Non-Surgical)",OP-AA-007,Follow-up Reduction,Planned medical activity (paediatric),v0.6.0,NA -op,activity_avoidance,followup_reduction_child_surgical,"Outpatient Followup Appointment Reduction (Children, Surgical)",OP-AA-008,Follow-up Reduction,Planned surgical activity (paediatric),v0.6.0,NA -op,activity_avoidance,gp_referred_first_attendance_reduction_adult_non-surgical,"Outpatient GP Referred First Attendance Reduction (Adult, Non-Surgical)",OP-AA-009,GP-referred First Attendance Reduction,Planned medical activity (adult),v0.6.3,NA -op,activity_avoidance,gp_referred_first_attendance_reduction_adult_surgical,"Outpatient GP Referred First Attendance Reduction (Adult, Surgical)",OP-AA-010,GP-referred First Attendance Reduction,Planned surgical activity (adult),v0.6.3,NA -op,activity_avoidance,gp_referred_first_attendance_reduction_child_non-surgical,"Outpatient GP Referred First Attendance Reduction (Children, Non-Surgical)",OP-AA-011,GP-referred First Attendance Reduction,Planned medical activity (paediatric),v0.6.3,NA -op,activity_avoidance,gp_referred_first_attendance_reduction_child_surgical,"Outpatient GP Referred First Attendance Reduction (Children, Surgical)",OP-AA-012,GP-referred First Attendance Reduction,Planned surgical activity (paediatric),v0.6.3,NA -op,efficiencies,convert_to_tele_adult_non-surgical,"Outpatient Convert to Tele-Attendance (Adult, Non-Surgical)",OP-EF-001,Convert to Tele,Planned medical activity (adult),v0.6.0,NA -op,efficiencies,convert_to_tele_adult_surgical,"Outpatient Convert to Tele-Attendance (Adult, Surgical)",OP-EF-002,Convert to Tele,Planned surgical activity (adult),v0.6.0,NA -op,efficiencies,convert_to_tele_child_non-surgical,"Outpatient Convert to Tele-Attendance (Children, Non-Surgical)",OP-EF-003,Convert to Tele,Planned medical activity (paediatric),v0.6.0,NA -op,efficiencies,convert_to_tele_child_surgical,"Outpatient Convert to Tele-Attendance (Children, Surgical)",OP-EF-004,Convert to Tele,Planned surgical activity (paediatric),v0.6.0,NA diff --git a/inst/mitigators.json b/inst/mitigators.json deleted file mode 100644 index 40d456f..0000000 --- a/inst/mitigators.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "alcohol_partially_attributable_acute": "Alcohol Related Admissions (Acute Conditions - Partially Attributable) (IP-AA-001)", - "alcohol_partially_attributable_chronic": "Alcohol Related Admissions (Chronic Conditions - Partially Attributable) (IP-AA-002)", - "alcohol_wholly_attributable": "Alcohol Related Admissions (Wholly Attributable) (IP-AA-003)", - "ambulatory_care_conditions_acute": "Ambulatory Care Sensitive Admissions (Acute Conditions) (IP-AA-004)", - "ambulatory_care_conditions_chronic": "Ambulatory Care Sensitive Admissions (Chronic Conditions) (IP-AA-005)", - "ambulatory_care_conditions_vaccine_preventable": "Ambulatory Care Sensitive Admissions (Vaccine Preventable) (IP-AA-006)", - "ambulatory_emergency_care_high": "Ambulatory Emergency Care (High Potential) (IP-EF-001)", - "ambulatory_emergency_care_low": "Ambulatory Emergency Care (Low Potential) (IP-EF-002)", - "ambulatory_emergency_care_moderate": "Ambulatory Emergency Care (Moderate Potential) (IP-EF-003)", - "ambulatory_emergency_care_very_high": "Ambulatory Emergency Care (Very High Potential) (IP-EF-004)", - "cancelled_operations": "Cancelled Operations (IP-AA-007)", - "consultant_to_consultant_reduction_adult_non-surgical": "Outpatient Consultant to Consultant Referrals (Adult, Non-Surgical) (OP-AA-001)", - "consultant_to_consultant_reduction_adult_surgical": "Outpatient Consultant to Consultant Referrals (Adult, Surgical) (OP-AA-002)", - "consultant_to_consultant_reduction_child_non-surgical": "Outpatient Consultant to Consultant Referrals (Children, Non-Surgical) (OP-AA-003)", - "consultant_to_consultant_reduction_child_surgical": "Outpatient Consultant to Consultant Referrals (Children, Surgical) (OP-AA-004)", - "convert_to_tele_adult_non-surgical": "Outpatient Convert to Tele-Attendance (Adult, Non-Surgical) (OP-EF-001)", - "convert_to_tele_adult_surgical": "Outpatient Convert to Tele-Attendance (Adult, Surgical) (OP-EF-002)", - "convert_to_tele_child_non-surgical": "Outpatient Convert to Tele-Attendance (Children, Non-Surgical) (OP-EF-003)", - "convert_to_tele_child_surgical": "Outpatient Convert to Tele-Attendance (Children, Surgical) (OP-EF-004)", - "day_procedures_occasionally_dc": "Day Procedures: Occasionally performed as a Daycase (IP-EF-005)", - "day_procedures_occasionally_op": "Day Procedures: Occasionally performed in Outpatients (IP-EF-006)", - "day_procedures_usually_dc": "Day Procedures: Usually performed as a Daycase (IP-EF-007)", - "day_procedures_usually_op": "Day Procedures: Usually performed in Outpatients (IP-EF-008)", - "discharged_no_treatment_adult_ambulance": "A&E Discharged No Investigation or Treatment (Adult, Ambulance Conveyed) (AE-AA-001)", - "discharged_no_treatment_adult_walk-in": "A&E Discharged No Investigation or Treatment (Adult, Walk-in) (AE-AA-002)", - "discharged_no_treatment_child_ambulance": "A&E Discharged No Investigation or Treatment (Children, Ambulance Conveyed) (AE-AA-003)", - "discharged_no_treatment_child_walk-in": "A&E Discharged No Investigation or Treatment (Children, Walk-in) (AE-AA-004)", - "emergency_elderly": "Emergency Admission of Older People (IP-EF-009)", - "enhanced_recovery_bladder": "Enhanced Recovery (Bladder) (IP-EF-010)", - "enhanced_recovery_breast": "Enhanced Recovery (Breast) (IP-EF-011)", - "enhanced_recovery_colectomy": "Enhanced Recovery (Colectomy) (IP-EF-012)", - "enhanced_recovery_hip": "Enhanced Recovery (Hip) (IP-EF-013)", - "enhanced_recovery_hysterectomy": "Enhanced Recovery (Hysterectomy) (IP-EF-014)", - "enhanced_recovery_knee": "Enhanced Recovery (Knee) (IP-EF-015)", - "enhanced_recovery_prostate": "Enhanced Recovery (Prostate) (IP-EF-016)", - "enhanced_recovery_rectum": "Enhanced Recovery (Rectum) (IP-EF-017)", - "eol_care_2_days": "End of Life Care Admissions (died within 2 days) (IP-AA-008)", - "eol_care_3_to_14_days": "End of Life Care Admissions (died within 3-14 days) (IP-AA-009)", - "evidence_based_interventions_ent": "Interventions with Limited Evidence (ENT) (IP-AA-010)", - "evidence_based_interventions_general_surgery": "Interventions with Limited Evidence (General Surgery) (IP-AA-011)", - "evidence_based_interventions_gi_surgical": "Interventions with Limited Evidence (GI Surgical) (IP-AA-012)", - "evidence_based_interventions_msk": "Interventions with Limited Evidence (MSK) (IP-AA-013)", - "evidence_based_interventions_urology": "Interventions with Limited Evidence (Urology) (IP-AA-014)", - "evidence_based_interventions_vascular_varicose_veins": "Interventions with Limited Evidence (Vascular Varicose Veins) (IP-AA-015)", - "excess_beddays_elective": "Excess Beddays (Elective Admissions) (IP-EF-018)", - "excess_beddays_emergency": "Excess Beddays (Emergency Admissions) (IP-EF-019)", - "falls_related_admissions": "Falls Related Admissions (IP-AA-016)", - "followup_reduction_adult_non-surgical": "Outpatient Followup Appointment Reduction (Adult, Non-Surgical) (OP-AA-005)", - "followup_reduction_adult_surgical": "Outpatient Followup Appointment Reduction (Adult, Surgical) (OP-AA-006)", - "followup_reduction_child_non-surgical": "Outpatient Followup Appointment Reduction (Children, Non-Surgical) (OP-AA-007)", - "followup_reduction_child_surgical": "Outpatient Followup Appointment Reduction (Children, Surgical) (OP-AA-008)", - "frail_elderly_high": "Older People with Frailty Admissions (High Frailty Risk) (IP-AA-017)", - "frail_elderly_intermediate": "Older People with Frailty Admissions (Intermediate Frailty Risk) (IP-AA-018)", - "frequent_attenders_adult_ambulance": "A&E Frequent Attenders (Adult, Ambulance Conveyed) (AE-AA-005)", - "frequent_attenders_adult_walk-in": "A&E Frequent Attenders (Adult, Walk-in) (AE-AA-006)", - "frequent_attenders_child_ambulance": "A&E Frequent Attenders (Children, Ambulance Conveyed) (AE-AA-007)", - "frequent_attenders_child_walk-in": "A&E Frequent Attenders (Children, Walk-in) (AE-AA-008)", - "general_los_reduction_elective": "General LoS Reduction: Elective Admissions (IP-EF-020)", - "general_los_reduction_emergency": "General LoS Reduction: Emergency Admissions (IP-EF-021)", - "gp_referred_first_attendance_reduction_adult_non-surgical": "Outpatient GP Referred First Attendance Reduction (Adult, Non-Surgical) (OP-AA-009)", - "gp_referred_first_attendance_reduction_adult_surgical": "Outpatient GP Referred First Attendance Reduction (Adult, Surgical) (OP-AA-010)", - "gp_referred_first_attendance_reduction_child_non-surgical": "Outpatient GP Referred First Attendance Reduction (Children, Non-Surgical) (OP-AA-011)", - "gp_referred_first_attendance_reduction_child_surgical": "Outpatient GP Referred First Attendance Reduction (Children, Surgical) (OP-AA-012)", - "intentional_self_harm": "Intentional Self Harm Admissions (IP-AA-019)", - "left_before_seen_adult_ambulance": "A&E Patients Left Before Being Treated (Adult, Ambulance Conveyed) (AE-AA-009)", - "left_before_seen_adult_walk-in": "A&E Patients Left Before Being Treated (Adult, Walk-in) (AE-AA-010)", - "left_before_seen_child_ambulance": "A&E Patients Left Before Being Treated (Children, Ambulance Conveyed) (AE-AA-011)", - "left_before_seen_child_walk-in": "A&E Patients Left Before Being Treated (Children, Walk-in) (AE-AA-012)", - "low_cost_discharged_adult_ambulance": "A&E Low Cost Discharged Attendances (Adult, Ambulance Conveyed) (AE-AA-013)", - "low_cost_discharged_adult_walk-in": "A&E Low Cost Discharged Attendances (Adult, Walk-in) (AE-AA-014)", - "low_cost_discharged_child_ambulance": "A&E Low Cost Discharged Attendances (Children, Ambulance Conveyed) (AE-AA-015)", - "low_cost_discharged_child_walk-in": "A&E Low Cost Discharged Attendances (Children, Walk-in) (AE-AA-016)", - "medically_unexplained_related_admissions": "Medically Unexplained Symptoms Admissions (IP-AA-020)", - "medicines_related_admissions_explicit": "Medicines Related Admissions (Explicit) (IP-AA-021)", - "medicines_related_admissions_implicit_anti-diabetics": "Medicines Related Admissions (Implicit - Anti-Diabetics) (IP-AA-022)", - "medicines_related_admissions_implicit_benzodiasepines": "Medicines Related Admissions (Implicit - Benzodiazepines) (IP-AA-023)", - "medicines_related_admissions_implicit_diurectics": "Medicines Related Admissions (Implicit - Diuretics) (IP-AA-024)", - "medicines_related_admissions_implicit_nsaids": "Medicines Related Admissions (Implicit - NSAIDs) (IP-AA-025)", - "obesity_related_admissions": "Obesity Related Admissions (IP-AA-026)", - "pre-op_los_1-day": "Pre-op Length of Stay of 1 day (IP-EF-022)", - "pre-op_los_2-day": "Pre-op Length of Stay of 2 days (IP-EF-023)", - "raid_ae": "Mental Health Admissions via Emergency Department (IP-AA-027)", - "raid_ip": "Admissions with Mental Health Comorbidities (IP-EF-024)", - "readmission_within_28_days": "Emergency Readmissions Within 28 Days (IP-AA-028)", - "same_day_emergency_care_low": "Same Day Emergency Care (Low Potential) (IP-EF-028)", - "same_day_emergency_care_moderate": "Same Day Emergency Care (Moderate Potential) (IP-EF-029)", - "same_day_emergency_care_high": "Same Day Emergency Care (High Potential) (IP-EF-030)", - "same_day_emergency_care_very_high": "Same Day Emergency Care (Very High Potential) (IP-EF-031)", - "smoking": "Smoking Related Admissions (IP-AA-029)", - "stroke_early_supported_discharge": "Stroke Early Supported Discharge (IP-EF-025)", - "virtual_wards_activity_avoidance_ari": "Virtual Wards Admission Avoidance (Acute Respiratory Infection) (IP-AA-030)", - "virtual_wards_activity_avoidance_heart_failure": "Virtual Wards Admission Avoidance (Heart Failure) (IP-AA-031)", - "virtual_wards_efficiencies_ari": "Virtual Wards LoS Reduction (Acute Respiratory Infection) (IP-EF-026)", - "virtual_wards_efficiencies_heart_failure": "Virtual Wards LoS Reduction (Heart Failure) (IP-EF-027)", - "zero_los_no_procedure_adult": "Admission With No Overnight Stay and No Procedure (Adults) (IP-AA-032)", - "zero_los_no_procedure_child": "Admission With No Overnight Stay and No Procedure (Children) (IP-AA-033)" -} diff --git a/inst/pod_measures.yml b/inst/pod_measures.yml deleted file mode 100644 index d2dc005..0000000 --- a/inst/pod_measures.yml +++ /dev/null @@ -1,79 +0,0 @@ -pod_measures: - ip: - name: "Inpatient" - pods: - ip_non-elective_admission: - name: "Non-Elective Admission" - measures: - - admissions - - beddays - ip_elective_admission: - name: "Elective Admission" - measures: - - admissions - - beddays - ip_elective_daycase: - name: "Daycase Admission" - measures: - - admissions - - beddays - ip_maternity_admission: - name: "Maternity Admission" - measures: - - admissions - - beddays - ip_regular_day_attender: - name: "Regular Day Attender Admission" - measures: - - admissions - - beddays - ip_regular_night_attender: - name: "Regular Night Attender Admission" - measures: - - admissions - - beddays - op: - name: "Outpatient" - pods: - op_first: - name: "First Outpatient Attendance" - measures: - - attendances - - tele_attendances - op_follow-up: - name: "Follow-up Outpatient Attendance" - measures: - - attendances - - tele_attendances - op_procedure: - name: "Outpatient Procedure" - measures: - - attendances - aae: - name: "A&E" - pods: - aae_type-01: - name: "Type 1 Department" - measures: - - walk-in - - ambulance - aae_type-02: - name: "Type 2 Department" - measures: - - walk-in - - ambulance - aae_type-03: - name: "Type 3 Department" - measures: - - walk-in - - ambulance - aae_type-04: - name: "Type 4 Department" - measures: - - walk-in - - ambulance - aae_type-05: - name: "Type 5 Department (SDEC)" - measures: - - walk-in - - ambulance diff --git a/man/add_baseline_values.Rd b/man/add_baseline_values.Rd new file mode 100644 index 0000000..0a8a404 --- /dev/null +++ b/man/add_baseline_values.Rd @@ -0,0 +1,12 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/demo_results_tables.R +\name{add_baseline_values} +\alias{add_baseline_values} +\title{Helper function} +\usage{ +add_baseline_values(base_tbl, baseline_range, step = 100L, seed) +} +\description{ +Helper function +} +\keyword{internal} diff --git a/man/add_horizon_values.Rd b/man/add_horizon_values.Rd new file mode 100644 index 0000000..ef8b4e9 --- /dev/null +++ b/man/add_horizon_values.Rd @@ -0,0 +1,12 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/demo_results_tables.R +\name{add_horizon_values} +\alias{add_horizon_values} +\title{Helper function} +\usage{ +add_horizon_values(tbl_with_baseline, initial_means, seed) +} +\description{ +Helper function +} +\keyword{internal} diff --git a/man/convert_activity_type.Rd b/man/convert_activity_type.Rd new file mode 100644 index 0000000..8da2073 --- /dev/null +++ b/man/convert_activity_type.Rd @@ -0,0 +1,18 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/helpers.R +\name{convert_activity_type} +\alias{convert_activity_type} +\title{Converts "In|Outpatients", "A&E" strings to "ip", "op" and "aae"} +\usage{ +convert_activity_type(x) +} +\arguments{ +\item{x}{A character vector} +} +\value{ +A character vector +} +\description{ +Converts "In|Outpatients", "A&E" strings to "ip", "op" and "aae" +} +\keyword{internal} diff --git a/man/create_ae_base_tbl.Rd b/man/create_ae_base_tbl.Rd new file mode 100644 index 0000000..718f41f --- /dev/null +++ b/man/create_ae_base_tbl.Rd @@ -0,0 +1,12 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/demo_results_tables.R +\name{create_ae_base_tbl} +\alias{create_ae_base_tbl} +\title{Helper function} +\usage{ +create_ae_base_tbl() +} +\description{ +Helper function +} +\keyword{internal} diff --git a/man/create_base_tbl_with_sitetret.Rd b/man/create_base_tbl_with_sitetret.Rd new file mode 100644 index 0000000..b310303 --- /dev/null +++ b/man/create_base_tbl_with_sitetret.Rd @@ -0,0 +1,15 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/demo_results_tables.R +\name{create_base_tbl_with_sitetret} +\alias{create_base_tbl_with_sitetret} +\title{Helper function} +\usage{ +create_base_tbl_with_sitetret(site) +} +\arguments{ +\item{site}{A string giving the name/code of an imaginary site} +} +\description{ +Helper function +} +\keyword{internal} diff --git a/man/create_demo_default_tbl.Rd b/man/create_demo_default_tbl.Rd new file mode 100644 index 0000000..b0d0533 --- /dev/null +++ b/man/create_demo_default_tbl.Rd @@ -0,0 +1,16 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/demo_results_tables.R +\name{create_demo_default_tbl} +\alias{create_demo_default_tbl} +\title{Function to create a "default" table with synthetic values} +\usage{ +create_demo_default_tbl(seed) +} +\arguments{ +\item{seed}{integer, for reproducibility of outputs, a seed value to be used} +} +\description{ +The table contains synthetic (randomly created) values for a selection of +PODs and measures, across 2 "sites", as if created by 64 model runs +} +\keyword{internal} diff --git a/man/create_demo_sex_agegroup_tbl.Rd b/man/create_demo_sex_agegroup_tbl.Rd new file mode 100644 index 0000000..37c4afd --- /dev/null +++ b/man/create_demo_sex_agegroup_tbl.Rd @@ -0,0 +1,21 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/demo_results_tables.R +\name{create_demo_sex_agegroup_tbl} +\alias{create_demo_sex_agegroup_tbl} +\title{Function to create a "tretspef + age group" table with synthetic values +The table contains synthetic (randomly created) values for a selection of +PODs, tretspefs, age groups and measures, across 2 "sites", as if created +by 64 model runs} +\usage{ +create_demo_sex_agegroup_tbl(seed) +} +\arguments{ +\item{seed}{integer, for reproducibility of outputs, a seed value to be used} +} +\description{ +Function to create a "tretspef + age group" table with synthetic values +The table contains synthetic (randomly created) values for a selection of +PODs, tretspefs, age groups and measures, across 2 "sites", as if created +by 64 model runs +} +\keyword{internal} diff --git a/man/create_demo_sex_tretspef_tbl.Rd b/man/create_demo_sex_tretspef_tbl.Rd new file mode 100644 index 0000000..6128283 --- /dev/null +++ b/man/create_demo_sex_tretspef_tbl.Rd @@ -0,0 +1,21 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/demo_results_tables.R +\name{create_demo_sex_tretspef_tbl} +\alias{create_demo_sex_tretspef_tbl} +\title{Function to create a "sex + tretspef_grouped" table with synthetic values +The table contains synthetic (randomly created) values for 2 sexes, a +selection of tretspef group codes, and measures, across 2 "sites", as if +created by 64 model runs} +\usage{ +create_demo_sex_tretspef_tbl(seed) +} +\arguments{ +\item{seed}{integer, for reproducibility of outputs, a seed value to be used} +} +\description{ +Function to create a "sex + tretspef_grouped" table with synthetic values +The table contains synthetic (randomly created) values for 2 sexes, a +selection of tretspef group codes, and measures, across 2 "sites", as if +created by 64 model runs +} +\keyword{internal} diff --git a/man/create_demo_stepcounts_tbl.Rd b/man/create_demo_stepcounts_tbl.Rd new file mode 100644 index 0000000..2ac9fea --- /dev/null +++ b/man/create_demo_stepcounts_tbl.Rd @@ -0,0 +1,21 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/demo_results_tables.R +\name{create_demo_stepcounts_tbl} +\alias{create_demo_stepcounts_tbl} +\title{Function to create a "step_counts" table with synthetic values +The table contains synthetic (randomly created) values for a selection of +64 model runs, providing random baselines, random sizes of mitigated +activity across a subset of TPMAs, and random values for demographic growth} +\usage{ +create_demo_stepcounts_tbl(seed) +} +\arguments{ +\item{seed}{integer, for reproducibility of outputs, a seed value to be used} +} +\description{ +Function to create a "step_counts" table with synthetic values +The table contains synthetic (randomly created) values for a selection of +64 model runs, providing random baselines, random sizes of mitigated +activity across a subset of TPMAs, and random values for demographic growth +} +\keyword{internal} diff --git a/man/create_demo_tretspef_losgroup_tbl.Rd b/man/create_demo_tretspef_losgroup_tbl.Rd new file mode 100644 index 0000000..6b16622 --- /dev/null +++ b/man/create_demo_tretspef_losgroup_tbl.Rd @@ -0,0 +1,21 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/demo_results_tables.R +\name{create_demo_tretspef_losgroup_tbl} +\alias{create_demo_tretspef_losgroup_tbl} +\title{Function to create a "tretspef + LoS group" table with synthetic values +The table contains synthetic (randomly created) values for a selection of +PODs, tretspefs, LoS groups and measures, across 2 "sites", as if created +by 64 model runs} +\usage{ +create_demo_tretspef_losgroup_tbl(seed) +} +\arguments{ +\item{seed}{integer, for reproducibility of outputs, a seed value to be used} +} +\description{ +Function to create a "tretspef + LoS group" table with synthetic values +The table contains synthetic (randomly created) values for a selection of +PODs, tretspefs, LoS groups and measures, across 2 "sites", as if created +by 64 model runs +} +\keyword{internal} diff --git a/man/create_dummy_stepcounts_tbl.Rd b/man/create_dummy_stepcounts_tbl.Rd new file mode 100644 index 0000000..a497dc4 --- /dev/null +++ b/man/create_dummy_stepcounts_tbl.Rd @@ -0,0 +1,21 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/demo_results_tables.R +\name{create_dummy_stepcounts_tbl} +\alias{create_dummy_stepcounts_tbl} +\title{Function to create a "step_counts" table with synthetic values +The table contains synthetic (randomly created) values for a selection of +64 model runs, providing random baselines, random sizes of mitigated +activity across a subset of TPMAs, and random values for demographic growth} +\usage{ +create_dummy_stepcounts_tbl(seed) +} +\arguments{ +\item{seed}{integer, for reproducibility of outputs, a seed value to be used} +} +\description{ +Function to create a "step_counts" table with synthetic values +The table contains synthetic (randomly created) values for a selection of +64 model runs, providing random baselines, random sizes of mitigated +activity across a subset of TPMAs, and random values for demographic growth +} +\keyword{internal} diff --git a/man/create_ip_base_tbl.Rd b/man/create_ip_base_tbl.Rd new file mode 100644 index 0000000..f7d4916 --- /dev/null +++ b/man/create_ip_base_tbl.Rd @@ -0,0 +1,12 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/demo_results_tables.R +\name{create_ip_base_tbl} +\alias{create_ip_base_tbl} +\title{Helper function} +\usage{ +create_ip_base_tbl() +} +\description{ +Helper function +} +\keyword{internal} diff --git a/man/create_op_base_tbl.Rd b/man/create_op_base_tbl.Rd new file mode 100644 index 0000000..5281bc7 --- /dev/null +++ b/man/create_op_base_tbl.Rd @@ -0,0 +1,12 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/demo_results_tables.R +\name{create_op_base_tbl} +\alias{create_op_base_tbl} +\title{Helper function} +\usage{ +create_op_base_tbl() +} +\description{ +Helper function +} +\keyword{internal} diff --git a/man/create_sample_impacts.Rd b/man/create_sample_impacts.Rd new file mode 100644 index 0000000..5d0ab6a --- /dev/null +++ b/man/create_sample_impacts.Rd @@ -0,0 +1,12 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/demo_results_tables.R +\name{create_sample_impacts} +\alias{create_sample_impacts} +\title{Helper function} +\usage{ +create_sample_impacts(dat, mitigation, seed, picks = 64) +} +\description{ +Helper function +} +\keyword{internal} diff --git a/man/generate_horizon_values.Rd b/man/generate_horizon_values.Rd new file mode 100644 index 0000000..58ed41c --- /dev/null +++ b/man/generate_horizon_values.Rd @@ -0,0 +1,12 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/demo_results_tables.R +\name{generate_horizon_values} +\alias{generate_horizon_values} +\title{Helper function} +\usage{ +generate_horizon_values(baseline, mitigation, seed, picks = 64) +} +\description{ +Helper function +} +\keyword{internal} diff --git a/man/get_detailed_pods.Rd b/man/get_detailed_pods.Rd index a28d98a..0d029da 100644 --- a/man/get_detailed_pods.Rd +++ b/man/get_detailed_pods.Rd @@ -5,17 +5,9 @@ \alias{get_principal_pods} \title{Prepare a lookup table with activity type labels and PoD labels for each PoD} \usage{ -get_detailed_pods(use_local = FALSE) +get_detailed_pods() -get_principal_pods(use_local = FALSE) -} -\arguments{ -\item{use_local}{logical. Whether to use a local file (internal to the -reskit package) or attempt to pull the lookup file from GitHub. Default is -\code{FALSE}, meaning it will use the GitHub route. If you want to always use a -local file (for example, for fully offline working), you can set the -\code{reskit.local.lookups} option to \code{TRUE} using -\code{options(reskit.local.lookups = TRUE)} or \code{withr::with_options()}} +get_principal_pods() } \value{ A tibble @@ -24,5 +16,5 @@ A tibble } \description{ This function condenses all A&E activity to a single category - compare -\code{get_detailed_pods()} which \emph{keeps} all A&E categories +\link{get_detailed_pods} which \emph{keeps} all A&E categories } diff --git a/man/get_full_initial_means.Rd b/man/get_full_initial_means.Rd new file mode 100644 index 0000000..dcbf305 --- /dev/null +++ b/man/get_full_initial_means.Rd @@ -0,0 +1,12 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/demo_results_tables.R +\name{get_full_initial_means} +\alias{get_full_initial_means} +\title{Helper function} +\usage{ +get_full_initial_means(ae_mean, ip_mean, op_mean) +} +\description{ +Helper function +} +\keyword{internal} diff --git a/man/get_github_app_installation_id.Rd b/man/get_github_app_installation_id.Rd new file mode 100644 index 0000000..8300b87 --- /dev/null +++ b/man/get_github_app_installation_id.Rd @@ -0,0 +1,19 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/get_github_file.R +\name{get_github_app_installation_id} +\alias{get_github_app_installation_id} +\title{Returns the installation ID for the reskit GitHub app} +\usage{ +get_github_app_installation_id(jwt = get_github_jwt()) +} +\arguments{ +\item{jwt}{JWT for the app. Defaults to the output of \code{get_github_jwt()}.} +} +\value{ +An installation ID as an integer +} +\description{ +The envvars "RESKIT_GH_APP_ID" and "RESKIT_GH_APP_PRIVATE_KEY" must +be set. The former as a string, the latter as a path to a PEM key. +} +\keyword{internal} diff --git a/man/get_github_jwt.Rd b/man/get_github_jwt.Rd new file mode 100644 index 0000000..fcca969 --- /dev/null +++ b/man/get_github_jwt.Rd @@ -0,0 +1,16 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/get_github_file.R +\name{get_github_jwt} +\alias{get_github_jwt} +\title{Returns a GitHub JWT for the reskit authentication app} +\usage{ +get_github_jwt() +} +\value{ +A JSON Web Token (JWT) as a string +} +\description{ +The envvars "RESKIT_GH_APP_ID" and "RESKIT_GH_APP_PRIVATE_KEY" must +be set. The former as a string, the latter as a path to a PEM key. +} +\keyword{internal} diff --git a/man/get_github_pat.Rd b/man/get_github_pat.Rd new file mode 100644 index 0000000..fc58e77 --- /dev/null +++ b/man/get_github_pat.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/get_github_file.R +\name{get_github_pat} +\alias{get_github_pat} +\title{Return a GitHub access token} +\usage{ +get_github_pat() +} +\value{ +A personal access token (PAT) with permissions granted to the app +} +\description{ +If the envvar "RESKIT_GH_APP_PAT" is set, this will be used as the token. +Otherwise, the envvars "RESKIT_GH_APP_ID" and "RESKIT_GH_APP_PRIVATE_KEY" +must be set. The former as a string, the latter as a path to a PEM key. +} +\keyword{internal} diff --git a/man/get_github_pat_via_api.Rd b/man/get_github_pat_via_api.Rd new file mode 100644 index 0000000..1ff2538 --- /dev/null +++ b/man/get_github_pat_via_api.Rd @@ -0,0 +1,16 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/get_github_file.R +\name{get_github_pat_via_api} +\alias{get_github_pat_via_api} +\title{Return a GitHub PAT via the API using the reskit authentication GitHub app} +\usage{ +get_github_pat_via_api() +} +\value{ +An access token (PAT) as a string +} +\description{ +The envvars "RESKIT_GH_APP_ID" and "RESKIT_GH_APP_PRIVATE_KEY" must +be set. The former as a string, the latter as a path to a PEM key. +} +\keyword{internal} diff --git a/man/get_ipop_initial_means.Rd b/man/get_ipop_initial_means.Rd new file mode 100644 index 0000000..5f2ef9d --- /dev/null +++ b/man/get_ipop_initial_means.Rd @@ -0,0 +1,12 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/demo_results_tables.R +\name{get_ipop_initial_means} +\alias{get_ipop_initial_means} +\title{Helper function} +\usage{ +get_ipop_initial_means(ip_mean, op_mean) +} +\description{ +Helper function +} +\keyword{internal} diff --git a/man/get_outputs_gh_file.Rd b/man/get_outputs_gh_file.Rd deleted file mode 100644 index 807b366..0000000 --- a/man/get_outputs_gh_file.Rd +++ /dev/null @@ -1,21 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/get_github_file.R -\name{get_outputs_gh_file} -\alias{get_outputs_gh_file} -\title{Read in a file from the NHP Outputs app GitHub repo} -\usage{ -get_outputs_gh_file(file, folder = "inst") -} -\arguments{ -\item{file}{string. The name of the file to read in} - -\item{folder}{string. The folder where the file is located. \code{"inst"} by -default. Set to \code{""} to use the root folder of the repo.} -} -\value{ -The file contents as a stream, to be passed to a reader function -} -\description{ -Read in a file from the NHP Outputs app GitHub repo -} -\keyword{internal} diff --git a/man/get_outputs_gh_url.Rd b/man/get_outputs_gh_url.Rd new file mode 100644 index 0000000..201e1ab --- /dev/null +++ b/man/get_outputs_gh_url.Rd @@ -0,0 +1,15 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/get_github_file.R +\name{get_outputs_gh_url} +\alias{get_outputs_gh_url} +\title{Get the direct URL to a file in the NHP Outputs GitHub repo} +\usage{ +get_outputs_gh_url(...) +} +\arguments{ +\item{...}{Pass the name of the file in via \code{...}} +} +\description{ +Get the direct URL to a file in the NHP Outputs GitHub repo +} +\keyword{internal} diff --git a/man/get_su_gh_file.Rd b/man/get_su_gh_file.Rd new file mode 100644 index 0000000..221b84c --- /dev/null +++ b/man/get_su_gh_file.Rd @@ -0,0 +1,23 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/get_github_file.R +\name{get_su_gh_file} +\alias{get_su_gh_file} +\title{Read in a file from a Strategy Unit GitHub repo} +\usage{ +get_su_gh_file(repo, folder, file) +} +\arguments{ +\item{repo}{string. The name of the repository in which to find the file} + +\item{folder}{string. The folder where the file is located. Set to \code{""} to +use the root folder of the repo.} + +\item{file}{string. The name of the file to read in} +} +\value{ +The URL to the raw file contents, to be passed to a reader function +} +\description{ +Read in a file from a Strategy Unit GitHub repo +} +\keyword{internal} diff --git a/man/get_tpma_label_lookup.Rd b/man/get_tpma_label_lookup.Rd index f83148e..dbba986 100644 --- a/man/get_tpma_label_lookup.Rd +++ b/man/get_tpma_label_lookup.Rd @@ -4,19 +4,11 @@ \alias{get_tpma_label_lookup} \title{Prepare a lookup table for all current TPMAs} \usage{ -get_tpma_label_lookup(use_local = FALSE) -} -\arguments{ -\item{use_local}{logical. Whether to use a local file (internal to the -reskit package) or attempt to pull the lookup file from GitHub. Default is -\code{FALSE}, meaning it will use the GitHub route. If you want to always use a -local file (for example, for fully offline working), you can set the -\code{reskit.local.lookups} option to \code{TRUE} using -\code{options(reskit.local.lookups = TRUE)} or \code{withr::with_options()}} +get_tpma_label_lookup() } \value{ -A 4-column tibble, with columns \code{activity_type}, \code{change_factor}, -\code{strategy} and \code{tpma_label} +A 4-column tibble, with columns \code{strategy}, \code{activity_type}, +\code{change_factor} and \code{tpma_label} } \description{ Prepare a lookup table for all current TPMAs diff --git a/man/get_tpmas_gh_file.Rd b/man/get_tpmas_gh_file.Rd deleted file mode 100644 index bd27243..0000000 --- a/man/get_tpmas_gh_file.Rd +++ /dev/null @@ -1,21 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/get_github_file.R -\name{get_tpmas_gh_file} -\alias{get_tpmas_gh_file} -\title{Read in a file from the TPMAs GitHub repo} -\usage{ -get_tpmas_gh_file(file, folder = "reference") -} -\arguments{ -\item{file}{string. The name of the file to read in} - -\item{folder}{string. The folder where the file is located. \code{"reference"} by -default. Set to \code{""} to use the root folder of the repo.} -} -\value{ -The file contents as a stream, to be passed to a reader function -} -\description{ -Read in a file from the TPMAs GitHub repo -} -\keyword{internal} diff --git a/man/get_tpmas_gh_url.Rd b/man/get_tpmas_gh_url.Rd new file mode 100644 index 0000000..76ac56e --- /dev/null +++ b/man/get_tpmas_gh_url.Rd @@ -0,0 +1,15 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/get_github_file.R +\name{get_tpmas_gh_url} +\alias{get_tpmas_gh_url} +\title{Get the direct URL to a file in the TPMAs GitHub repo} +\usage{ +get_tpmas_gh_url(...) +} +\arguments{ +\item{...}{Pass the name of the file in via \code{...}} +} +\description{ +Get the direct URL to a file in the TPMAs GitHub repo +} +\keyword{internal} diff --git a/man/make_detailed_activity_table.Rd b/man/make_detailed_activity_table.Rd index 50bee6a..518fafc 100644 --- a/man/make_detailed_activity_table.Rd +++ b/man/make_detailed_activity_table.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/tables.R \name{make_detailed_activity_table} \alias{make_detailed_activity_table} -\title{Create a gt table with data from compile_detailed_activity_data()} +\title{Create a gt table with data from \link{compile_detailed_activity_data}} \usage{ make_detailed_activity_table(detailed_activity_data, final_year) } @@ -15,5 +15,5 @@ make_detailed_activity_table(detailed_activity_data, final_year) A gt table } \description{ -Create a gt table with data from compile_detailed_activity_data() +Create a gt table with data from \link{compile_detailed_activity_data} } diff --git a/man/make_distribution_summary_table.Rd b/man/make_distribution_summary_table.Rd index a03e3ff..b47f369 100644 --- a/man/make_distribution_summary_table.Rd +++ b/man/make_distribution_summary_table.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/tables.R \name{make_distribution_summary_table} \alias{make_distribution_summary_table} -\title{Create a gt table with data from compile_distribution_summary_data()} +\title{Create a gt table with data from \link{compile_distribution_summary_data}} \usage{ make_distribution_summary_table(distr_summary_data) } @@ -13,5 +13,5 @@ make_distribution_summary_table(distr_summary_data) A gt table } \description{ -Create a gt table with data from compile_distribution_summary_data() +Create a gt table with data from \link{compile_distribution_summary_data} } diff --git a/man/read_pods_lookup.Rd b/man/read_pods_lookup.Rd new file mode 100644 index 0000000..e75fff0 --- /dev/null +++ b/man/read_pods_lookup.Rd @@ -0,0 +1,11 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/get_github_file.R +\name{read_pods_lookup} +\alias{read_pods_lookup} +\title{Read the pods lookup table from a YAML file in the NHP Outputs repo} +\usage{ +read_pods_lookup(file = "golem-config.yml") +} +\description{ +Read the pods lookup table from a YAML file in the NHP Outputs repo +} diff --git a/man/read_tpmas_lookup.Rd b/man/read_tpmas_lookup.Rd new file mode 100644 index 0000000..64e0570 --- /dev/null +++ b/man/read_tpmas_lookup.Rd @@ -0,0 +1,11 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/get_github_file.R +\name{read_tpmas_lookup} +\alias{read_tpmas_lookup} +\title{Read the TPMAs lookup table from a CSV file in the TPMAs repo} +\usage{ +read_tpmas_lookup(file = "tpma-lookup.csv") +} +\description{ +Read the TPMAs lookup table from a CSV file in the TPMAs repo +} diff --git a/vignettes/.gitignore b/vignettes/.gitignore new file mode 100644 index 0000000..cc7173d --- /dev/null +++ b/vignettes/.gitignore @@ -0,0 +1,6 @@ +*.html +*.R +*_files + +/.quarto/ +**/*.quarto_ipynb diff --git a/vignettes/misc.qmd b/vignettes/misc.qmd new file mode 100644 index 0000000..6d0632c --- /dev/null +++ b/vignettes/misc.qmd @@ -0,0 +1,309 @@ + +### Impact of changes - overall ("waterfall") chart with baseline + +Selecting `pods = NULL` would use data + +```{r} +results |> + purrr::pluck("step_counts") |> + compile_change_factor_data( + measure = "admissions", + activity_type = "ip", + pods = c( + "Daycase Admission", + "Maternity Admission", + "Non-Elective Admission" + ), + sites = NULL, + include_baseline = TRUE + ) |> + make_overall_cf_plot() +``` + + + +### Impact of changes - overall ("waterfall") chart without baseline + +```{r} +results |> + purrr::pluck("step_counts") |> + compile_change_factor_data( + activity_type = "Inpatient", + pods = c( + "Daycase Admission", + "Maternity Admission", + "Non-Elective Admission" + ), + measure = "Admissions", + sites = NULL, + include_baseline = FALSE + ) |> + make_overall_cf_plot() +``` + + +### Impact of changes - individual TPMA chart, Admissions measure, sort by value + + +```{r} +measure <- "Admissions" + +results |> + purrr::pluck("step_counts") |> + compile_indiv_change_factor_data( + activity_type = "Inpatient", + pods = c( + "Daycase Admission", + "Maternity Admission", + "Non-Elective Admission" + ), + measure = measure, + sort_by = "value", + sites = NULL + ) |> + make_individual_cf_plot(x_axis_label = measure) +``` + + +### Impact of changes - individual TPMA chart, Admissions measure, sorted by name + + +```{r} +measure <- "Admissions" + +results |> + purrr::pluck("step_counts") |> + compile_indiv_change_factor_data( + activity_type = "Inpatient", + pods = c( + "Daycase Admission", + "Maternity Admission", + "Non-Elective Admission" + ), + measure = measure, + sort_by = "tpma_label", + sites = NULL + ) |> + make_individual_cf_plot(x_axis_label = measure) +``` + + +### Impact of changes - individual TPMA chart, Bed Days measure, sort by value + + +```{r} +measure <- "Beddays" + +results |> + purrr::pluck("step_counts") |> + compile_indiv_change_factor_data( + activity_type = "Inpatient", + pods = c( + "Daycase Admission", + "Maternity Admission", + "Non-Elective Admission" + ), + measure = measure, + sort_by = "value", + sites = NULL + ) |> + make_individual_cf_plot(x_axis_label = measure) +``` + + +### Activity in detail table - IP activity by sex and age group + + +```{r} +results |> + compile_detailed_activity_data() +# filter_detailed_activity_data( +# aggregation = "age_group", +# activity_type = "ip", +# pods = +# ) +``` + + + + + + +## Breakdown of a data preparation function + +This section shows the interim steps generated by the constituent functions and +processes with an example data preparation function. + +We will look at `compile_principal_pod_data()` here. + +```{r} +#| echo: false +def <- results[["default"]] +``` + +Starting with the default table, before applying any functions to it, we can see +that it has `r ncol(def)` columns. +Several of these are "metadata" columns - containing only a single unique value, +such as the name of the scenario - that we won't need for the further processing +of the table. + +The data columns we need to work with are: + +* `sitetret` +* `pod` +* `measure` +* `model_run`, and +* `value` + +(Other results tables will have a different selection of column names that we +would need to use.) + + +```{r} +results[["default"]] +``` + +In preparing the data for visualisation, we apply the +`compile_principal_pod_data()` function. +This runs through a sequence of functions that transform and summarise the data. +These are, in turn: + +* `prepare_sites_principal_pod_data()` +* `filter_to_selected_sites()` + `summarise_for_all_sites()` +* `add_change_cols()` +* final preparations, via for example `forcats::fct()` and `dplyr::arrange()` + + +```{r} +interim1 <- results[["default"]] |> + prepare_sites_principal_pod_data() +interim1 +``` + +The `prepare_sites_principal_pod_data()` function applies some filters to the +data table and adds a human-friendly `pod_label` column (via `relabel_pods()`), +then - even more importantly - applies `calculate_principal_stats()`. +This last function calculates the "p10" and "p90" values as well as the mean of +the values across all the model runs for each combination of `pod` and +`measure` (in this case). + +### Breaking down `prepare_sites_principal_pod_data()` + +Let's have a look at how these functions change the shape and content of the +data table to create the `interim1` object shown above. + +Firstly there are some initial changes and filters: + +```{r} +interim1a <- results[["default"]] |> + dplyr::filter(dplyr::if_any("measure", \(x) x %in% keep_measures())) |> + dplyr::filter( + # exclude outpatient procedures from tele-attendances count only + dplyr::if_any("measure", \(x) x != "tele_attendances") | + dplyr::if_any("pod", \(x) x != "op_procedure") + ) |> + dplyr::mutate(dplyr::across("pod", \(x) sub("^aae.*$", "aae", x))) +interim1a +``` + +Now joining to a lookup of POD (point of delivery) codes and labels: + +```{r} +interim1b <- interim1a |> + inner_join_for_labels(get_principal_pods()) |> + relabel_pods() +interim1b +``` + +We now have a new `activity_type_label` column. + +And then, summarising by certain fields to calculate the mean values: + + +```{r} +interim1c <- interim1b |> + calculate_principal_stats(default_group_cols("activity_type_label")) |> + dplyr::filter(dplyr::if_any("stat", \(x) x == "mean")) |> + dplyr::select(!"stat") +interim1c +``` + +```{r} +identical(interim1c, interim1) +``` + +`calculate_principal_stats()` helps us treat model run 0 as a "baseline" value, +and model runs 1-256 as the basis for our "principal" projection. + +We now have a table with just `r nrow(interim1c)` rows and `r ncol(interim1c)` +columns, and some quite different column names to the table we started with. + +### Subsequent steps + +The above steps will be the same no matter what the user of the NHP Outputs app +selects. + +Next there is a further step that will depend on the selection of sites chosen +by the user. +The default selection is `NULL`, meaning all sites in the data will be included. +The dataset we are using in this vignette is "national", which means we don't +have any specific sites to filter by in any case. +But for a local scheme, a user could choose to filter results data just to +specific sites. + +The `filter_to_selected_sites()` and `summarise_for_all_sites()` functions +deal with this. + +`add_change_cols()` calculates the change from the baseline values to the +mean principal projected values, as an absolute number and as a percentage. + +Let's apply these anyway to our output from +`prepare_sites_principal_pod_data()`, and then apply `add_change_cols()`. + + +```{r} +interim2 <- interim1 |> + filter_to_selected_sites(NULL) |> + summarise_for_all_sites(site_col = "sitetret") |> + add_change_cols() +interim2 +``` + +Then our final steps in this breakdown of `compile_principal_pod_data()`. + +We should have ended up reproducing the output we get from simply running +`compile_principal_pod_data(results[["default"]])`: + +```{r} +at_levels <- c( + "Inpatient Admissions", + "Inpatient Bed Days", + "Outpatient", + "A&E" +) +interim3 <- interim2 |> + dplyr::mutate( + dplyr::across("activity_type_label", \(x) forcats::fct(x, at_levels)), + # display pods in descending order of baseline value, by activity type + dplyr::across("pod_label", \(x) { + forcats::fct_reorder(x, .data[["baseline"]], sum, .desc = TRUE) + }) + ) |> + dplyr::arrange(dplyr::pick(c("activity_type_label", "pod_label"))) +interim3 +``` + +This data table is now in the expected format to be passed through to +`make_principal_pod_table()`. + +### Other data preparation functions + +Exploring each preparation pipeline in detail would make this a very lengthy +vignette. +However they do share some common functions and techniques. + +Other data preparation functions in {reskit} include: + +* `compile_principal_los_data()`, used to prepare data for `make_principal_los_table()` +* `compile_change_factor_data()`, used to prepare data for `make_overall_cf_plot()` +* and so on diff --git a/vignettes/nhp_reskit.qmd b/vignettes/nhp_reskit.qmd new file mode 100644 index 0000000..7524e79 --- /dev/null +++ b/vignettes/nhp_reskit.qmd @@ -0,0 +1,16 @@ +--- +title: "nhp_reskit" +vignette: > + %\VignetteIndexEntry{nhp_reskit} + %\VignetteEngine{quarto::html} + %\VignetteEncoding{UTF-8} +knitr: + opts_chunk: + collapse: true + comment: '#>' +--- + +```{r} +#| label: setup +library(reskit) +``` diff --git a/vignettes/plots_tables.qmd b/vignettes/plots_tables.qmd new file mode 100644 index 0000000..58fc9aa --- /dev/null +++ b/vignettes/plots_tables.qmd @@ -0,0 +1,298 @@ +--- +title: "Plots and tables with reskit" +vignette: > + %\VignetteIndexEntry{Plots and tables with reskit} + %\VignetteEngine{quarto::html} + %\VignetteEncoding{UTF-8} +lang: en-GB +date: today +theme: lumen +code-fold: show +fig-width: 12 +fig-asp: 0.618 +knitr: + opts_chunk: + collapse: true + comment: '#>' +--- + +The aims of this vignette are to: + +* illustrate usage patterns of some of the functions in {reskit} +* provide a set of test/example outputs of tables and charts derived from NHP + demand model results data. + +The latter may be visually compared to / validated against visualisations +currently produced by the NHP Outputs app. + +Firstly we load the functions in the {reskit} package. +Then we create a fake `results` object which consists of synthetic data +created by some internal reskit functions. +It ought to go without saying that the numbers in these synthetic tables are +entirely fictitious and unrealistic. +They exist purely to provide a test basis for the data processing and +visualisation functions in this package. + + +```{r} +#| label: setup +# library(reskit) +purrr::walk(dir(here::here("R"), full.names = TRUE), source) +seed <- 1871 +``` + +## Example using azkit and reskit to download results + +Here is an example of some code that you might use to access results data from +Azure storage + + +```r +token <- azkit::get_auth_token() +results_container <- azkit::get_container( + Sys.getenv("AZ_RESULTS_CONTAINER"), + token = token +) + +# use various filters to get the right dataset (PartitionKey), model version and +# scenario from a runs lookup table +results_path <- azkit::read_azure_table( + Sys.getenv("AZ_RUNS_TABLE"), + token = token, + filter = "PartitionKey eq 'national' and app_version eq 'v5.1'", + select = "aggregated_results_path" +) |> + dplyr::pull("aggregated_results_path") |> + grepv(pattern = "NDG2\\-zero") |> + dplyr::first() # ensure we only get 1 path! + +results <- read_results_parquet_files(results_container, results_path) +``` + +```{r} +#| label: create-demo-data +#| cache: true +#| cache-refresh: false +default_tbl <- create_demo_default_tbl(seed) +tretspef_losgroup_tbl <- create_demo_tretspef_losgroup_tbl(seed) +sex_agegroup_tbl <- create_demo_sex_agegroup_tbl(seed) +sex_tretspef_tbl <- create_demo_sex_tretspef_tbl(seed) +stepcounts_tbl <- create_demo_stepcounts_tbl(seed) + +# fmt: skip +tbl_names <- c( + "default", "tretspef+los_group", "sex+age_group", + "sex+tretspef_grouped", "step_counts" +) + +results <- list( + default_tbl, + tretspef_losgroup_tbl, + sex_agegroup_tbl, + sex_tretspef_tbl, + stepcounts_tbl +) |> + rlang::set_names(tbl_names) +``` + + +Having shown one way of accessing the results parquet files, this vignette now +runs through the suggested pipelines of functions that generate the NHP Outputs +app tables and charts, which usually comprise in their simplest form, a data +preparation function which passes data into a table or chart creation function. + +This series of example outputs is followed by a breakdown of one of the data +preparation functions, showing how a results data table may be filtered, +enhanced, summarised and arranged using {reskit} functions to produce standard +statistics and outputs. + + +## Outputs: tables + + +### "Main summary table" - overall change by Point of Delivery + +This uses the "default" table (from `default.parquet`), passing it to the +`compile_principal_pod_data` function which prepares the data for the table. + +The only relevant filter here is for site selection. + +Then the `make_principal_pod_table` function generates the table. + + +```{r} +#| label: main-summary-table1 +results |> + compile_principal_pod_data() |> + make_principal_pod_table() +``` + +Now the same thing again but testing the site selection feature. +We should get a similar style table but with smaller numbers as we have +filtered down to just one site. + +```{r} +#| label: main-summary-table2 +results |> + compile_principal_pod_data(sites = "site1") |> + make_principal_pod_table() +``` + + +### The principal LoS table + + +This uses data from the "tretspef+los_group" results table. + +With `measure` set to "beddays": + +```{r} +#| label: los-summary-table1 +results |> + compile_principal_los_data(measure = "beddays") |> + make_principal_los_table() +``` + + +With `measure` set to "admissions": + +```{r} +#| label: los-summary-table2 +results |> + compile_principal_los_data(measure = "admissions", sites = "site2") |> + make_principal_los_table() +``` + +## Outputs: charts + +### Impact of changes charts + +For these we need to use carefully chosen combinations of measure, activity +type, and pod. + +#### Overall ("waterfall") chart with baseline + +As this is for admissions, "efficiencies" should not be shown on the y-axis. + +```{r} +#| label: waterfall-chart1 +results |> + compile_change_factor_data( + measure = "admissions", + activity_type = "ip", + pods = c( + "ip_elective_admission", + "ip_maternity_admission", + "ip_non-elective_admission" + ), + include_baseline = TRUE + ) |> + make_overall_cf_plot() +``` + + +```{r} +#| label: waterfall-chart2 +results |> + compile_change_factor_data( + measure = "beddays", + activity_type = "ip", + pods = c( + "ip_elective_admission", + "ip_maternity_admission", + "ip_non-elective_admission" + ), + sites = "site1", + include_baseline = TRUE + ) |> + make_overall_cf_plot() +``` + +Let's look at an outpatients chart... + +```{r} +#| label: waterfall-chart3 +results |> + compile_change_factor_data( + measure = "attendances", + activity_type = "op", + pods = c("op_first", "op_follow-up") + ) |> + make_overall_cf_plot() +``` + + +...and one without the baseline: + +```{r} +#| label: waterfall-chart4 +results |> + compile_change_factor_data( + measure = "attendances", + activity_type = "op", + pods = c("op_first", "op_follow-up"), + include_baseline = FALSE + ) |> + make_overall_cf_plot() +``` + + +#### Individual change factor charts + + +And a couple of individual change factor charts: + +```{r} +#| label: indiv-waterfall-chart1 +results |> + compile_indiv_change_factor_data( + measure = "attendances", + activity_type = "op", + pods = NULL + ) |> + make_individual_cf_plot() +``` + + +```{r} +#| label: indiv-waterfall-chart2 +results |> + compile_indiv_change_factor_data( + measure = "arrivals", + activity_type = "aae", + pods = NULL, + sites = "site2" + ) |> + make_individual_cf_plot() +``` + + +### Activity in detail charts + + +These are even more tricky to specify as they require several arguments to be +provided. + +#### A chart by sex and age_group + +```{r} +#| label: activity-detail-chart1 +results |> + compile_detailed_activity_data( + measure = "walk-in", + activity_type = "aae", + aggregation = "age_group" + ) |> + make_detailed_activity_table(final_year = "2029/30") +``` + +```{r} +#| label: activity-detail-chart2 +results |> + compile_detailed_activity_data( + measure = "beddays", + activity_type = "ip", + aggregation = "tretspef_grouped" + ) |> + make_detailed_activity_table(final_year = "2029/30") +```