Measles by the Numbers

 

Generated by ChatGPT 5.2

On Feb. 28, 2026, I downloaded data for reported weekly US measles cases by rash onset from the CDC website https://www.cdc.gov/measles/data-research/index.html into a file named measles_data_weekly.csv. I plotted the data using R.


library(tidyverse)
df_by_week <- read_csv("/mnt/g/measles/data/measles_data_weekly.csv")
> head(df_by_week)
# A tibble: 6 × 2
  week_start cases
  <date>     <dbl>
1 2022-01-02     0
2 2022-01-09     0
3 2022-01-16     0
4 2022-01-23     0
5 2022-01-30     1
6 2022-02-06     0
> 

# plot weekly data
ggplot(df_by_week, aes(x = week_start, y = cases)) + 
  geom_bar(stat = "identity", color = 'blue') + 
  labs(x = "Date", y = "Cases", title = "Measles Cases by Week")


What happened in February 2025? One thing was that a new administration was in place in Washington with an anti-vax conspiracy theorist as Secretary of Health and Human Services. I hadn't expected such a clear correlation. Maybe all of the dramatic increase in cases can be attributed to the new HHS administration, but I suspect that they deserves much of the blame. 

I also downloaded a file of estimated percent of the population vaccinated by state and school year from the same CDC site. I used the data to plot a map of the continental US showing the percent vaccinated in each state.

#' vax_map - display a map of vaccination status by state
#'
#' @param school_year - a string, the school year in the format YYYY-YY
#' @param data_file  - a file of MMR coverage from
#'                     https://www.cdc.gov/measles/data-research/index.html
#'
#' @returns a list
#'    school_year - the input school year
#'    data_file - the source data file
#'    df - a data frame of State, percent_vaxed, state_abbr for the school year.
#'    us_vaxed - a data_frame returned by map_data with added columns:
#'               percent_vaxed and state_abbr. Used for drawing the map.
#'               
vax_map <- function(school_year = "2024-25", 
                    data_file = "/mnt/g/measles/data/vacinations.csv") {
  library(tidyverse)
  
  # read the CSV file, select the school year. 
  # Create a data frame with columns: 
  #   State, percent_vaxed (percentage vaccinated), 
  #   and state_abbr (state abbreviation)
  df <- read_csv(data_file)
  df_school_year <- df |>
    filter(`School Year` == school_year) |>
    select(Location, `Estimated Percent Vaccinated`) |>
    rename(percent_vaxed = `Estimated Percent Vaccinated`) |>
    rename(State = Location) |>
    filter(! State %in% c("District of Columbia", "New York City",
                          "San Antonio", "Houston", "Alaska", "Hawaii")) |>
    mutate(percent_vaxed = parse_number(percent_vaxed)) |>
    mutate(State = str_to_lower(State)) |>
    mutate(state_abbr = state.abb[match(State, str_to_lower(state.name))])
  
  # join percent_vaxed and state_abbr to state map data
  us_states <- map_data("state")
  us_states <- us_states |>
    filter(! region %in% "district of columbia") |>
    left_join(df_school_year, by=c("region"="State")) 
  
  # Calculate centroid to center state_abbr on map
  centroid <- aggregate(cbind(long,lat) ~ region, data=us_states, 
                        FUN=function(x) mean(range(x)))
  centroid <- centroid |>
    left_join(df_school_year, by = c("region" = "State"))

  p <- ggplot() +
    geom_polygon(data = us_states, 
                 mapping = aes(x = long, y = lat, 
                               group = group, 
                               fill = percent_vaxed),
                 linewidth = 0.1,
                 color = "grey90") +
    geom_text(data = centroid, mapping = aes(x = long, y = lat, 
                                             label = state_abbr)) +
    coord_map(projection = "albers", lat0 = 45, lat1 = 55) +
    scale_fill_continuous(type = "viridis")+
    theme(legend.position="bottom",
          axis.line=element_blank(),
          axis.text=element_blank(),
          axis.ticks=element_blank(),
          axis.title=element_blank(),
          panel.background=element_blank(),
          panel.border=element_blank(),
          panel.grid=element_blank()) +
    labs(fill = "Percent Vaxed",
         title = paste("Measles PerCent Vacination for School Year", school_year))
  
  print(p)
  
  return(list(school_year = school_year,
              data_file = data_file,
              df = df_school_year, 
              us_vaxed = us_states))
}



Comments

Popular posts from this blog

Julia and the Blockchain

Filter Reads in Bam Files

School Shootings Are Political Violence