-
Notifications
You must be signed in to change notification settings - Fork 0
Standardize Locations Exclusion-Inclusion Logic #178
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
acbdbb8
5d756be
bc37c4a
c576514
e53102b
fcf311b
e7c82ac
b91733c
fbc1159
641e497
87bc184
9bd2bb1
0df2574
5bc406c
f8d5c64
2e7102b
413d3f5
d9a6ac1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,74 +1 @@ | ||
| #' Two digits FIPS codes for locations excluded from Hubs' | ||
| #' target data. | ||
| #' | ||
| #' Excludes Virgin Islands (78), Northern Mariana | ||
| #' Islands (69), Guam (66), American Samoa (60), and Minor | ||
| #' Outlying Islands (74). | ||
| #' | ||
| #' @export | ||
| excluded_locations <- c("78", "74", "69", "66", "60") | ||
|
|
||
| #' Two digits FIPS codes for locations included in Hubs' | ||
| #' target data. | ||
| #' | ||
| #' Includes 50 states, US national, DC, and Puerto Rico | ||
| #' (PR). Excludes Virgin Islands (78), Northern Mariana | ||
| #' Islands (69), Guam (66), American Samoa (60), and Minor | ||
| #' Outlying Islands (74). | ||
| #' | ||
| #' @export | ||
| included_locations <- c( | ||
| "01", | ||
| "02", | ||
| "04", | ||
| "05", | ||
| "06", | ||
| "08", | ||
| "09", | ||
| "10", | ||
| "11", | ||
| "12", | ||
| "13", | ||
| "15", | ||
| "16", | ||
| "17", | ||
| "18", | ||
| "19", | ||
| "20", | ||
| "21", | ||
| "22", | ||
| "23", | ||
| "24", | ||
| "25", | ||
| "26", | ||
| "27", | ||
| "28", | ||
| "29", | ||
| "30", | ||
| "31", | ||
| "32", | ||
| "33", | ||
| "34", | ||
| "35", | ||
| "36", | ||
| "37", | ||
| "38", | ||
| "39", | ||
| "40", | ||
| "41", | ||
| "42", | ||
| "44", | ||
| "45", | ||
| "46", | ||
| "47", | ||
| "48", | ||
| "49", | ||
| "50", | ||
| "51", | ||
| "53", | ||
| "54", | ||
| "55", | ||
| "56", | ||
| "72", | ||
| "US" | ||
| ) | ||
| # constants used across hubhelpr functions. |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,176 @@ | ||||||||||||||||||||||||||||||||||||||||||||||
| #' Normalize excluded locations to a named list. | ||||||||||||||||||||||||||||||||||||||||||||||
| #' | ||||||||||||||||||||||||||||||||||||||||||||||
| #' Converts a character vector or named list of excluded | ||||||||||||||||||||||||||||||||||||||||||||||
| #' locations into a consistent named list format. | ||||||||||||||||||||||||||||||||||||||||||||||
| #' Validates that all abbreviations are valid US | ||||||||||||||||||||||||||||||||||||||||||||||
| #' state/territory abbreviations. | ||||||||||||||||||||||||||||||||||||||||||||||
| #' | ||||||||||||||||||||||||||||||||||||||||||||||
| #' @param excluded_locations NULL, character vector, or | ||||||||||||||||||||||||||||||||||||||||||||||
| #' named list of character vectors. | ||||||||||||||||||||||||||||||||||||||||||||||
| #' | ||||||||||||||||||||||||||||||||||||||||||||||
| #' @return Named list of character vectors, or NULL if | ||||||||||||||||||||||||||||||||||||||||||||||
| #' input is NULL or zero-length. | ||||||||||||||||||||||||||||||||||||||||||||||
| #' @noRd | ||||||||||||||||||||||||||||||||||||||||||||||
| normalize_excluded_locations <- function(excluded_locations) { | ||||||||||||||||||||||||||||||||||||||||||||||
| if (is.null(excluded_locations) || length(excluded_locations) == 0) { | ||||||||||||||||||||||||||||||||||||||||||||||
| return(NULL) | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
| if (is.character(excluded_locations)) { | ||||||||||||||||||||||||||||||||||||||||||||||
| assert_valid_location_abbrs(excluded_locations) | ||||||||||||||||||||||||||||||||||||||||||||||
| return(list("all" = excluded_locations)) | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
| if (is.list(excluded_locations)) { | ||||||||||||||||||||||||||||||||||||||||||||||
| purrr::walk(excluded_locations, function(x) { | ||||||||||||||||||||||||||||||||||||||||||||||
| checkmate::assert_character( | ||||||||||||||||||||||||||||||||||||||||||||||
| x, | ||||||||||||||||||||||||||||||||||||||||||||||
| .var.name = "excluded_locations list values" | ||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||
| assert_valid_location_abbrs(x) | ||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||
| return(excluded_locations) | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
| cli::cli_abort( | ||||||||||||||||||||||||||||||||||||||||||||||
| "{.arg excluded_locations} must be NULL, a character vector, or a named list." | ||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| #' Assert that location abbreviations are valid. | ||||||||||||||||||||||||||||||||||||||||||||||
| #' | ||||||||||||||||||||||||||||||||||||||||||||||
| #' Checks that all provided abbreviations are present | ||||||||||||||||||||||||||||||||||||||||||||||
| #' in the US location table (from forecasttools). | ||||||||||||||||||||||||||||||||||||||||||||||
| #' Errors with a message listing any invalid | ||||||||||||||||||||||||||||||||||||||||||||||
| #' abbreviations. | ||||||||||||||||||||||||||||||||||||||||||||||
| #' | ||||||||||||||||||||||||||||||||||||||||||||||
| #' @param abbrs Character vector of abbreviations to | ||||||||||||||||||||||||||||||||||||||||||||||
| #' validate. | ||||||||||||||||||||||||||||||||||||||||||||||
| #' | ||||||||||||||||||||||||||||||||||||||||||||||
| #' @return Invisible NULL. Called for side effects. | ||||||||||||||||||||||||||||||||||||||||||||||
| #' @noRd | ||||||||||||||||||||||||||||||||||||||||||||||
| assert_valid_location_abbrs <- function(abbrs) { | ||||||||||||||||||||||||||||||||||||||||||||||
| valid_abbrs <- forecasttools::us_location_table$abbr | ||||||||||||||||||||||||||||||||||||||||||||||
| invalid <- setdiff(abbrs, valid_abbrs) | ||||||||||||||||||||||||||||||||||||||||||||||
| if (length(invalid) > 0) { | ||||||||||||||||||||||||||||||||||||||||||||||
| cli::cli_abort( | ||||||||||||||||||||||||||||||||||||||||||||||
| "{.arg excluded_locations} contains invalid abbreviation{?s}: {.val {invalid}}." | ||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| #' Get excluded abbreviations for a specific target. | ||||||||||||||||||||||||||||||||||||||||||||||
| #' | ||||||||||||||||||||||||||||||||||||||||||||||
| #' Extracts the abbreviations that should be excluded | ||||||||||||||||||||||||||||||||||||||||||||||
| #' for a given target from a normalized exclusion list, | ||||||||||||||||||||||||||||||||||||||||||||||
| #' combining global ("all") exclusions with any | ||||||||||||||||||||||||||||||||||||||||||||||
| #' target-specific ones. | ||||||||||||||||||||||||||||||||||||||||||||||
| #' | ||||||||||||||||||||||||||||||||||||||||||||||
| #' @param normalized Named list as returned by | ||||||||||||||||||||||||||||||||||||||||||||||
| #' `normalize_excluded_locations()`. | ||||||||||||||||||||||||||||||||||||||||||||||
| #' @param target Character, the target name. | ||||||||||||||||||||||||||||||||||||||||||||||
| #' | ||||||||||||||||||||||||||||||||||||||||||||||
| #' @return Character vector of unique abbreviations to | ||||||||||||||||||||||||||||||||||||||||||||||
| #' exclude for this target. | ||||||||||||||||||||||||||||||||||||||||||||||
| #' @noRd | ||||||||||||||||||||||||||||||||||||||||||||||
| get_target_exclusions <- function(normalized, target) { | ||||||||||||||||||||||||||||||||||||||||||||||
| unique(c(normalized[["all"]], normalized[[target]])) | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| #' Apply target-specific location exclusions to a data | ||||||||||||||||||||||||||||||||||||||||||||||
| #' frame. | ||||||||||||||||||||||||||||||||||||||||||||||
| #' | ||||||||||||||||||||||||||||||||||||||||||||||
| #' Removes rows from a data frame based on | ||||||||||||||||||||||||||||||||||||||||||||||
| #' target-specific excluded location abbreviations. | ||||||||||||||||||||||||||||||||||||||||||||||
| #' Supports uniform exclusions (character vector applied | ||||||||||||||||||||||||||||||||||||||||||||||
| #' to all targets) and target-specific exclusions (named | ||||||||||||||||||||||||||||||||||||||||||||||
| #' list with target names as keys). Validates target | ||||||||||||||||||||||||||||||||||||||||||||||
| #' names against the targets present in the data. | ||||||||||||||||||||||||||||||||||||||||||||||
| #' Filters on the "target" and "location" columns via | ||||||||||||||||||||||||||||||||||||||||||||||
| #' anti-join. | ||||||||||||||||||||||||||||||||||||||||||||||
| #' | ||||||||||||||||||||||||||||||||||||||||||||||
| #' @param data Data frame with "target" and "location" | ||||||||||||||||||||||||||||||||||||||||||||||
| #' columns. | ||||||||||||||||||||||||||||||||||||||||||||||
| #' @param excluded_locations NULL, character vector, or | ||||||||||||||||||||||||||||||||||||||||||||||
| #' named list of US state/territory abbreviations to | ||||||||||||||||||||||||||||||||||||||||||||||
| #' exclude. If a character vector, locations are | ||||||||||||||||||||||||||||||||||||||||||||||
| #' excluded across all targets. If a named list, names | ||||||||||||||||||||||||||||||||||||||||||||||
| #' should be target names (or "all" for global | ||||||||||||||||||||||||||||||||||||||||||||||
| #' exclusions) mapping to character vectors of | ||||||||||||||||||||||||||||||||||||||||||||||
| #' abbreviations. | ||||||||||||||||||||||||||||||||||||||||||||||
| #' | ||||||||||||||||||||||||||||||||||||||||||||||
| #' @return Data frame with excluded rows removed. | ||||||||||||||||||||||||||||||||||||||||||||||
| #' @export | ||||||||||||||||||||||||||||||||||||||||||||||
| apply_target_location_exclusions <- function( | ||||||||||||||||||||||||||||||||||||||||||||||
| data, | ||||||||||||||||||||||||||||||||||||||||||||||
| excluded_locations | ||||||||||||||||||||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||||||||||||||||||||
| normalized <- normalize_excluded_locations(excluded_locations) | ||||||||||||||||||||||||||||||||||||||||||||||
| if (is.null(normalized)) { | ||||||||||||||||||||||||||||||||||||||||||||||
| return(data) | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| data_targets <- unique(data$target) | ||||||||||||||||||||||||||||||||||||||||||||||
| named_targets <- setdiff(names(normalized), "all") | ||||||||||||||||||||||||||||||||||||||||||||||
| unmatched <- setdiff(named_targets, data_targets) | ||||||||||||||||||||||||||||||||||||||||||||||
| if (length(unmatched) > 0) { | ||||||||||||||||||||||||||||||||||||||||||||||
| cli::cli_warn( | ||||||||||||||||||||||||||||||||||||||||||||||
| "{.arg excluded_locations} contains target{?s} not in data: {.val {unmatched}}." | ||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| exclusion_df <- purrr::map_df(data_targets, \(tgt) { | ||||||||||||||||||||||||||||||||||||||||||||||
| excl_abbrs <- get_target_exclusions(normalized, tgt) | ||||||||||||||||||||||||||||||||||||||||||||||
| if (length(excl_abbrs) == 0) { | ||||||||||||||||||||||||||||||||||||||||||||||
| return(tibble::tibble(target = character(), location = character())) | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
| tibble::tibble( | ||||||||||||||||||||||||||||||||||||||||||||||
| target = tgt, | ||||||||||||||||||||||||||||||||||||||||||||||
| location = forecasttools::us_location_recode(excl_abbrs, "abbr", "hub") | ||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+122
to
+131
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will implicitly handle empty rows
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| dplyr::anti_join( | ||||||||||||||||||||||||||||||||||||||||||||||
| data, | ||||||||||||||||||||||||||||||||||||||||||||||
| exclusion_df, | ||||||||||||||||||||||||||||||||||||||||||||||
| by = c("target", "location") | ||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| #' Filter data to included locations only. | ||||||||||||||||||||||||||||||||||||||||||||||
| #' | ||||||||||||||||||||||||||||||||||||||||||||||
| #' Only keeps rows where location is in the set of | ||||||||||||||||||||||||||||||||||||||||||||||
| #' valid US locations minus any excluded locations for | ||||||||||||||||||||||||||||||||||||||||||||||
| #' that target. | ||||||||||||||||||||||||||||||||||||||||||||||
| #' | ||||||||||||||||||||||||||||||||||||||||||||||
| #' @param data Data frame with "target" and "location" | ||||||||||||||||||||||||||||||||||||||||||||||
| #' columns. | ||||||||||||||||||||||||||||||||||||||||||||||
| #' @param excluded_locations NULL, character vector, or | ||||||||||||||||||||||||||||||||||||||||||||||
| #' named list of US state/territory abbreviations to | ||||||||||||||||||||||||||||||||||||||||||||||
| #' exclude. | ||||||||||||||||||||||||||||||||||||||||||||||
| #' | ||||||||||||||||||||||||||||||||||||||||||||||
| #' @return Data frame filtered to included locations. | ||||||||||||||||||||||||||||||||||||||||||||||
| #' @noRd | ||||||||||||||||||||||||||||||||||||||||||||||
| filter_to_included_locations <- function( | ||||||||||||||||||||||||||||||||||||||||||||||
| data, | ||||||||||||||||||||||||||||||||||||||||||||||
| excluded_locations | ||||||||||||||||||||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||||||||||||||||||||
| normalized <- normalize_excluded_locations(excluded_locations) | ||||||||||||||||||||||||||||||||||||||||||||||
| all_valid_codes <- forecasttools::us_location_table$code | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| purrr::map_df(unique(data$target), \(tgt) { | ||||||||||||||||||||||||||||||||||||||||||||||
| if (!is.null(normalized)) { | ||||||||||||||||||||||||||||||||||||||||||||||
| excl_abbrs <- get_target_exclusions(normalized, tgt) | ||||||||||||||||||||||||||||||||||||||||||||||
| excl_codes <- forecasttools::us_location_recode( | ||||||||||||||||||||||||||||||||||||||||||||||
| excl_abbrs, | ||||||||||||||||||||||||||||||||||||||||||||||
| "abbr", | ||||||||||||||||||||||||||||||||||||||||||||||
| "hub" | ||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||
| included_codes <- setdiff(all_valid_codes, excl_codes) | ||||||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||||||
| included_codes <- all_valid_codes | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
| dplyr::filter(data, .data$target == tgt, .data$location %in% included_codes) | ||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+155
to
+176
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is a mismatch here between function name and argument. Name of the function makes it easy to misinterpret the argument. Then create expected_df and exclusion_df
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't love this, but I think it's clearer than the current approach and has same approach as apply_exclusion (https://github.com/CDCgov/hubhelpr/pull/178/files#r2990093161) |
||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not hub supported targets here? as before?