To show all code please click “Show All Code” using the code button at the top right of the file.
knitr::opts_chunk$set(
comment = "",
tidy = TRUE,
tidy.opts = list(width.cutoff = 80),
width = 80
)
# Set encoding: UTF-8
options(encoding = "UTF-8")
try(Sys.setlocale("LC_CTYPE", "en_US.UTF-8"), silent = TRUE)
[1] “en_US.UTF-8”
# Ensure chunk output is UTF-8
knitr::knit_hooks$set(output = function(x, options) enc2utf8(x))
# Set working directory to a filepath on computer
setwd('/Users/akthiersch/Desktop/Professional Applications/Job Interview Prep/The Joint Commission/Senior Healthcare Data Analyst/Assessment/Final')
# getwd()
# # Install packages to load necessary libraries
# # If needed, comment out to imporve R knitting performance
# options(repos = c(CRAN = "https://cloud.r-project.org/"))
# # Install Packages
# install.packages("tidyverse")
# install.packages("lubridate")
# install.packages("curl")
# install.packages("expss")
# install.packages("gt")
# install.packages("gtsummary")
# install.packages("maps")
# install.packages("usmap")
# install.packages("viridis")
# install.packages("ggrepel")
# # install.packages("cowplot")
# install.packages("statebins)
# install.packages("rmarkdown)
# Install Libraries
library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr 1.1.4 ✔ readr 2.1.5
✔ forcats 1.0.0 ✔ stringr 1.5.1
✔ ggplot2 4.0.0 ✔ tibble 3.2.1
✔ lubridate 1.9.4 ✔ tidyr 1.3.1
✔ purrr 1.0.4
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag() masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(lubridate)
library(curl)
Using libcurl 8.14.1 with LibreSSL/3.3.6
Attaching package: 'curl'
The following object is masked from 'package:readr':
parse_date
library(expss)
Loading required package: maditr
To select columns from data: columns(mtcars, mpg, vs:carb)
Attaching package: 'maditr'
The following objects are masked from 'package:dplyr':
between, coalesce, first, last
The following object is masked from 'package:purrr':
transpose
The following object is masked from 'package:readr':
cols
Attaching package: 'expss'
The following objects are masked from 'package:stringr':
fixed, regex
The following objects are masked from 'package:dplyr':
compute, contains, na_if, recode, vars, where
The following objects are masked from 'package:purrr':
keep, modify, modify_if, when
The following objects are masked from 'package:tidyr':
contains, nest
The following object is masked from 'package:ggplot2':
vars
library(gt)
Attaching package: 'gt'
The following objects are masked from 'package:expss':
contains, gt, tab_caption, vars, where
library(gtsummary)
Attaching package: 'gtsummary'
The following objects are masked from 'package:expss':
contains, vars, where
library(maps)
Attaching package: 'maps'
The following object is masked from 'package:purrr':
map
library(usmap)
library(viridis)
Loading required package: viridisLite
Attaching package: 'viridis'
The following object is masked from 'package:maps':
unemp
library(ggrepel)
# library(cowplot)
library(grid)
library(gridExtra)
Attaching package: 'gridExtra'
The following object is masked from 'package:dplyr':
combine
library(statebins)
library(rmarkdown)
# ---- CMS Medicare Advantage (MA) Penetration Data Import Function ----
# ---- Function: download_with_retry ----
# Purpose: Allow multiple url download attempts
# Parameters:
# url: website address of file to download
# dest: destination file path
# tries: number of download tries
download_with_retry <- function(url, dest, tries = 5) {
# Create connection handle
h <- curl::new_handle()
# Configure handle set to HTTP version 1.1 (1L) and user agent string
curl::handle_setopt(h, http_version = 1L, useragent = "R curl/MA-pen-fetcher")
# Set loop tp run through number of tries
for (i in seq_len(tries)) {
# Download attempt
ok <- try({
curl::curl_download(
# File website url
url,
# File path destination
destfile = dest,
# Handle configuration
handle = h,
# Suppress messages
quiet = TRUE)
# TRUE if file successfully downloads
TRUE
}, silent = TRUE)
# Checks if download worked
if (isTRUE(ok)) return(invisible(dest))
# Download cool down time, wait before retrying
Sys.sleep(1.5 * i)
}
# Download fail error message
stop("Failed to download after ", tries, " attempts: ", url)
}
# ---- Function: cms_ma_penetration_import ----
# Purpose: Import CSM Medicare Advantage (MA) Penetration files give a date range
# Parameters:
# start_date = "YYYY-MM-DD"
# end_date = "YYYY-MM-DD"
cms_ma_penetration_import <- function(start_date, end_date) {
# Parse and normalize dates
.parse_ym <- function(x) {
# Force dates to be character datatype
x <- as.character(x)
# Keep only "YYYY-MM"
ym <- sub("^([0-9]{4}-[0-9]{2}).*$", "\\1", x)
# Convert date to "YYYY-MM-01"
ymd(paste0(ym, "-01"), quiet = TRUE)
}
# Set first month to download
start <- .parse_ym(start_date)
# Set last month to download
end <- .parse_ym(end_date)
# Error message if could not parse date formatting
if (any(is.na(c(start, end)))) stop("Could not parse dates; use 'YYYY-MM' or 'YYYY-MM-DD'.")
# Error message if start_data is large than end_date
if (start > end) stop("start_date must be <= end_date.")
# Generate monthly sequence based on first and last month
months_seq <- seq.Date(floor_date(start, "month"), floor_date(end, "month"), by = "month")
# Create temp directory for downloaded files
td <- tempdir()
# Create list to hold dataframe for each month
out <- vector("list", length(months_seq))
# Generate list of month abbreviations
abbr <- c("jan","feb","mar","apr","may","jun","jul","aug","sept","oct","nov","dec")
# Set loop to iterate through month sequence
for (i in seq_along(months_seq)) {
# Current month
d <- months_seq[i]
# Month number
m <- lubridate::month(d)
# Current year
y <- lubridate::year(d)
# Lowercase month name
m_full <- tolower(month.name[m])
# Month abbreviation
m_abbr <- abbr[m]
# Month number
mm <- sprintf("%02d", m)
# ---- List of possible CMS MA Penetration URL Formats ----
# More url formats could be added for older formats
urls <- c(
# 1. Numeric month name year format (september-2025 etc.)
sprintf("https://www.cms.gov/files/zip/ma-state/county-penetration-%s-%d.zip",
m_full, y),
# 2. Abbreviated month format (apr, aug, sept, etc.)
sprintf(paste0("https://www.cms.gov/research-statistics-data-and-systems/",
"statistics-trends-and-reports/mcradvpartdenroldata/downloads/",
"%d/%s/state-county-penetration-ma-%d-%s.zip"),
y, m_abbr, y, mm),
# 3. Numeric month year format (01–12 etc.)
sprintf(paste0("https://www.cms.gov/research-statistics-data-and-systems/",
"statistics-trends-and-reports/mcradvpartdenroldata/downloads/",
"%d/%02d/state-county-penetration-ma-%d-%s.zip"),
y, m, y, mm),
# 4. Full-month name format (august, december, etc.)
sprintf(paste0("https://www.cms.gov/research-statistics-data-and-systems/",
"statistics-trends-and-reports/mcradvpartdenroldata/downloads/",
"%d/%s/state-county-penetration-ma-%d-%s.zip"),
y, m_full, y, mm)
)
# Set filepath to save downloaded zipfile
zf <- file.path(td, sprintf("ma_%d_%02d.zip", y, m))
# Message to print when trying downloads
message("Trying downloads for ", format(d, "%B %Y"), "...")
# Set loop to try downloads for each url format
success <- FALSE
for (u in urls) {
message(" ", u)
ok <- tryCatch({
# download_with_retry function for multiple download attempts
download_with_retry(u, zf)
TRUE
}, error = function(e) FALSE)
# Check zipfile size > 5 KB
if (ok && file.exists(zf) && file.info(zf)$size > 5000) {
# Message print when file successfully downloaded
success <- TRUE
message(" Success: ", basename(zf))
break
}
}
# Message print if no file is downloaded
if (!success) {
message(" No valid file found for ", format(d, "%B %Y"))
next
}
# Extract and read data file data
# List file contents
listing <- try(utils::unzip(zf, list = TRUE), silent = TRUE)
if (inherits(listing, "try-error")) next
# Select file extension type
pick <- listing$Name[grepl("\\.(csv|xlsx?)$", tolower(listing$Name))][1]
if (is.na(pick)) next
# Extract data from zip file and send to tempdir
f <- utils::unzip(zf, files = pick, exdir = td, overwrite = TRUE)[1]
ext <- tools::file_ext(f)
# Read file into dataframe
df <- if (tolower(ext) == "csv") {
# Ensure propr encoding: UTF-8
readr::read_csv(f, locale = locale(encoding = "UTF-8"), show_col_types = FALSE)
# xlxs option
} else {
readxl::read_excel(f)
}
# Insert report year into dataframe
df$report_year <- y
# Insert report month into dataframe
df$report_month <- m
# Store output list
out[[i]] <- df
}
# Bind rows together
dplyr::bind_rows(Filter(Negate(is.null), out))
}
# Import CMS Medicare Advantage (MA) penetration data for Fiscal Year 2024 (FY24)
# If needed, comment out import function to improve R Markdown knitting performance
# Last Import: 10/30/2025
df.ma_penetration_FY24_RAW <- data.frame(cms_ma_penetration_import('2023-10-01', '2024-09-30'))
Trying downloads for October 2023...
https://www.cms.gov/files/zip/ma-state/county-penetration-october-2023.zip
Success: ma_2023_10.zip
Trying downloads for November 2023...
https://www.cms.gov/files/zip/ma-state/county-penetration-november-2023.zip
Success: ma_2023_11.zip
Trying downloads for December 2023...
https://www.cms.gov/files/zip/ma-state/county-penetration-december-2023.zip
Success: ma_2023_12.zip
Trying downloads for January 2024...
https://www.cms.gov/files/zip/ma-state/county-penetration-january-2024.zip
Success: ma_2024_01.zip
Trying downloads for February 2024...
https://www.cms.gov/files/zip/ma-state/county-penetration-february-2024.zip
Success: ma_2024_02.zip
Trying downloads for March 2024...
https://www.cms.gov/files/zip/ma-state/county-penetration-march-2024.zip
Success: ma_2024_03.zip
Trying downloads for April 2024...
https://www.cms.gov/files/zip/ma-state/county-penetration-april-2024.zip
Success: ma_2024_04.zip
Trying downloads for May 2024...
https://www.cms.gov/files/zip/ma-state/county-penetration-may-2024.zip
Success: ma_2024_05.zip
Trying downloads for June 2024...
https://www.cms.gov/files/zip/ma-state/county-penetration-june-2024.zip
Success: ma_2024_06.zip
Trying downloads for July 2024...
https://www.cms.gov/files/zip/ma-state/county-penetration-july-2024.zip
Success: ma_2024_07.zip
Trying downloads for August 2024...
https://www.cms.gov/files/zip/ma-state/county-penetration-august-2024.zip
Success: ma_2024_08.zip
Trying downloads for September 2024...
https://www.cms.gov/files/zip/ma-state/county-penetration-september-2024.zip
Success: ma_2024_09.zip
# Export dataframe
write_csv(df.ma_penetration_FY24_RAW, "df.ma_penetration_FY24_RAW.csv")
# Read in dataframe
# df.ma_penetration_FY24_RAW <- read_csv("df.ma_penetration_FY24_RAW.csv")
# View characteristics of dataframe
# glimpse(df.ma_penetration_FY24_RAW)
paged_table(df.ma_penetration_FY24_RAW)
# head(df.ma_penetration_FY24_RAW)
# Import CMS Medicare Advantage (MA) penetration data for Fiscal Year 2016 (FY16)
# If needed, comment out import function to improve R Markdown knitting performace
# Last Import: 10/30/2025
df.ma_penetration_FY16_RAW <- data.frame(cms_ma_penetration_import('2015-10-01', '2016-09-30'))
Trying downloads for October 2015...
https://www.cms.gov/files/zip/ma-state/county-penetration-october-2015.zip
https://www.cms.gov/research-statistics-data-and-systems/statistics-trends-and-reports/mcradvpartdenroldata/downloads/2015/oct/state-county-penetration-ma-2015-10.zip
Success: ma_2015_10.zip
Trying downloads for November 2015...
https://www.cms.gov/files/zip/ma-state/county-penetration-november-2015.zip
https://www.cms.gov/research-statistics-data-and-systems/statistics-trends-and-reports/mcradvpartdenroldata/downloads/2015/nov/state-county-penetration-ma-2015-11.zip
Success: ma_2015_11.zip
Trying downloads for December 2015...
https://www.cms.gov/files/zip/ma-state/county-penetration-december-2015.zip
https://www.cms.gov/research-statistics-data-and-systems/statistics-trends-and-reports/mcradvpartdenroldata/downloads/2015/dec/state-county-penetration-ma-2015-12.zip
Success: ma_2015_12.zip
Trying downloads for January 2016...
https://www.cms.gov/files/zip/ma-state/county-penetration-january-2016.zip
https://www.cms.gov/research-statistics-data-and-systems/statistics-trends-and-reports/mcradvpartdenroldata/downloads/2016/jan/state-county-penetration-ma-2016-01.zip
Success: ma_2016_01.zip
Trying downloads for February 2016...
https://www.cms.gov/files/zip/ma-state/county-penetration-february-2016.zip
https://www.cms.gov/research-statistics-data-and-systems/statistics-trends-and-reports/mcradvpartdenroldata/downloads/2016/feb/state-county-penetration-ma-2016-02.zip
Success: ma_2016_02.zip
Trying downloads for March 2016...
https://www.cms.gov/files/zip/ma-state/county-penetration-march-2016.zip
https://www.cms.gov/research-statistics-data-and-systems/statistics-trends-and-reports/mcradvpartdenroldata/downloads/2016/mar/state-county-penetration-ma-2016-03.zip
https://www.cms.gov/research-statistics-data-and-systems/statistics-trends-and-reports/mcradvpartdenroldata/downloads/2016/03/state-county-penetration-ma-2016-03.zip
https://www.cms.gov/research-statistics-data-and-systems/statistics-trends-and-reports/mcradvpartdenroldata/downloads/2016/march/state-county-penetration-ma-2016-03.zip
Success: ma_2016_03.zip
Trying downloads for April 2016...
https://www.cms.gov/files/zip/ma-state/county-penetration-april-2016.zip
https://www.cms.gov/research-statistics-data-and-systems/statistics-trends-and-reports/mcradvpartdenroldata/downloads/2016/apr/state-county-penetration-ma-2016-04.zip
Success: ma_2016_04.zip
Trying downloads for May 2016...
https://www.cms.gov/files/zip/ma-state/county-penetration-may-2016.zip
https://www.cms.gov/research-statistics-data-and-systems/statistics-trends-and-reports/mcradvpartdenroldata/downloads/2016/may/state-county-penetration-ma-2016-05.zip
Success: ma_2016_05.zip
Trying downloads for June 2016...
https://www.cms.gov/files/zip/ma-state/county-penetration-june-2016.zip
https://www.cms.gov/research-statistics-data-and-systems/statistics-trends-and-reports/mcradvpartdenroldata/downloads/2016/jun/state-county-penetration-ma-2016-06.zip
https://www.cms.gov/research-statistics-data-and-systems/statistics-trends-and-reports/mcradvpartdenroldata/downloads/2016/06/state-county-penetration-ma-2016-06.zip
https://www.cms.gov/research-statistics-data-and-systems/statistics-trends-and-reports/mcradvpartdenroldata/downloads/2016/june/state-county-penetration-ma-2016-06.zip
Success: ma_2016_06.zip
Trying downloads for July 2016...
https://www.cms.gov/files/zip/ma-state/county-penetration-july-2016.zip
https://www.cms.gov/research-statistics-data-and-systems/statistics-trends-and-reports/mcradvpartdenroldata/downloads/2016/jul/state-county-penetration-ma-2016-07.zip
https://www.cms.gov/research-statistics-data-and-systems/statistics-trends-and-reports/mcradvpartdenroldata/downloads/2016/07/state-county-penetration-ma-2016-07.zip
https://www.cms.gov/research-statistics-data-and-systems/statistics-trends-and-reports/mcradvpartdenroldata/downloads/2016/july/state-county-penetration-ma-2016-07.zip
Success: ma_2016_07.zip
Trying downloads for August 2016...
https://www.cms.gov/files/zip/ma-state/county-penetration-august-2016.zip
https://www.cms.gov/research-statistics-data-and-systems/statistics-trends-and-reports/mcradvpartdenroldata/downloads/2016/aug/state-county-penetration-ma-2016-08.zip
https://www.cms.gov/research-statistics-data-and-systems/statistics-trends-and-reports/mcradvpartdenroldata/downloads/2016/08/state-county-penetration-ma-2016-08.zip
https://www.cms.gov/research-statistics-data-and-systems/statistics-trends-and-reports/mcradvpartdenroldata/downloads/2016/august/state-county-penetration-ma-2016-08.zip
Success: ma_2016_08.zip
Trying downloads for September 2016...
https://www.cms.gov/files/zip/ma-state/county-penetration-september-2016.zip
https://www.cms.gov/research-statistics-data-and-systems/statistics-trends-and-reports/mcradvpartdenroldata/downloads/2016/sept/state-county-penetration-ma-2016-09.zip
Success: ma_2016_09.zip
# Export dataframe
write_csv(df.ma_penetration_FY16_RAW, "df.ma_penetration_FY16_RAW.csv")
# Read in dataframe
# df.ma_penetration_FY16_RAW <- read_csv("df.ma_penetration_FY16_RAW.csv")
# View dataframe
# glimpse(df.ma_penetration_FY16_RAW)
paged_table(df.ma_penetration_FY16_RAW)
# head(df.ma_penetration_FY16_RAW)
# Modify RAW data
df.ma_penetration_FY16_mod <- df.ma_penetration_FY16_RAW |>
# Remove % symbol and convert Penetration to numeric
mutate(
Penetration = as.numeric(gsub("[^0-9\\.]", "", Penetration))
) |>
# Create month abbreviations variable
mutate(
report_month_text = month.abb[report_month],
# Create factored month text variable
report_month_text = factor(report_month_text,
levels = month.abb, ordered = TRUE)
) |>
# Factor State and County names
mutate(across(c(State.Name, County.Name), as.factor)) |>
# Standardize District of Columbia name format for State.Name
mutate(State.Name = case_when(State.Name == "Washington D.C." ~ "District of Columbia",
State.Name == "District Of Columbia" ~ "District of Columbia",
TRUE ~ State.Name))
# TABLE 1: Mean penetration (%) by month per State (FY16)
# Subset for relevant variables
df.ma_penetration_FY16_tbl1 <- df.ma_penetration_FY16_mod |>
filter(!State.Name %in% c("Pending State Designation", "American Samoa", "Guam", "Northern Mariana Islands", "Puerto Rico", "Virgin Islands", "Wake Island")) |>
filter(!County.Name %in% c("Pending County Designation")) |>
subset(select = c(State.Name, Penetration, report_month_text))
# Calculate mean penetration (%) by per State by Month
tbl1_ma_penetration <- df.ma_penetration_FY16_tbl1 |>
group_by(State.Name, report_month_text) |>
summarize(
mean_pen = mean(Penetration, na.rm = TRUE),
.groups = "drop"
) |>
# Pivot data long to wide
select(State.Name, report_month_text, mean_pen) |>
pivot_wider(names_from = report_month_text, values_from = mean_pen)|>
arrange(State.Name)
# View characteristics of dataframe
# glimpse(tbl1_ma_penetration)
# Calculate total month means for all states
month_means <- df.ma_penetration_FY16_tbl1 |>
group_by(report_month_text) |>
summarize(
mean_pen = mean(Penetration, na.rm = TRUE),
.groups = "drop"
) |>
mutate(State.Name = "All States") |>
# Pivot data long to wind
pivot_wider(names_from = report_month_text, values_from = mean_pen)|>
arrange(State.Name)
# View characteristics of dataframe
# glimpse(month_means)
# Bind rows to create combined dataframe
tbl1_ma_penetration_all <- bind_rows(tbl1_ma_penetration, month_means)
# glimpse(tbl1_ma_penetration_all)
paged_table(tbl1_ma_penetration_all)
# If needed, mean calculations per state
# state_means <- df.ma_penetration_FY16_tbl1 |>
# group_by(State.Name) |>
# summarize(
# mean_pen = mean(Penetration, na.rm = TRUE),
# .groups = "drop"
# )
#
# glimpse(state_means)
# Construct gt table
gt_tbl1 <- gt::gt(tbl1_ma_penetration_all, rowname_col = "State.Name") |>
tab_stubhead(label = "State") |>
# Format table numbers
gt::fmt_number(
decimals = 1,
pattern = "{x}%"
) |>
# Format missing numbers
gt::sub_missing(columns = everything(), missing_text = "-") |>
# Set titles
gt::tab_header(title = gt::md("**Table 1. Mean MA Percent Penetration (%) per State by Month (FY16)**"),
subtitle = gt::md("October 1<sup>st</sup>, 2014 - September 30<sup>th</sup>, 2016")) |>
# Format column spanner title
gt::tab_spanner(
label = "Months",
columns = 2:13) |>
# Format rows
gt::cols_label(State.Name = gt::md("**State**")) |>
gt::tab_options(
table.font.size = "small",
data_row.padding = gt::px(3),
heading.align = "left"
) |>
# Format table body
gt::tab_options(
table.font.size = gt::px(11),
data_row.padding = gt::px(2),
table.font.color = "black",
table.border.top.color = "black",
table.border.top.width = gt::px(1),
table.border.bottom.color = "black",
table.border.bottom.width = gt::px(1),
column_labels.font.weight = "bold",
column_labels.border.bottom.color = "black",
column_labels.border.bottom.width = gt::px(1),
column_labels.border.top.color = "black",
column_labels.border.top.width = gt::px(1),
heading.align = "center",
heading.background.color = "white",
heading.title.font.weight = "bold",
table.align = "center"
) |>
# Format font
gt::opt_table_font(
font = list(
gt::system_fonts(name = "old-style"),
gt::default_fonts()
)
)|>
# Format lines - thin gray lines between rows (no shading)
gt::tab_style(
style = list(gt::cell_borders(sides = "bottom", color = "#bfbfbf", weight = gt::px(0.5))),
locations = gt::cells_body(rows = everything())) |>
# Format final row
gt::tab_style(
style = gt::cell_text(weight = "bold"),
locations = gt::cells_body(rows = State.Name == "All States")
) |>
gt::tab_style(
style = list(gt::cell_text(weight = "bold")),
locations = gt::cells_stub(rows = State.Name == "All States")) |>
# Format alignment
gt::cols_align(align = "left", columns = State.Name) |>
gt::cols_align(align = "center", columns = -State.Name) |>
# Format Notes and Source
gt::tab_source_note(
gt::md("**_Note:_** The calculations above do not contain data from American Samoa, Guam, Northern Mariana Islands, Puerto Rico, Virgin Islands, Wake Island, Pending State Designation, or Pending County Designation.<br>
**_Source:_** Centers for Medicare & Medicaid Services, *Medicare Advantage/Part D Contract and Enrollment Data: MA State/County Penetration*, https://www.cms.gov/data-research/statistics-trends-and-reports/medicare-advantagepart-d-contract-and-enrollment-data/ma-state/county-penetration (accessed October 26, 2025).")
)
gt_tbl1
| Table 1. Mean MA Percent Penetration (%) per State by Month (FY16) | ||||||||||||
| October 1st, 2014 - September 30th, 2016 | ||||||||||||
| State |
Months
|
|||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec | |
| Alabama | 20.0% | 20.4% | 20.2% | 20.3% | 20.2% | 20.3% | 20.4% | 20.3% | 20.3% | 19.4% | 19.4% | 19.5% |
| Alaska | 0.5% | 0.5% | 0.5% | 0.5% | 0.4% | 0.4% | 0.4% | 0.4% | 0.5% | 0.5% | 0.5% | 0.5% |
| Arizona | 26.7% | 26.9% | 26.8% | 26.9% | 26.8% | 26.7% | 26.8% | 26.7% | 26.7% | 26.6% | 26.6% | 26.5% |
| Arkansas | 19.2% | 19.3% | 19.1% | 19.1% | 19.1% | 19.1% | 19.1% | 19.1% | 19.1% | 18.6% | 18.6% | 18.6% |
| California | 21.6% | 21.8% | 21.9% | 22.0% | 21.9% | 21.9% | 21.7% | 21.6% | 21.5% | 20.8% | 20.8% | 20.8% |
| Colorado | 19.1% | 19.2% | 18.9% | 18.7% | 18.6% | 18.6% | 18.7% | 18.5% | 18.5% | 19.6% | 19.5% | 19.5% |
| Connecticut | 24.8% | 25.0% | 25.0% | 25.2% | 25.1% | 25.2% | 25.4% | 25.4% | 25.4% | 24.5% | 24.5% | 24.5% |
| Delaware | 8.6% | 9.1% | 9.0% | 9.0% | 8.9% | 8.9% | 8.9% | 8.9% | 8.9% | 7.6% | 7.6% | 7.6% |
| District of Columbia | 13.7% | 13.9% | 13.8% | 14.0% | 14.1% | 14.2% | 14.3% | 14.4% | 14.5% | 13.3% | 13.4% | 13.4% |
| Florida | 31.6% | 31.8% | 31.5% | 31.7% | 31.6% | 31.7% | 31.8% | 31.7% | 31.8% | 30.8% | 30.8% | 30.8% |
| Georgia | 31.6% | 31.9% | 31.5% | 31.7% | 31.6% | 31.6% | 31.8% | 31.7% | 31.8% | 30.5% | 30.5% | 30.5% |
| Hawaii | 42.8% | 43.0% | 42.9% | 43.2% | 42.9% | 42.9% | 43.0% | 42.8% | 42.8% | 43.6% | 43.5% | 43.5% |
| Idaho | 20.0% | 20.4% | 20.3% | 20.3% | 20.2% | 20.2% | 20.2% | 20.1% | 20.1% | 22.2% | 22.3% | 22.2% |
| Illinois | 18.7% | 19.3% | 19.1% | 19.2% | 19.1% | 19.0% | 19.0% | 19.0% | 18.9% | 18.3% | 18.3% | 18.2% |
| Indiana | 21.7% | 22.5% | 22.3% | 22.4% | 22.3% | 22.3% | 22.4% | 22.5% | 22.5% | 21.9% | 21.9% | 21.9% |
| Iowa | 10.6% | 12.3% | 12.1% | 12.1% | 12.0% | 12.0% | 12.1% | 12.0% | 12.0% | 10.5% | 10.5% | 10.3% |
| Kansas | 5.8% | 6.1% | 6.1% | 6.1% | 6.1% | 6.1% | 6.2% | 6.1% | 6.1% | 5.5% | 5.5% | 5.5% |
| Kentucky | 25.2% | 25.6% | 25.4% | 25.5% | 25.4% | 25.4% | 25.6% | 25.5% | 25.5% | 24.6% | 24.6% | 24.6% |
| Louisiana | 24.9% | 25.1% | 24.9% | 25.0% | 24.9% | 24.9% | 25.1% | 25.0% | 25.0% | 24.0% | 24.1% | 24.1% |
| Maine | 22.2% | 22.6% | 22.6% | 22.8% | 22.8% | 23.0% | 23.2% | 23.2% | 23.4% | 21.6% | 21.7% | 21.7% |
| Maryland | 6.0% | 6.4% | 6.4% | 6.4% | 6.4% | 6.4% | 6.5% | 6.5% | 6.5% | 5.2% | 5.2% | 5.2% |
| Massachusetts | 16.7% | 16.8% | 16.7% | 16.7% | 16.7% | 16.7% | 16.8% | 16.8% | 16.8% | 16.3% | 16.3% | 16.2% |
| Michigan | 30.4% | 30.8% | 30.5% | 30.6% | 30.5% | 30.7% | 30.9% | 30.8% | 30.9% | 30.1% | 30.1% | 30.0% |
| Minnesota | 52.8% | 53.3% | 52.7% | 52.9% | 52.8% | 52.8% | 53.2% | 53.0% | 53.1% | 51.6% | 51.7% | 51.7% |
| Mississippi | 12.8% | 12.9% | 12.8% | 12.9% | 12.9% | 13.0% | 13.0% | 13.0% | 13.0% | 12.2% | 12.2% | 12.2% |
| Missouri | 19.4% | 20.0% | 19.8% | 19.9% | 19.8% | 19.9% | 20.0% | 20.0% | 20.0% | 18.9% | 18.9% | 18.9% |
| Montana | 14.1% | 14.4% | 14.4% | 14.4% | 14.3% | 14.3% | 14.4% | 14.4% | 14.4% | 13.6% | 13.6% | 13.6% |
| Nebraska | 8.6% | 8.7% | 8.4% | 8.4% | 8.4% | 8.3% | 8.3% | 8.3% | 8.2% | 8.4% | 8.4% | 8.3% |
| Nevada | 15.1% | 14.4% | 14.4% | 14.4% | 14.4% | 14.3% | 15.2% | 15.1% | 15.2% | 14.5% | 13.5% | 14.5% |
| New Hampshire | 6.3% | 6.5% | 6.5% | 6.5% | 6.5% | 6.5% | 6.6% | 6.6% | 6.7% | 5.7% | 5.7% | 5.8% |
| New Jersey | 14.9% | 15.1% | 14.9% | 15.0% | 15.0% | 15.0% | 15.1% | 15.1% | 15.2% | 13.9% | 14.0% | 13.9% |
| New Mexico | 19.7% | 20.0% | 19.9% | 20.0% | 20.0% | 20.0% | 20.1% | 20.0% | 20.1% | 20.4% | 20.4% | 20.3% |
| New York | 35.6% | 36.1% | 35.9% | 36.1% | 36.0% | 36.1% | 36.2% | 36.1% | 36.2% | 35.4% | 35.5% | 35.4% |
| North Carolina | 25.7% | 26.1% | 26.0% | 26.1% | 26.0% | 26.0% | 26.1% | 26.0% | 26.0% | 25.4% | 25.4% | 25.4% |
| North Dakota | 16.6% | 17.2% | 17.4% | 17.6% | 17.6% | 17.6% | 17.9% | 17.8% | 18.1% | 16.7% | 16.7% | 16.8% |
| Ohio | 32.4% | 31.4% | 31.1% | 31.2% | 31.1% | 31.0% | 31.2% | 31.1% | 31.0% | 35.7% | 35.6% | 35.5% |
| Oklahoma | 9.8% | 9.9% | 9.7% | 9.7% | 9.6% | 9.7% | 9.6% | 9.7% | 9.5% | 9.3% | 9.3% | 9.3% |
| Oregon | 27.6% | 28.0% | 27.6% | 27.7% | 27.5% | 27.5% | 27.6% | 27.4% | 27.4% | 27.8% | 27.7% | 27.7% |
| Pennsylvania | 37.7% | 37.8% | 37.4% | 37.5% | 37.4% | 37.4% | 37.5% | 37.4% | 37.4% | 37.4% | 37.4% | 37.4% |
| Rhode Island | 34.3% | 34.4% | 34.2% | 34.3% | 34.2% | 34.1% | 34.3% | 34.2% | 34.3% | 33.8% | 33.8% | 33.8% |
| South Carolina | 24.9% | 25.0% | 24.8% | 25.5% | 25.3% | 25.3% | 26.5% | 26.0% | 25.9% | 24.2% | 24.2% | 24.2% |
| South Dakota | 19.3% | 17.7% | 17.3% | 17.7% | 17.8% | 17.9% | 18.1% | 18.1% | 18.2% | 15.6% | 18.6% | 18.5% |
| Tennessee | 31.9% | 32.4% | 32.1% | 32.2% | 32.1% | 32.1% | 32.3% | 32.3% | 32.3% | 31.0% | 31.0% | 31.0% |
| Texas | 23.0% | 23.3% | 23.0% | 23.1% | 23.0% | 23.0% | 23.1% | 23.1% | 23.1% | 22.2% | 22.2% | 22.2% |
| Utah | 19.0% | 19.3% | 19.1% | 19.2% | 19.2% | 19.2% | 19.2% | 19.2% | 19.1% | 19.4% | 19.4% | 19.4% |
| Vermont | 7.4% | 7.5% | 7.5% | 7.5% | 7.5% | 7.5% | 7.5% | 7.4% | 7.4% | 7.2% | 7.2% | 7.2% |
| Virginia | 18.0% | 45.0% | 17.9% | 17.9% | 17.8% | 17.8% | 17.9% | 17.8% | 17.8% | 17.8% | 17.7% | 17.7% |
| Washington | 17.0% | 17.2% | 17.1% | 17.2% | 17.1% | 17.1% | 17.2% | 17.1% | 17.1% | 18.4% | 18.4% | 18.4% |
| West Virginia | 27.2% | 27.3% | 26.9% | 27.0% | 26.8% | 26.7% | 26.8% | 26.7% | 26.7% | 26.2% | 26.1% | 26.1% |
| Wisconsin | 36.3% | 37.0% | 36.5% | 36.7% | 36.5% | 36.4% | 36.6% | 36.4% | 36.4% | 36.3% | 36.3% | 36.2% |
| Wyoming | 3.2% | 3.2% | 3.2% | 3.2% | 3.2% | 3.2% | 3.2% | 3.1% | 3.1% | 3.2% | 3.2% | 3.2% |
| All States | 22.9% | 24.4% | 23.0% | 23.1% | 23.0% | 23.0% | 23.1% | 23.1% | 23.1% | 22.5% | 22.6% | 22.6% |
| Note: The calculations above do not contain data from American Samoa, Guam, Northern Mariana Islands, Puerto Rico, Virgin Islands, Wake Island, Pending State Designation, or Pending County Designation. Source: Centers for Medicare & Medicaid Services, Medicare Advantage/Part D Contract and Enrollment Data: MA State/County Penetration, https://www.cms.gov/data-research/statistics-trends-and-reports/medicare-advantagepart-d-contract-and-enrollment-data/ma-state/county-penetration (accessed October 26, 2025). |
||||||||||||
# Export table
gt::gtsave(gt_tbl1, filename = "gt_tbl1.png")
file:////var/folders/kz/p2v973zn3tvby5f6_bzbrk9m0000gn/T//RtmpF7yEH3/file31471a284d4e.html screenshot completed
# TABLE 2: Summary Statistics
# Subset for relevant variables
df.ma_penetration_FY16_tbl2 <- df.ma_penetration_FY16_mod |>
# Remove non-states
filter(!State.Name %in% c("Pending State Designation", "American Samoa", "Guam", "Northern Mariana Islands", "Puerto Rico", "Virgin Islands", "Wake Island")) |>
# Remove non-counties
filter(!County.Name %in% c("Pending County Designation")) |>
subset(select = c(State.Name, Penetration, report_month_text))
# TABLE 2: Summary Statistics of Medicare Advantage Penetration by State
# Calculate summary statistics
tbl2_ma_penetration <- df.ma_penetration_FY16_tbl2 |>
group_by(State.Name) |>
summarize(
N = n(),
missing = sum(is.na(Penetration)),
mean_pen = mean(Penetration, na.rm = TRUE),
sd_pen = sd(Penetration, na.rm = TRUE),
min_pen = min(Penetration, na.rm = TRUE),
p25_pen = quantile(Penetration, 0.25, na.rm = TRUE),
p50_pen = quantile(Penetration, 0.50, na.rm = TRUE),
p75_pen = quantile(Penetration, 0.75, na.rm = TRUE),
max_pen = max(Penetration, na.rm = TRUE),
.groups = "drop"
) |>
# Remove -inf errors
mutate(across(where(is.numeric), ~ ifelse(!is.finite(.x), NA, .x)))
# Calculate summary statistics for all states
tbl2_allstates <- df.ma_penetration_FY16_mod %>%
summarize(
State.Name = "All States",
N = n(),
missing = sum(is.na(Penetration)),
mean_pen = mean(Penetration, na.rm = TRUE),
sd_pen = sd(Penetration, na.rm = TRUE),
min_pen = min(Penetration, na.rm = TRUE),
p25_pen = quantile(Penetration, 0.25, na.rm = TRUE),
p50_pen = quantile(Penetration, 0.50, na.rm = TRUE),
p75_pen = quantile(Penetration, 0.75, na.rm = TRUE),
max_pen = max(Penetration, na.rm = TRUE)
)
# Combine dataframes
tbl2_ma_penatration_allstates <- bind_rows(tbl2_ma_penetration, tbl2_allstates)
# View characteristic of dataframe
# glimpse(tbl2_ma_penatration_allstates)
paged_table(tbl2_ma_penatration_allstates)
# Construct gt table
gt_tbl2 <- gt::gt(tbl2_ma_penatration_allstates, rowname_col = "State.Name") |>
tab_stubhead(label = "State") |>
# Format numbers
gt::fmt_number(
columns = c(mean_pen, sd_pen, min_pen, p25_pen, p50_pen, p75_pen, max_pen),
decimals = 2,
use_seps = TRUE,
pattern = "{x}%"
) |>
# Format numbers
gt::fmt_number(
columns = c(N, missing),
decimals = 0,
use_seps = TRUE) |>
# Format missing numbers
gt::sub_missing(columns = everything(), missing_text = "-") |>
# Format titles
gt::tab_header(
title = gt::md("**Table 2. Summary Statistics of MA Percent Penetration (%) by State (FY16)**"),
subtitle = gt::md("October 1<sup>st</sup>, 2014 - September 30<sup>th</sup>, 2016")) |>
# Format column spanner label
gt::tab_spanner(
label = "Summary Statistics",
columns = 2:10) |>
# Format columns
gt::cols_label(
State.Name = gt::md("**State**"),
N = gt::md("**N**"),
missing = gt::md("**Missing**"),
mean_pen = gt::md("**Mean**"),
sd_pen = gt::md("**SD**"),
min_pen = gt::md("**Min**"),
p25_pen = gt::md("**P25**"),
p50_pen = gt::md("**P50**"),
p75_pen = gt::md("**P75**"),
max_pen = gt::md("**Max**")
) |>
# Format table body
gt::tab_options(
table.font.size = gt::px(11),
data_row.padding = gt::px(2),
table.font.color = "black",
table.border.top.color = "black",
table.border.top.width = gt::px(1),
table.border.bottom.color = "black",
table.border.bottom.width = gt::px(1),
column_labels.font.weight = "bold",
column_labels.border.bottom.color = "black",
column_labels.border.bottom.width = gt::px(1),
column_labels.border.top.color = "black",
column_labels.border.top.width = gt::px(1),
heading.align = "center",
heading.background.color = "white",
heading.title.font.weight = "bold",
table.align = "center"
) |>
# Format Font
gt::opt_table_font(
font = list(
gt::system_fonts(name = "old-style"),
gt::default_fonts()
)
) |>
# Format lines - thin gray lines between rows (no shading)
gt::tab_style(
style = list(gt::cell_borders(sides = "bottom", color = "#bfbfbf", weight = gt::px(0.5))),
locations = gt::cells_body(rows = everything())
) |>
# Format final row
gt::tab_style(
style = gt::cell_text(weight = "bold"),
locations = gt::cells_body(rows = State.Name == "All States")
) |>
gt::tab_style(
style = list(gt::cell_text(weight = "bold")),
locations = gt::cells_stub(rows = State.Name == "All States")) |>
# Format alignment
gt::cols_align(align = "left", columns = State.Name) |>
gt::cols_align(align = "center", columns = -State.Name) |>
# Caption below (economics style)
gt::tab_source_note(
gt::md("**_Note:_** The calculations above do not contain data from American Samoa, Guam, Northern Mariana Islands, Puerto Rico, Virgin Islands, Wake Island, Pending State Designation, or Pending County Designation.<br>
**_Source:_** Centers for Medicare & Medicaid Services, *Medicare Advantage/Part D Contract and Enrollment Data: MA State/County Penetration*, https://www.cms.gov/data-research/statistics-trends-and-reports/medicare-advantagepart-d-contract-and-enrollment-data/ma-state/county-penetration (accessed October 26, 2025).")
)
gt_tbl2
| Table 2. Summary Statistics of MA Percent Penetration (%) by State (FY16) | |||||||||
| October 1st, 2014 - September 30th, 2016 | |||||||||
| State |
Summary Statistics
|
||||||||
|---|---|---|---|---|---|---|---|---|---|
| N | Missing | Mean | SD | Min | P25 | P50 | P75 | Max | |
| Alabama | 804 | 0 | 20.06% | 10.54% | 6.49% | 12.35% | 16.02% | 25.08% | 47.42% |
| Alaska | 303 | 242 | 0.47% | 0.09% | 0.28% | 0.44% | 0.47% | 0.51% | 0.83% |
| Arizona | 180 | 0 | 26.72% | 12.98% | 5.90% | 15.74% | 27.75% | 36.92% | 51.02% |
| Arkansas | 900 | 0 | 19.00% | 5.95% | 8.83% | 13.94% | 18.84% | 22.55% | 38.42% |
| California | 696 | 4 | 21.51% | 18.10% | 0.82% | 5.11% | 12.88% | 40.75% | 58.14% |
| Colorado | 768 | 30 | 18.96% | 13.82% | 1.66% | 7.95% | 14.54% | 29.41% | 54.15% |
| Connecticut | 96 | 0 | 25.01% | 3.79% | 18.47% | 22.27% | 24.24% | 28.55% | 31.20% |
| Delaware | 36 | 0 | 8.59% | 2.09% | 5.41% | 6.26% | 9.36% | 10.07% | 11.30% |
| District of Columbia | 12 | 0 | 13.92% | 0.40% | 13.33% | 13.65% | 13.96% | 14.21% | 14.48% |
| Florida | 804 | 0 | 31.47% | 11.65% | 9.54% | 22.73% | 28.48% | 39.16% | 64.26% |
| Georgia | 1,908 | 0 | 31.39% | 5.28% | 15.89% | 27.98% | 31.26% | 34.95% | 45.04% |
| Hawaii | 59 | 11 | 43.08% | 5.51% | 35.48% | 38.46% | 43.84% | 48.34% | 49.19% |
| Idaho | 528 | 0 | 20.72% | 13.08% | 1.02% | 9.54% | 21.15% | 29.72% | 50.96% |
| Illinois | 1,224 | 0 | 18.84% | 8.25% | 6.38% | 12.40% | 17.11% | 22.75% | 45.65% |
| Indiana | 1,104 | 0 | 22.22% | 8.92% | 8.65% | 16.14% | 20.21% | 26.22% | 50.59% |
| Iowa | 1,188 | 6 | 11.53% | 7.68% | 0.30% | 6.12% | 10.34% | 15.33% | 53.50% |
| Kansas | 1,260 | 175 | 5.94% | 5.91% | 0.82% | 2.47% | 3.63% | 6.98% | 33.65% |
| Kentucky | 1,440 | 0 | 25.25% | 5.53% | 13.83% | 20.69% | 24.80% | 28.81% | 39.38% |
| Louisiana | 768 | 0 | 24.74% | 14.64% | 6.47% | 14.50% | 18.18% | 32.29% | 57.87% |
| Maine | 192 | 0 | 22.56% | 6.26% | 10.25% | 17.31% | 23.00% | 28.15% | 31.68% |
| Maryland | 288 | 0 | 6.08% | 3.66% | 0.71% | 3.48% | 4.62% | 8.16% | 15.17% |
| Massachusetts | 168 | 0 | 16.63% | 8.91% | 1.28% | 11.90% | 18.01% | 22.82% | 33.32% |
| Michigan | 996 | 0 | 30.52% | 6.53% | 18.01% | 26.26% | 28.95% | 33.14% | 58.73% |
| Minnesota | 1,044 | 0 | 52.64% | 7.55% | 31.48% | 48.16% | 53.62% | 58.05% | 69.88% |
| Mississippi | 984 | 0 | 12.74% | 5.80% | 2.54% | 8.63% | 12.07% | 17.00% | 30.66% |
| Missouri | 1,380 | 0 | 19.62% | 11.96% | 3.43% | 10.21% | 15.53% | 26.86% | 49.96% |
| Montana | 672 | 48 | 14.17% | 7.60% | 1.81% | 7.60% | 14.69% | 20.47% | 32.54% |
| Nebraska | 1,116 | 446 | 8.40% | 5.74% | 0.38% | 4.10% | 7.52% | 11.48% | 24.01% |
| Nevada | 204 | 30 | 14.57% | 14.01% | 0.66% | 1.83% | 10.16% | 20.92% | 48.57% |
| New Hampshire | 120 | 0 | 6.34% | 2.85% | 0.76% | 5.70% | 7.43% | 8.07% | 10.43% |
| New Jersey | 252 | 0 | 14.76% | 4.61% | 7.63% | 10.66% | 14.35% | 17.93% | 24.98% |
| New Mexico | 396 | 0 | 20.08% | 13.53% | 2.05% | 8.61% | 17.53% | 27.15% | 51.01% |
| New York | 744 | 0 | 35.88% | 12.54% | 11.34% | 25.58% | 36.18% | 44.01% | 64.58% |
| North Carolina | 1,200 | 0 | 25.84% | 12.01% | 9.29% | 16.43% | 24.24% | 31.38% | 61.23% |
| North Dakota | 636 | 93 | 17.34% | 8.79% | 0.57% | 12.09% | 16.79% | 22.49% | 40.72% |
| Ohio | 1,056 | 0 | 32.37% | 9.18% | 16.52% | 24.29% | 31.95% | 39.91% | 52.85% |
| Oklahoma | 924 | 14 | 9.57% | 6.84% | 1.66% | 5.17% | 7.53% | 10.59% | 31.04% |
| Oregon | 432 | 0 | 27.63% | 18.15% | 3.61% | 13.34% | 22.66% | 47.38% | 61.38% |
| Pennsylvania | 804 | 0 | 37.48% | 13.49% | 10.97% | 26.99% | 35.18% | 46.60% | 65.64% |
| Rhode Island | 60 | 0 | 34.14% | 5.55% | 24.58% | 30.32% | 37.05% | 38.87% | 39.57% |
| South Carolina | 552 | 0 | 25.16% | 5.96% | 12.98% | 20.34% | 24.98% | 29.93% | 40.39% |
| South Dakota | 785 | 36 | 17.90% | 13.03% | 1.04% | 11.55% | 16.66% | 21.62% | 185.71% |
| Tennessee | 1,140 | 0 | 31.89% | 10.66% | 10.03% | 22.41% | 29.84% | 41.11% | 57.86% |
| Texas | 3,048 | 31 | 22.85% | 8.19% | 4.49% | 17.05% | 21.57% | 26.89% | 54.37% |
| Utah | 348 | 15 | 19.21% | 14.47% | 0.77% | 3.31% | 21.77% | 33.54% | 44.68% |
| Vermont | 168 | 0 | 7.40% | 1.56% | 4.58% | 6.37% | 7.20% | 8.40% | 10.86% |
| Virginia | 1,608 | 0 | 20.10% | 89.61% | 6.20% | 12.95% | 16.16% | 21.32% | 3,600.00% |
| Washington | 468 | 12 | 17.46% | 14.06% | 0.81% | 4.10% | 14.96% | 27.11% | 54.91% |
| West Virginia | 660 | 0 | 26.71% | 5.60% | 13.89% | 22.27% | 27.16% | 31.01% | 40.97% |
| Wisconsin | 864 | 0 | 36.48% | 10.56% | 12.01% | 29.94% | 36.50% | 43.02% | 64.30% |
| Wyoming | 276 | 36 | 3.19% | 2.29% | 0.29% | 1.15% | 3.31% | 4.62% | 9.39% |
| All States | 38,659 | 1,634 | 23.76% | 23.78% | 0.17% | 13.01% | 21.55% | 31.48% | 3,600.00% |
| Note: The calculations above do not contain data from American Samoa, Guam, Northern Mariana Islands, Puerto Rico, Virgin Islands, Wake Island, Pending State Designation, or Pending County Designation. Source: Centers for Medicare & Medicaid Services, Medicare Advantage/Part D Contract and Enrollment Data: MA State/County Penetration, https://www.cms.gov/data-research/statistics-trends-and-reports/medicare-advantagepart-d-contract-and-enrollment-data/ma-state/county-penetration (accessed October 26, 2025). |
|||||||||
# Export table
gt::gtsave(gt_tbl2, filename = "gt_tbl2.png")
file:////var/folders/kz/p2v973zn3tvby5f6_bzbrk9m0000gn/T//RtmpF7yEH3/file31473cde1e21.html screenshot completed
# Import JCRC VA Facilities data
df.JCRC_VA_Facilities_RAW <- data.frame(read_csv("JCRC VA Facilities.csv"))
Rows: 50 Columns: 4
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr (1): StateAbbrev
dbl (3): ID, latitude, longitude
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
# Add period to StateAbbrev
df.JCRC_VA_Facilities_mod <- df.JCRC_VA_Facilities_RAW |>
rename(State.Abbrev = StateAbbrev)
# View characteristics of the dataset
# glimpse(df.JCRC_VA_Facilities_mod)
# paged_table(df.JCRC_VA_Facilities_mod)
# Add state abbreviations
tbl2_ma_penetration_stateabbrev <- tbl2_ma_penetration |>
mutate(State.Abbrev = state.abb[match(State.Name, state.name)]) |>
# Insert District of Columbia abbreviation
mutate(State.Abbrev = case_when(State.Name == "District of Columbia" ~ "DC",
TRUE ~ State.Abbrev)) |>
filter(!is.na(State.Abbrev))
# View characteristics of dataframe
# glimpse(tbl2_ma_penetration_stateabbrev)
# Merge State Percent Penetration with VA Facilities by State.Abbrec
df.merged_ma_pen_va_fac <- inner_join(tbl2_ma_penetration_stateabbrev, df.JCRC_VA_Facilities_mod, by = "State.Abbrev" )
state_fips <- df.ma_penetration_FY16_mod|>
distinct(State.Name, FIPSST)
# Join FIPS codes by State.Name
df.merged_ma_pen_va_fac_fips <- left_join(df.merged_ma_pen_va_fac, state_fips, by = "State.Name")
# View charateristics of dataframe
# glimpse(df.merged_ma_pen_va_fac_fips)
paged_table(df.merged_ma_pen_va_fac_fips)
# Construct coordinate scatterplot
plt1 <- ggplot(df.merged_ma_pen_va_fac_fips, aes(x = longitude, y = latitude)) +
# Set to scatterplot
geom_point(aes(color = mean_pen, size = mean_pen), alpha = 0.8) +
ggrepel::geom_text_repel(
aes(label = State.Abbrev),
size = 3, max.overlaps = 15, segment.color = "gray70"
) +
# Format color scale legend
scale_color_viridis_c(
option = "viridis",
name = "Mean MA Percent Penetration (%)"
) +
# Format size legend
scale_size_continuous(
name = "Mean MA Percent Penetration (%)",
range = c(2, 8),
guide = guide_legend(reverse = TRUE)
) +
# Set titles and axis labels
labs(
title = "Figure 1. State Mean MA Percent Penetration (%) per VA Facility Coordinates",
subtitle = "Each point labeled by state; color and size indicate % penetration.",
x = "Longitude",
y = "Latitude",
caption = paste0(
"Note: Data from Kansas (KS) and Iowa (IA) were omitted because they did not have VA facility coordinate data.\n",
"Source: CMS MA/Part D Penetration Data (Accessed Oct 26 2025)."
)
) +
# Format theme
theme_minimal(base_family = "Times") +
theme(
# Format titles, legend, and caption
legend.position = "right",
plot.title = element_text(face = "bold"),
plot.subtitle = element_text(margin = margin(b = 6)),
plot.caption = element_text(
hjust = 0,
size = 9,
color = "gray35",
lineheight = 1.1,
face = "italic"
)
)
plt1
# Export figure
ggsave(
filename = "plt1.jpeg",
plot = plt1,
width = 15, height = 10, dpi = 300
)
# Create state tile dataframe base on state abbreviation
df.tiles <- df.merged_ma_pen_va_fac_fips |>
distinct(State.Abbrev, mean_pen)
# Construct state grid plot
plt2 <- ggplot(df.tiles, aes(state = State.Abbrev, fill = mean_pen)) +
geom_statebins(border_col = "white") +
scale_fill_viridis_c(name = "Mean MA Percent Penetration (%)", option = "viridis") +
labs(
title = "Figure 2. Mean MA Percent Penetration (%) by State",
subtitle = "Each tile represents a state; color indicates mean MA percent penetration (%).",
caption = paste0(
"Note: Data from Kansas (KS) and Iowa (IA) were omitted because they did not have VA facility coordinate data.\n",
"Source: CMS MA/Part D Penetration Data (Accessed Oct 26 2025)."
)
) +
# Format bin theme
theme_statebins(base_size = 12) +
theme(
legend.position = "right",
plot.title = element_text(face = "bold", family = "Times"),
plot.subtitle = element_text(margin = margin(b = 6), family = "Times")
) +
# Format theme and captions
theme_minimal(base_family = "Times") +
theme(
# Remove grid lines and axis lines
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_blank(),
plot.background = element_blank(),
axis.line = element_blank(),
# Format titles,legend, caption
legend.position = "right",
plot.title = element_text(face = "bold"),
plot.subtitle = element_text(margin = margin(b = 6)),
plot.caption = element_text(
hjust = 0,
size = 9,
color = "gray35",
lineheight = 1.1,
face = "italic"
)
)
plt2
# Export figure
ggsave(
filename = "plt2.jpeg",
plot = plt2,
width = 15, height = 10, dpi = 300
)
To calculate the percent (%) penetration of Medicare Advantage (MA) by VA facility, the following data would be needed:
To calculate the percent penetration by VA facilities, I would:
Aggregate the MA enrollee counts and
Medicare-eligible counts for all counties within each VA facility’s
service area.
Compute the penetration rate as:
\[ \text{Percent Penetration} = \left( \frac{\text{MA Enrollees}}{\text{Medicare Eligibles}} \right) \times 100 \]
This represents the ratio of enrollees to eligibles expressed as a percentage.
Repeat this calculation for the service area of each VA facility.
This method follows the calculation outlined in the README files
from the CMS dataset:
Centers for Medicare & Medicaid Services (CMS), Medicare
Advantage/Part D Contract and Enrollment Data: MA State/County
Penetration.
https://www.cms.gov/data-research/statistics-trends-and-reports/medicare-advantagepart-d-contract-and-enrollment-data/ma-state/county-penetration
The resulting percentages represent an estimate
of MA penetration by VA facility, depending on the precision of the
service area definition.
Overlap between VA facilities may occur when nearby facilities share portions of the same counties or ZIP codes.
# The following files were formatted in Excel for proper import
# Import VA Patient Population Demographics files
df.va_vetpop_race_ethnicity_RAW <- readxl::read_xlsx("VetPop2023_Race_Ethnicity_State_NCVAS.xlsx")
# glimpse(df.va_vetpop_race_ethnicity_RAW)
df.va_vetpop_age_group_RAW <- readxl::read_xlsx("VetPop2023_State_AgeGroup_Sex_NCVAS.xlsx")
# View dataframe
# glimpse(df.va_vetpop_age_group_RAW)
# Calculate state-level demographic percentages for Sex, Race/Ethnicity, and Age Groups
# Factor levels: Sex
sex_levels <- c("Female", "Male")
# Sex Percentage Calculations per State
df.va_vetpop_sex <- df.va_vetpop_race_ethnicity_RAW |>
subset(select = -c(Race_Ethnicity)) |>
group_by(State, Sex) |>
summarize(state_sex_pop = sum(Veterans, na.rm = TRUE), .groups = "drop") |>
group_by(State) |>
mutate(
perc_state_sex = round((state_sex_pop / sum(state_sex_pop)) * 100, 2)
) |>
ungroup() |>
mutate(Sex = factor(Sex, levels = sex_levels, ordered = TRUE))
# Sex Percentage Calculations for All States
total_va_vetpop_sex <- df.va_vetpop_race_ethnicity_RAW |>
subset(select = -c(Race_Ethnicity)) |>
group_by(Sex) |>
summarize(state_sex_pop = sum(Veterans, na.rm = TRUE), .groups = "drop")|>
mutate(
perc_state_sex = round((state_sex_pop / sum(state_sex_pop)) * 100, 2)
) |>
ungroup() |>
mutate(Sex = factor(Sex, levels = sex_levels, ordered = TRUE)) |>
mutate(State = "All States")
# Combine dataframes
df.va_vetpop_sex_all <- bind_rows(df.va_vetpop_sex, total_va_vetpop_sex)
# View dataframe
# glimpse(df.va_vetpop_sex_all)
# Factor levels: Race/Ethnicity
race_levels <- c("White, alone", "Black or African American, alone", "American Indian and Alaska Native, alone", "Asian, alone", "Native Hawaiian and Other Pacific Islander, alone", "Some othe race, alone", "Two or more races", "Hispanic or Latino (of any race)", "White alone, Not Hispanic or Latino")
# Race/Ethnicity Percentage Calculations per State
df.va_vetpop_race_ethnic <- df.va_vetpop_race_ethnicity_RAW |>
subset(select = -c(Sex)) |>
group_by(State, Race_Ethnicity) |>
summarize(state_race_ethnic_pop = sum(Veterans, na.rm = TRUE), .groups = "drop") |>
group_by(State) |>
mutate(
perc_state_race_ethnic = round((state_race_ethnic_pop / sum(state_race_ethnic_pop)) * 100, 2)
) |>
ungroup() |>
mutate(Race_Ethnicity = factor(Race_Ethnicity, levels = race_levels, ordered = TRUE))
# Race/Ethnicity Percentage Calculations for All States
total_va_vetpop_race_ethnicity <- df.va_vetpop_race_ethnicity_RAW |>
subset(select = -c(Sex)) |>
group_by(Race_Ethnicity) |>
summarize(state_race_ethnic_pop = sum(Veterans, na.rm = TRUE), .groups = "drop")|>
mutate(
perc_state_race_ethnic = round((state_race_ethnic_pop / sum(state_race_ethnic_pop)) * 100, 2)
) |>
ungroup() |>
mutate(Race_Ethnicity = factor(Race_Ethnicity, levels = race_levels, ordered = TRUE)) |>
mutate(State = "All States")
# Combine dataframes
df.va_vetpop_race_ethnic_all <- bind_rows(df.va_vetpop_race_ethnic, total_va_vetpop_race_ethnicity)
# View dataframe
# glimpse(df.va_vetpop_race_ethnic_all)
# Factor level: Age groups
age_levels <- c("< 20", "20-24", "25-29", "30-34", "35-39", "40-44", "45-49", "50-54", "55-59", "60-64", "65-69", "70-74", "75-79", "80-84", "85+")
# Age Group Percentage Calculations per State
df.va_vetpop_age_group <- df.va_vetpop_age_group_RAW |>
subset(select = -c(Sex)) |>
group_by(State, Age_Group) |>
summarize(state_age_group_pop = sum(Veterans, na.rm = TRUE), .groups = "drop") |>
group_by(State) |>
mutate(
perc_state_age_group = round((state_age_group_pop / sum(state_age_group_pop)) * 100, 2)
) |>
ungroup() |>
mutate(Age_Group = factor(Age_Group, levels = age_levels, ordered = TRUE))
# Age Group Percentage Calculations for All States
total_va_vetpop_age_group <- df.va_vetpop_age_group_RAW |>
subset(select = -c(Sex)) |>
group_by(Age_Group) |>
summarize(state_age_group_pop = sum(Veterans, na.rm = TRUE), .groups = "drop")|>
mutate(
perc_state_age_group = round((state_age_group_pop / sum(state_age_group_pop)) * 100, 2)
) |>
ungroup() |>
mutate(Age_Group = factor(Age_Group, levels = age_levels, ordered = TRUE)) |>
mutate(State = "All States")
# Combine dataframes
df.va_vetpop_age_group_all <- bind_rows(df.va_vetpop_age_group, total_va_vetpop_age_group)
# View dataframe
# glimpse(df.va_vetpop_age_group_all)
# paged_table(df.va_vetpop_age_group_all)
# Convert data frames from long to wide
# Sex
sex_wide <- df.va_vetpop_sex_all |>
select(State, category = Sex, pct = perc_state_sex) |>
pivot_wider(names_from = category, values_from = pct, names_prefix = "Sex: ")
# Race/Ethnicity
race_wide <- df.va_vetpop_race_ethnic_all |>
select(State, category = Race_Ethnicity, pct = perc_state_race_ethnic) |>
pivot_wider(names_from = category, values_from = pct, names_prefix = "Race: ")
# Age Groups
age_wide <- df.va_vetpop_age_group_all |>
select(State, category = Age_Group, pct = perc_state_age_group) |>
pivot_wider(names_from = category, values_from = pct, names_prefix = "Age: ")
# Combine all dataframes by State
df.state_perc_demographics <- sex_wide |>
full_join(race_wide, by = "State") |>
full_join(age_wide, by = "State") |>
arrange(State) |>
select(State, all_of(paste0("Sex: ", sex_levels)), all_of(paste0("Race: ", race_levels)), all_of(paste0("Age: ", age_levels)))
# Format row and column order
tbl3_state_perc_demographics <- df.state_perc_demographics |>
filter(!State %in% c("Island Areas & Foreign", "Puerto Rico")) |>
rename_with(~ gsub("^(Sex: |Race: |Age: )", "", .x), -State) |>
arrange(State == "All States")
# glimpse(tbl3_state_perc_demographics)
paged_table(tbl3_state_perc_demographics)
# Construct gt table
gt_tbl3 <- gt::gt(tbl3_state_perc_demographics, rowname_col = "State") |>
tab_stubhead(label = "State") |>
# Format title
tab_header(
title = md("**Table 3. State-Level Veteran Population Demographic Percentages (2023)**"),
subtitle = md("Percent distribution of veterans by sex, race/ethnicity, and age group")
) |>
# Format column spanned titles
tab_spanner(
label = "Sex",
columns = 2:3
) |>
tab_spanner(
label = "Race / Ethnicity",
columns = 4:12
) |>
tab_spanner(
label = "Age Group (years)",
columns = 13:27
) |>
# Format numbers
fmt_number(columns = where(is.numeric),
decimals = 2,
pattern = "{x}%") |>
# Format table body
gt::tab_options(
table.font.size = gt::px(11),
data_row.padding = gt::px(2),
table.font.color = "black",
table.border.top.color = "black",
table.border.top.width = gt::px(1),
table.border.bottom.color = "black",
table.border.bottom.width = gt::px(1),
column_labels.font.weight = "bold",
column_labels.border.bottom.color = "black",
column_labels.border.bottom.width = gt::px(1),
column_labels.border.top.color = "black",
column_labels.border.top.width = gt::px(1),
heading.align = "center",
heading.background.color = "white",
heading.title.font.weight = "bold",
table.align = "center"
) |>
gt::opt_table_font(
font = list(
gt::system_fonts(name = "old-style"),
gt::default_fonts()
)
) |>
# Thin gray lines between rows (no shading)
gt::tab_style(
style = list(gt::cell_borders(sides = "bottom", color = "#bfbfbf", weight = gt::px(0.5))),
locations = gt::cells_body(rows = everything())) |>
# Format last row
gt::tab_style(
style = gt::cell_text(weight = "bold"),
locations = gt::cells_body(rows = State == "All States")
) |>
gt::tab_style(
style = list(gt::cell_text(weight = "bold")),
locations = gt::cells_stub(rows = State == "All States")) |>
# Format alignment
gt::cols_align(align = "left", columns = State) |>
gt::cols_align(align = "center", columns = -State) |>
# Format note and source caption
gt::tab_source_note(
gt::md("**_Note:_** The calculations above do not contain data from Island Areas & Foreign or Puerto Rico. All data is from September 30<sup>th</sup>, 2023 VA state-level population tables<br>
**_Source:_** U.S. Department of Veterans Affairs, *National Center for Veterans Analysis & Statistics.* Veteran Population - Population Tables: The States. Last updated March 26 2025. https://www.va.gov/vetdata/veteran_population.asp (accessed October 26, 2025).")
)
gt_tbl3
| Table 3. State-Level Veteran Population Demographic Percentages (2023) | ||||||||||||||||||||||||||
| Percent distribution of veterans by sex, race/ethnicity, and age group | ||||||||||||||||||||||||||
| State |
Sex
|
Race / Ethnicity
|
Age Group (years)
|
|||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Female | Male | White, alone | Black or African American, alone | American Indian and Alaska Native, alone | Asian, alone | Native Hawaiian and Other Pacific Islander, alone | Some othe race, alone | Two or more races | Hispanic or Latino (of any race) | White alone, Not Hispanic or Latino | < 20 | 20-24 | 25-29 | 30-34 | 35-39 | 40-44 | 45-49 | 50-54 | 55-59 | 60-64 | 65-69 | 70-74 | 75-79 | 80-84 | 85+ | |
| Alabama | 11.40% | 88.60% | 40.96% | 14.40% | 0.19% | 0.31% | 0.02% | 0.51% | 1.77% | 1.48% | 40.36% | 0.02% | 0.90% | 3.09% | 4.72% | 5.60% | 6.32% | 6.34% | 8.77% | 9.91% | 11.19% | 10.52% | 9.90% | 11.67% | 5.87% | 5.17% |
| Alaska | 14.97% | 85.03% | 43.33% | 2.37% | 3.52% | 1.41% | 0.61% | 0.82% | 3.57% | 2.92% | 41.46% | 0.01% | 1.72% | 4.82% | 6.84% | 8.03% | 8.74% | 7.49% | 8.39% | 9.23% | 10.69% | 9.51% | 8.23% | 9.15% | 4.37% | 2.77% |
| Arizona | 10.88% | 89.12% | 42.80% | 2.79% | 1.19% | 0.54% | 0.08% | 1.78% | 3.76% | 7.72% | 39.34% | 0.03% | 0.93% | 3.27% | 4.66% | 5.32% | 5.83% | 5.39% | 6.78% | 7.98% | 9.26% | 9.26% | 10.38% | 15.17% | 8.45% | 7.28% |
| Arkansas | 10.61% | 89.39% | 44.33% | 6.53% | 0.35% | 0.23% | 0.14% | 0.60% | 2.54% | 1.47% | 43.81% | 0.02% | 0.73% | 3.06% | 4.74% | 5.54% | 6.16% | 5.86% | 8.22% | 9.22% | 10.35% | 9.95% | 11.24% | 11.97% | 6.24% | 6.71% |
| California | 9.83% | 90.17% | 37.00% | 5.55% | 0.57% | 4.31% | 0.26% | 3.46% | 5.09% | 10.99% | 32.77% | 0.04% | 1.22% | 3.81% | 5.28% | 6.14% | 6.80% | 6.16% | 6.88% | 7.95% | 9.15% | 9.14% | 9.26% | 12.19% | 7.33% | 8.66% |
| Colorado | 12.48% | 87.52% | 42.99% | 3.35% | 0.51% | 0.85% | 0.13% | 1.65% | 3.74% | 6.72% | 40.06% | 0.05% | 1.47% | 4.42% | 6.39% | 7.12% | 7.07% | 6.44% | 8.05% | 8.89% | 9.44% | 8.96% | 9.17% | 11.15% | 5.34% | 6.06% |
| Connecticut | 8.33% | 91.67% | 44.83% | 4.07% | 0.17% | 0.50% | 0.01% | 1.31% | 2.06% | 3.88% | 43.17% | 0.01% | 0.86% | 2.83% | 4.28% | 5.04% | 5.72% | 5.42% | 6.55% | 8.18% | 10.32% | 9.29% | 8.10% | 14.24% | 8.81% | 10.35% |
| Delaware | 11.73% | 88.27% | 41.39% | 12.58% | 0.13% | 0.46% | 0.02% | 0.86% | 1.77% | 2.71% | 40.09% | 0.01% | 0.69% | 2.44% | 3.69% | 4.22% | 5.20% | 4.95% | 6.47% | 9.07% | 11.93% | 10.44% | 12.05% | 14.25% | 7.82% | 6.76% |
| District of Columbia | 14.72% | 85.28% | 28.02% | 34.39% | 0.32% | 1.49% | 0.01% | 1.20% | 3.51% | 4.99% | 26.07% | 0.01% | 0.43% | 2.72% | 5.67% | 7.28% | 8.70% | 7.13% | 7.81% | 9.13% | 11.71% | 11.04% | 8.08% | 7.07% | 5.80% | 7.43% |
| Florida | 11.14% | 88.86% | 42.39% | 6.67% | 0.19% | 0.59% | 0.04% | 1.18% | 3.33% | 5.80% | 39.82% | 0.02% | 0.78% | 2.68% | 4.01% | 4.84% | 5.71% | 5.67% | 7.17% | 8.68% | 10.63% | 9.77% | 9.64% | 13.59% | 8.19% | 8.63% |
| Georgia | 13.45% | 86.55% | 36.69% | 20.95% | 0.13% | 0.66% | 0.06% | 0.90% | 2.21% | 2.63% | 35.77% | 0.03% | 1.21% | 3.88% | 5.55% | 6.07% | 6.62% | 6.58% | 8.79% | 10.16% | 11.14% | 9.75% | 8.89% | 10.48% | 5.76% | 5.07% |
| Hawaii | 13.58% | 86.42% | 26.23% | 3.87% | 0.21% | 19.96% | 5.32% | 1.81% | 12.19% | 6.16% | 24.26% | 0.02% | 1.44% | 4.70% | 6.00% | 7.14% | 8.51% | 6.95% | 7.26% | 8.50% | 9.37% | 8.27% | 7.98% | 10.39% | 5.61% | 7.85% |
| Idaho | 9.77% | 90.23% | 46.75% | 0.38% | 0.45% | 0.32% | 0.07% | 1.09% | 2.42% | 2.78% | 45.74% | 0.02% | 0.91% | 3.12% | 5.09% | 5.90% | 6.45% | 5.87% | 7.34% | 8.75% | 9.40% | 9.12% | 10.11% | 13.38% | 7.35% | 7.19% |
| Illinois | 11.31% | 88.69% | 42.21% | 7.77% | 0.22% | 0.98% | 0.03% | 1.22% | 2.65% | 4.60% | 40.32% | 0.08% | 3.87% | 8.47% | 7.58% | 5.56% | 6.10% | 5.29% | 6.79% | 7.93% | 8.21% | 7.25% | 8.20% | 11.53% | 6.06% | 7.11% |
| Indiana | 9.40% | 90.60% | 46.09% | 4.09% | 0.15% | 0.26% | 0.03% | 0.58% | 1.70% | 1.62% | 45.49% | 0.03% | 0.83% | 3.08% | 4.78% | 5.51% | 5.49% | 5.14% | 7.91% | 9.99% | 11.12% | 9.79% | 10.56% | 13.20% | 6.52% | 6.05% |
| Iowa | 9.10% | 90.90% | 48.00% | 1.15% | 0.20% | 0.17% | 0.06% | 0.33% | 1.39% | 1.29% | 47.41% | 0.02% | 0.89% | 2.99% | 4.39% | 5.32% | 5.53% | 5.28% | 7.18% | 9.32% | 9.81% | 8.58% | 12.15% | 13.25% | 7.70% | 7.59% |
| Kansas | 10.75% | 89.25% | 45.20% | 3.71% | 0.37% | 0.44% | 0.14% | 0.65% | 2.79% | 2.96% | 43.73% | 0.02% | 1.43% | 3.99% | 5.31% | 6.33% | 6.74% | 6.36% | 7.75% | 8.60% | 9.24% | 8.79% | 10.12% | 11.66% | 7.10% | 6.57% |
| Kentucky | 9.76% | 90.24% | 46.09% | 4.97% | 0.14% | 0.29% | 0.07% | 0.28% | 1.47% | 1.02% | 45.68% | 0.02% | 1.06% | 3.40% | 4.51% | 5.60% | 6.18% | 6.27% | 8.55% | 10.19% | 10.98% | 9.81% | 10.27% | 11.49% | 5.99% | 5.68% |
| Louisiana | 11.27% | 88.73% | 39.64% | 16.33% | 0.24% | 0.39% | 0.02% | 0.57% | 2.10% | 1.76% | 38.95% | 0.02% | 1.12% | 3.37% | 4.60% | 5.69% | 7.57% | 7.30% | 9.49% | 9.53% | 8.82% | 9.04% | 9.92% | 11.71% | 6.43% | 5.39% |
| Maine | 9.11% | 90.89% | 48.40% | 0.48% | 0.19% | 0.10% | 0.01% | 0.20% | 1.79% | 0.75% | 48.08% | 0.02% | 0.56% | 2.12% | 3.69% | 4.65% | 4.80% | 5.23% | 7.01% | 8.93% | 11.55% | 10.59% | 10.47% | 15.06% | 7.90% | 7.42% |
| Maryland | 14.55% | 85.45% | 36.76% | 19.15% | 0.15% | 1.36% | 0.05% | 1.06% | 2.70% | 3.16% | 35.62% | 0.02% | 0.82% | 2.67% | 4.44% | 5.63% | 7.12% | 6.98% | 8.41% | 10.05% | 11.57% | 9.57% | 9.34% | 10.45% | 6.20% | 6.72% |
| Massachusetts | 8.16% | 91.84% | 46.14% | 2.37% | 0.18% | 0.61% | 0.01% | 0.95% | 1.95% | 2.58% | 45.21% | 0.01% | 0.58% | 2.60% | 4.26% | 4.91% | 4.96% | 4.88% | 6.62% | 8.58% | 10.83% | 9.64% | 9.63% | 14.45% | 7.68% | 10.36% |
| Michigan | 8.46% | 91.54% | 45.47% | 5.58% | 0.25% | 0.33% | 0.01% | 0.49% | 1.61% | 1.41% | 44.85% | 0.02% | 0.59% | 2.29% | 3.76% | 4.64% | 4.67% | 4.67% | 7.41% | 9.57% | 10.65% | 9.58% | 11.21% | 15.10% | 7.81% | 8.03% |
| Minnesota | 8.64% | 91.36% | 47.57% | 1.23% | 0.41% | 0.62% | 0.02% | 0.39% | 1.64% | 1.12% | 47.00% | 0.01% | 0.77% | 2.89% | 4.17% | 5.12% | 5.16% | 4.54% | 6.41% | 8.64% | 9.64% | 9.17% | 11.18% | 15.96% | 7.75% | 8.59% |
| Mississippi | 12.50% | 87.50% | 39.91% | 16.73% | 0.26% | 0.44% | 0.07% | 0.39% | 1.63% | 1.10% | 39.45% | 0.02% | 1.04% | 3.52% | 5.22% | 6.02% | 7.10% | 6.91% | 8.81% | 9.74% | 10.99% | 9.84% | 9.74% | 10.24% | 5.28% | 5.52% |
| Missouri | 9.73% | 90.27% | 45.58% | 5.12% | 0.24% | 0.32% | 0.08% | 0.42% | 1.97% | 1.30% | 44.96% | 0.02% | 0.87% | 3.61% | 4.76% | 5.62% | 6.10% | 5.64% | 7.58% | 8.94% | 10.49% | 9.78% | 10.40% | 12.72% | 6.54% | 6.95% |
| Montana | 11.05% | 88.95% | 46.67% | 0.40% | 1.88% | 0.13% | 0.01% | 0.73% | 2.50% | 1.84% | 45.84% | 0.02% | 0.88% | 3.04% | 4.73% | 6.11% | 6.65% | 5.98% | 7.49% | 8.64% | 9.22% | 8.98% | 11.97% | 11.35% | 7.38% | 7.58% |
| Nebraska | 11.04% | 88.96% | 46.49% | 2.04% | 0.31% | 0.58% | 0.00% | 0.50% | 2.21% | 2.30% | 45.57% | 0.02% | 0.86% | 2.94% | 4.84% | 6.04% | 6.61% | 6.10% | 8.08% | 9.55% | 10.15% | 8.49% | 9.47% | 13.51% | 5.74% | 7.60% |
| Nevada | 10.67% | 89.33% | 40.44% | 5.89% | 0.67% | 2.75% | 0.34% | 1.72% | 4.17% | 5.81% | 38.20% | 0.03% | 0.87% | 3.45% | 5.01% | 5.78% | 6.37% | 5.73% | 6.98% | 8.67% | 10.03% | 9.77% | 10.01% | 14.04% | 7.44% | 5.82% |
| New Hampshire | 9.39% | 90.61% | 48.31% | 0.32% | 0.13% | 0.18% | 0.04% | 0.42% | 1.45% | 1.41% | 47.74% | 0.01% | 0.66% | 2.76% | 4.36% | 5.15% | 5.01% | 4.96% | 6.91% | 8.89% | 11.58% | 10.91% | 10.23% | 13.48% | 7.77% | 7.32% |
| New Jersey | 8.13% | 91.87% | 40.92% | 7.94% | 0.16% | 1.49% | 0.07% | 1.74% | 3.06% | 6.02% | 38.59% | 0.03% | 1.04% | 3.09% | 4.36% | 5.12% | 5.52% | 5.05% | 6.29% | 7.80% | 9.41% | 8.43% | 8.51% | 16.22% | 7.98% | 11.14% |
| New Mexico | 12.50% | 87.50% | 37.63% | 2.04% | 3.05% | 0.36% | 0.06% | 3.57% | 6.78% | 16.79% | 29.73% | 0.02% | 0.88% | 2.92% | 4.41% | 5.32% | 6.58% | 6.18% | 7.67% | 8.75% | 10.79% | 10.20% | 10.70% | 11.98% | 7.33% | 6.29% |
| New York | 8.52% | 91.48% | 41.90% | 6.67% | 0.28% | 1.07% | 0.02% | 1.77% | 2.80% | 5.24% | 40.25% | 0.03% | 0.88% | 2.74% | 4.17% | 5.07% | 5.58% | 5.23% | 6.53% | 8.99% | 10.65% | 9.47% | 8.87% | 14.37% | 7.32% | 10.10% |
| North Carolina | 12.46% | 87.54% | 40.99% | 12.81% | 0.49% | 0.43% | 0.10% | 0.80% | 1.96% | 2.35% | 40.08% | 0.02% | 1.27% | 4.28% | 5.53% | 6.10% | 6.46% | 6.37% | 8.13% | 9.11% | 10.08% | 9.42% | 9.80% | 11.88% | 6.04% | 5.53% |
| North Dakota | 11.00% | 89.00% | 47.32% | 1.03% | 1.60% | 0.24% | 0.03% | 0.24% | 1.56% | 1.16% | 46.82% | 0.01% | 1.13% | 3.96% | 6.17% | 7.35% | 8.03% | 6.67% | 8.15% | 9.83% | 9.83% | 8.79% | 8.93% | 10.23% | 5.18% | 5.73% |
| Ohio | 9.00% | 91.00% | 45.53% | 5.81% | 0.09% | 0.25% | 0.03% | 0.48% | 1.59% | 1.23% | 44.99% | 0.02% | 0.80% | 2.88% | 4.17% | 5.07% | 5.35% | 5.22% | 7.73% | 9.82% | 10.85% | 9.81% | 10.87% | 13.68% | 6.63% | 7.09% |
| Oklahoma | 11.18% | 88.82% | 43.28% | 4.23% | 2.70% | 0.42% | 0.05% | 0.88% | 3.59% | 2.69% | 42.15% | 0.05% | 1.29% | 3.65% | 5.50% | 6.61% | 7.57% | 6.79% | 8.07% | 8.53% | 8.83% | 9.19% | 10.72% | 10.52% | 7.24% | 5.46% |
| Oregon | 9.72% | 90.28% | 46.60% | 0.78% | 0.53% | 0.62% | 0.09% | 0.62% | 2.75% | 2.45% | 45.56% | 0.02% | 0.66% | 2.41% | 4.11% | 5.20% | 5.54% | 5.15% | 6.96% | 8.57% | 9.59% | 9.93% | 11.66% | 15.10% | 7.39% | 7.71% |
| Pennsylvania | 8.75% | 91.25% | 45.65% | 4.95% | 0.08% | 0.38% | 0.03% | 0.67% | 1.50% | 1.87% | 44.87% | 0.01% | 0.61% | 2.51% | 3.81% | 4.63% | 5.10% | 5.02% | 6.90% | 9.30% | 10.28% | 9.27% | 10.27% | 15.05% | 8.12% | 9.14% |
| Rhode Island | 8.72% | 91.28% | 45.98% | 2.34% | 0.41% | 0.65% | 0.00% | 1.25% | 1.59% | 2.58% | 45.19% | 0.04% | 1.19% | 3.10% | 5.03% | 5.39% | 5.30% | 5.26% | 6.29% | 8.56% | 11.31% | 9.39% | 8.22% | 15.50% | 5.48% | 9.95% |
| South Carolina | 12.15% | 87.85% | 40.57% | 14.47% | 0.18% | 0.40% | 0.06% | 0.66% | 1.95% | 1.92% | 39.79% | 0.19% | 1.86% | 3.97% | 4.98% | 5.69% | 6.24% | 6.23% | 7.94% | 9.05% | 10.46% | 9.28% | 9.29% | 12.75% | 5.81% | 6.26% |
| South Dakota | 11.71% | 88.29% | 47.40% | 0.61% | 2.18% | 0.22% | 0.03% | 0.25% | 1.41% | 1.08% | 46.83% | 0.02% | 0.83% | 3.13% | 4.63% | 5.95% | 6.85% | 6.34% | 8.08% | 9.82% | 11.09% | 9.72% | 10.30% | 13.04% | 5.59% | 4.61% |
| Tennessee | 10.47% | 89.53% | 44.38% | 7.92% | 0.16% | 0.28% | 0.03% | 0.44% | 1.57% | 1.47% | 43.75% | 0.03% | 0.91% | 3.34% | 4.98% | 5.58% | 5.80% | 5.62% | 8.02% | 9.51% | 10.60% | 9.84% | 10.54% | 12.53% | 6.62% | 6.09% |
| Texas | 12.43% | 87.57% | 38.41% | 8.38% | 0.37% | 0.84% | 0.12% | 2.00% | 5.37% | 11.68% | 32.83% | 0.04% | 1.43% | 4.39% | 5.98% | 7.31% | 8.23% | 7.45% | 8.94% | 8.94% | 8.93% | 8.79% | 8.69% | 10.43% | 5.39% | 5.04% |
| Utah | 9.15% | 90.85% | 46.13% | 0.98% | 0.37% | 0.66% | 0.39% | 0.94% | 2.47% | 3.28% | 44.77% | 0.04% | 1.06% | 4.00% | 6.04% | 6.89% | 7.63% | 6.89% | 7.47% | 7.96% | 8.40% | 8.08% | 9.36% | 12.52% | 6.36% | 7.30% |
| Vermont | 9.27% | 90.73% | 48.35% | 0.24% | 0.06% | 0.29% | 0.02% | 0.37% | 1.98% | 0.55% | 48.12% | 0.00% | 0.70% | 2.30% | 3.95% | 4.67% | 4.55% | 4.80% | 6.69% | 9.14% | 12.24% | 11.12% | 10.36% | 12.58% | 8.65% | 8.25% |
| Virginia | 15.24% | 84.76% | 39.85% | 12.46% | 0.17% | 1.42% | 0.06% | 1.10% | 2.86% | 3.48% | 38.59% | 0.02% | 0.90% | 3.36% | 5.23% | 6.64% | 8.17% | 7.97% | 9.42% | 10.12% | 10.76% | 9.36% | 8.58% | 9.58% | 4.65% | 5.26% |
| Washington | 11.32% | 88.68% | 44.31% | 2.81% | 0.48% | 1.59% | 0.40% | 1.03% | 3.24% | 2.92% | 43.22% | 0.01% | 0.83% | 3.20% | 5.09% | 6.16% | 6.79% | 6.23% | 7.61% | 9.08% | 9.81% | 9.85% | 9.88% | 13.12% | 6.43% | 5.91% |
| West Virginia | 8.54% | 91.46% | 48.25% | 1.72% | 0.05% | 0.20% | 0.01% | 0.28% | 0.99% | 0.55% | 47.95% | 0.02% | 0.71% | 2.53% | 3.74% | 4.78% | 5.85% | 6.29% | 8.70% | 9.77% | 9.74% | 9.22% | 11.47% | 12.10% | 8.33% | 6.73% |
| Wisconsin | 9.49% | 90.51% | 47.35% | 1.68% | 0.45% | 0.39% | 0.01% | 0.46% | 1.54% | 1.33% | 46.79% | 0.03% | 0.76% | 2.79% | 4.17% | 5.18% | 5.17% | 4.75% | 6.89% | 9.38% | 10.08% | 9.51% | 11.11% | 14.82% | 7.46% | 7.91% |
| Wyoming | 11.05% | 88.95% | 47.09% | 0.88% | 0.66% | 0.24% | 0.01% | 0.94% | 1.79% | 2.40% | 46.00% | 0.03% | 1.01% | 3.15% | 5.24% | 6.17% | 7.34% | 6.67% | 8.28% | 9.18% | 9.30% | 9.44% | 10.81% | 13.67% | 5.98% | 3.72% |
| All States | 10.80% | 89.20% | 42.17% | 7.05% | 0.41% | 1.07% | 0.14% | 1.26% | 2.97% | 4.80% | 40.13% | 0.03% | 1.10% | 3.52% | 4.95% | 5.77% | 6.40% | 6.04% | 7.68% | 9.01% | 10.05% | 9.34% | 9.70% | 12.58% | 6.75% | 7.08% |
| Note: The calculations above do not contain data from Island Areas & Foreign or Puerto Rico. All data is from September 30th, 2023 VA state-level population tables Source: U.S. Department of Veterans Affairs, National Center for Veterans Analysis & Statistics. Veteran Population - Population Tables: The States. Last updated March 26 2025. https://www.va.gov/vetdata/veteran_population.asp (accessed October 26, 2025). |
||||||||||||||||||||||||||
# Export table
gt::gtsave(gt_tbl3, filename = "gt_tbl3.png")
file:////var/folders/kz/p2v973zn3tvby5f6_bzbrk9m0000gn/T//RtmpF7yEH3/file314739ecdfcb.html screenshot completed
This assessment took me approximately 25 hours to complete. A lot of time was spent on constructing the functions to import the MA penetration files, formatting each of the tables and figures, and troubleshooting error messages.
The two challenges I faced during this task were constructing the functions to import the MA penetration files and creating a figure to showcase the lat and long data for VA facilities. The functions took many trial and error attempts to create. The VA facilities coordinates figure would have been more clear if I was able to overlay a map of the United States, Alaska, and Hawaii. Unfortunately, I was having challenges importing and formatting polygons of the United States, Alaska, and Hawaii into the same figure. R does have the capability to do maps, but I could not figure it out in time before this assessment’s deadline.