Leaflet popup graphs don't correspond to map

729 views Asked by At

I am trying to make a choropleth map as an html widget using the leaflet package. I don't want to deal with shiny for this. I have covid death time series data for each state. I would like to be able to click on states and have the corresponding time series graph to popup. I have gotten so close but my problem is that the graphs that popup when you click on a state do not correctly correspond to that state. For example, if you click on Ohio a West virginia map pops up.

Shapefile data: https://www.census.gov/cgi-bin/geo/shapefiles/index.php?year=2019&layergroup=States+%28and+equivalent%29

Covid data: https://data.cdc.gov/Case-Surveillance/United-States-COVID-19-Cases-and-Deaths-by-State-o/9mfq-cb36

library(tidyverse)
library(lubridate)
library(readr)
library(leaflet)
library(tigris)
library(rgdal)
library(leafpop)

states <- readOGR(dsn = "tl_2019_us_state", layer = "tl_2019_us_state")

covid_deaths<- read_csv("covid_deaths_usafacts.csv")
Clean_Deaths<- covid_deaths%>%
  select(submission_date, state, tot_cases,new_case,tot_death,new_death)%>%
  filter(new_death>=0)%>%
  mutate(submission_date=as.Date(Clean_Deaths$submission_date, "%m/%d/%Y"))

my_list <- list()  
loop<-for (i in unique(Clean_Deaths$state)) {
state<-Clean_Deaths%>% filter(state==i)
  plot<-ggplot(state, aes(x = submission_date, y = new_death)) + 
    geom_line()+scale_x_date(date_breaks = "1 month",date_labels = "%b")+labs(title = i)
  my_list[[i]] <- plot
}

m1 <- leaflet() %>%
  addTiles() %>%
  setView(lng = -120.5, lat = 44, zoom = 6)%>%
  addPolygons(data = states, 
              fillColor = "red",
              fillOpacity = 0.6,       
              color = "darkgrey",      
              weight = 1.5, 
              popup = popupGraph(my_list)
              )
  m1

My issue

1

There are 1 answers

1
Ben On BEST ANSWER

I think you have abbreviations for state in Clean_Deaths$state (e.g., "NY") and you have full state names in states$NAME (e.g., "New York").

In your filter, you can convert from one to other. Your for loop can go through states$NAME which will match your data used in your map:

for (i in states$NAME) {
  state<-Clean_Deaths%>% filter(state==state.abb[match(i, state.name)])
  plot<-ggplot(state, aes(x = submission_date, y = new_death)) + 
    geom_line()+scale_x_date(date_breaks = "1 month",date_labels = "%b")+labs(title = i)
  my_list[[i]] <- plot
}

Here is something comparable using lapply and simplified:

my_list <- lapply(states$NAME, function(i) {
  Clean_Deaths %>%
    filter(state == state.abb[match(i, state.name)]) %>%
    ggplot(aes(x = submission_date, y = new_death)) +
      geom_line() +
      scale_x_date(date_breaks = "1 month",date_labels = "%b") +
      labs(title = i)
})

As an aside, your mutate before this does not need the data frame referenced in the pipe:

mutate(submission_date=as.Date(submission_date, "%m/%d/%Y"))

Let me know if this addresses your problem.