Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@

name: update-map-data
run-name: Update map data
name: build-map-data
run-name: Add ${{ inputs.year }} map data

on:
schedule:
# runs at noon UTC on the 1st of each month
- cron: '0 12 1 * *'
workflow_dispatch:
inputs:
year:
description: "Shape file year"
required: false
default: ''

jobs:
check:
build:
runs-on: ubuntu-latest
env:
PUSHOVER_API_KEY: ${{ secrets.PUSHOVER_API_KEY }}
Expand All @@ -31,7 +36,7 @@ jobs:
- name: Download shapefiles
id: dl-shp
run: |
python data-raw/scripts/shapefiles.py
python data-raw/scripts/shapefiles.py ${{ inputs.year }}

- name: Setup R
uses: r-lib/actions/setup-r@v2
Expand All @@ -43,18 +48,24 @@ jobs:

- name: Modify shapefiles
env:
STATE_SHP: data-raw/shapefiles/${{ env.state_shp }}
COUNTY_SHP: data-raw/shapefiles/${{ env.county_shp }}
STATE_SHP: ${{ env.state_shp }}
COUNTY_SHP: ${{ env.county_shp }}
YEAR: ${{ env.shp_year }}
run: |
input_dir <- file.path("data-raw", "shapefiles", Sys.getenv("YEAR"))
output_dir <- file.path("inst", "extdata", Sys.getenv("YEAR"))

usmapdata:::create_us_map(
"states",
Sys.getenv("STATE_SHP"),
"inst/extdata/us_states.gpkg"
file.path(input_dir, Sys.getenv("STATE_SHP")),
output_dir,
"us_states.gpkg"
)
usmapdata:::create_us_map(
"counties",
Sys.getenv("COUNTY_SHP"),
"inst/extdata/us_counties.gpkg"
file.path(input_dir, Sys.getenv("COUNTY_SHP")),
output_dir,
"us_counties.gpkg"
)
shell: Rscript {0}

Expand All @@ -68,9 +79,11 @@ jobs:

- name: Determine pull request parameters
id: pr-params
env:
YEAR: ${{ env.shp_year }}
run: |
echo "branch_name=data-update/$(date +'%B-%Y')" >> "$GITHUB_OUTPUT"
echo "pr_title=$(date +'%B %Y') map data update" >> "$GITHUB_OUTPUT"
echo "branch_name=data-update/$YEAR" >> "$GITHUB_OUTPUT"
echo "pr_title=Add $YEAR map data" >> "$GITHUB_OUTPUT"

- name: Render pull request body
id: pr-body
Expand Down Expand Up @@ -100,7 +113,13 @@ jobs:
run: |
python data-raw/scripts/pushover.py "✅ usmapdata has updated its data files, a PR review is needed: <a href=\"${{ steps.open-pr.outputs.pull-request-url }}\">PR #${{ steps.open-pr.outputs.pull-request-number }}</a>"

- name: Send data not found notification
if: ${{ failure() && steps.dl-shp.outputs.exit_code == '404' }}
run: |
python data-raw/scripts/pushover.py "⚠️ usmapdata failed to find map data files for ${{ env.shp_year }}." "LOW"

- name: Send failure notification
if: ${{ failure() }}
if: ${{ failure() && steps.dl-shp.outputs.exit_code != '404' }}
run: |
python data-raw/scripts/pushover.py "⚠️ usmapdata failed to update map data files. (error: ${{ steps.dl-shp.outputs.python_exit_code }})" "LOW"
python data-raw/scripts/pushover.py "❌ usmapdata failed to update map data files. (error: ${{ steps.dl-shp.outputs.exit_code }})" "LOW"

1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Generated by roxygen2: do not edit by hand

export(available_map_years)
export(centroid_labels)
export(fips_data)
export(us_map)
Expand Down
18 changes: 16 additions & 2 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
# usmapdata 0.3.0.9000
# [unreleased]

### New Features
* Add `data_year` parameter to `us_map()`, see [Issue #34](https://github.com/pdil/usmapdata/issues/34).
* Allows user to select the year for which to plot US map.
* This will allow the user to match the map that is provided to the data they are using.
* To start with, 2022 and 2023 maps are included.
* Going forward, each year will be added to the package and previous years can be accessed with this parameter.
* If the value provided via `data_year` is not available, the package will select the next year for which data exists.
* For example, if data sets 2022 and 2023 are available and the user calls `us_map(data_year = 2019)`, 2022 will be used.
* A warning is presented when this occurs to alert the user.
* Further reading on the impetus for this change: [major changes made to Connecticut counties in 2023](https://www.ctinsider.com/projects/2023/ct-planning-regions/).

### Improvements
* Improve python script and GitHub Actions workflow that download and process map shapefiles to be more flexible and support new `data_year` feature listed above.
* `centroid_labels()` now accepts `"state"` and `"county"` as inputs for the `regions` parameter like `us_map()` and `fips_data()`.
* Update package author email.

# usmapdata 0.3.0
Expand All @@ -14,7 +28,7 @@ Released Friday, March 8, 2024.
* Improve language in `DESCRIPTION` and minor documentation, see [Issue #19](https://github.com/pdil/usmapdata/issues/19).

### Bug Fixes
* `alaska_bbox()` and `hawaii_bbox()` now output correct `sf` type (`sfc polygon`).
* `alaska_bbox()` and `hawaii_bbox()` now output correct `sf` type (`sfc_POLYGON`).

# usmapdata 0.2.1
Released Sunday, February 4, 2024.
Expand Down
19 changes: 13 additions & 6 deletions R/create-us-map.R
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
create_us_map <- function(
type = c("states", "counties"),
input_file,
output_dir,
output_file
) {
# check for dplyr
Expand Down Expand Up @@ -100,24 +101,30 @@ create_us_map <- function(
us_ea <- dplyr::arrange(us_ea, .data$abbr, .data$county)
}

# prepare output directory
if (!dir.exists(output_dir)) {
dir.create(output_dir, recursive = TRUE)
}
output_path <- file.path(output_dir, output_file)

# export modified shape file
sf::st_write(us_ea, output_file, quiet = TRUE, append = FALSE)
sf::st_write(us_ea, output_path, quiet = TRUE, append = FALSE)

# compute centroids
centroids <- compute_centroids(us_ea)

# determine centroids file path
centroids_output_file <- file.path(
dirname(output_file),
centroids_output_path <- file.path(
output_dir,
paste0(
tools::file_path_sans_ext(basename(output_file)),
tools::file_path_sans_ext(basename(output_path)),
"_centroids.",
tools::file_ext(output_file)
tools::file_ext(output_path)
)
)

# export centroids
sf::st_write(centroids, centroids_output_file, quiet = TRUE, append = FALSE)
sf::st_write(centroids, centroids_output_path, quiet = TRUE, append = FALSE)
}

#' @rdname create_us_map
Expand Down
11 changes: 4 additions & 7 deletions R/fips-data.R
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
#' Retrieve state and county FIPS codes
#'
#' @param regions The region breakdown for the map, can be one of
#' (\code{"states"}, \code{"state"}, \code{"counties"}, \code{"county"}).
#' The default is \code{"states"}.
#' @param as_sf Defunct, this parameter no longer has any effect and will be removed in
#' the future.
#' @inheritParams us_map
#'
#' @return An data frame of FIPS codes of the desired \code{regions}.
#'
Expand All @@ -17,11 +13,12 @@
#' @export
fips_data <- function(
regions = c("states", "state", "counties", "county"),
as_sf = TRUE
as_sf = TRUE,
data_year = NULL
) {
regions <- match.arg(regions)

map_data <- usmapdata::us_map(regions)
map_data <- usmapdata::us_map(regions, data_year = data_year)
sf::st_geometry(map_data) <- NULL
map_data
}
94 changes: 77 additions & 17 deletions R/us-map.R
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@
#' not present in the included regions will be ignored.
#' @param as_sf Defunct, this parameter no longer has any effect and will be removed in
#' the future.
#' @param data_year The year for which to obtain map data.
#' If the value is \code{NULL}, the most recent year's data is used. If the
#' provided year is not found from the available map data sets, the next most
#' recent year's data is used. This can be used if an older data set is being
#' plotted on the US map so that the data matches the map more accurately.
#' Therefore, the provided value should match the year of the plotted data set.
#' The default is \code{NULL}, i.e. the most recent available year is used.
#'
#' @return An `sf` data frame of US map coordinates divided by the desired \code{regions}.
#'
Expand All @@ -27,22 +34,24 @@
#'
#' excl_west_coast <- us_map(exclude = c("CA", "OR", "WA"))
#'
#' ct_counties_as_of_2022 <- us_map(regions = "counties", include = "CT", data_year = 2022)
#'
#' @export
us_map <- function(
regions = c("states", "state", "counties", "county"),
include = c(),
exclude = c(),
as_sf = TRUE
as_sf = TRUE,
data_year = NULL
) {
regions <- match.arg(regions)

if (regions == "state") regions <- "states"
else if (regions == "county") regions <- "counties"

df <- sf::read_sf(
system.file("extdata", paste0("us_", regions, ".gpkg"),
package = "usmapdata")
)
map_year <- select_map_year(data_year)
file_name <- paste0("us_", regions, ".gpkg")
file_path <- system.file("extdata", map_year, file_name, package = "usmapdata")
df <- sf::read_sf(file_path)

if (length(include) > 0) {
df <- df[df$full %in% include |
Expand All @@ -63,24 +72,75 @@ us_map <- function(

#' Retrieve centroid labels
#'
#' @param regions The region breakdown for the map, can be one of
#' (\code{"states"}, \code{"counties"}, as specified by the internal file names.
#' The default is \code{"states"}.
#' @param as_sf Defunct, this parameter no longer has any effect and will be removed in
#' the future.
#' @inheritParams us_map
#'
#' @return An `sf` data frame of state or county centroid labels and positions
#' relative to the coordinates returned by the \code{us_map} function.
#'
#' @export
centroid_labels <- function(
regions = c("states", "counties"),
as_sf = TRUE
regions = c("states", "state", "counties", "county"),
as_sf = TRUE,
data_year = NULL
) {
regions <- match.arg(regions)
if (regions == "state") regions <- "states"
else if (regions == "county") regions <- "counties"

map_year <- select_map_year(data_year)
file_name <- paste0("us_", regions, "_centroids.gpkg")
file_path <- system.file("extdata", map_year, file_name, package = "usmapdata")

sf::read_sf(
system.file("extdata", paste0("us_", regions, "_centroids.gpkg"),
package = "usmapdata")
)
sf::read_sf(file_path)
}

#' Years for which US map data is available
#'
#' @return A numeric vector of available map data years,
#' sorted in descending order.
#'
#' @examples
#' available_map_years()
#'
#' @export
available_map_years <- function() {
sort(as.numeric(list.files(system.file("extdata", package = "usmapdata"))))
}

#' Select appropriate map data year from available years
#'
#' @param data_year The year for which to obtain \code{usmap} data.
#' If the value is \code{NULL}, the most recent year is returned. If the
#' provided year is not found from the available map data sets, the next most
#' recent available year is returned.
#'
#' @keywords internal
select_map_year <- function(data_year) {
years <- available_map_years()

if (is.null(data_year)) {
max(years)
} else if (!(data_year %in% years)) {
warn <- function(provided, used) {
warning(
paste0(provided, " map data not available, using ", used, " instead.\n\n",
"See available years with `usmapdata::available_map_years()`."),
call. = FALSE
)
}

years_greater <- years[years >= data_year]

if (length(years_greater) == 0) {
last_available <- max(years[years < data_year])
warn(data_year, last_available)
last_available
} else {
next_available <- min(years_greater)
warn(data_year, next_available)
next_available
}
} else {
data_year
}
}
Loading