Harish
Harish

Reputation: 295

Interactive United sates county map using Leaflet

I have US county data set for all the sates. Providing only a sample how it looks like,

county   state   value_x
Adair    Oklahoma  5
Adair    Missouri  2
Adair    Kentucky  10
Adair    lowas     1

I was able to plot this using plotly by adding lat and long coordinates to the dataset using map_data . But I found plotly was too slow to hover/zoom functions when entire US states were plotted.

So i wanted to try using leaflet. I went through some of the codes online. Interesting none of them had the lat/long coordinates. I want to understand how to use them for my dataset. Because some counties appear to have same name but available in different sates. How would that be plotted without any coordinates?

Here's the code i tried. The value_x is not plotted correctly as per the county. It's bizarre. Please help fix this. I want to zoom in at counties and want value_x to get popped up when i click on it.

library(raster)
library(leaflet)
library(tidyverse)

# Get USA polygon data
USA <- getData("GADM", country = "usa", level = 2)

### Get data. I can't provide the date set. It has county, state and value _x as shown above 
mydata <- county,state,value_x

### Check counties that exist in USA, but not in mydata
### Create a dummy data frame and bind it with mydata

mydata <- data.frame(county= setdiff(USA$NAME_2, mydata$county),
                     value_x = NA,
                     stringsAsFactors = FALSE) %>%
          bind_rows(mydata)

### Create a color palette
mypal <- colorNumeric(palette = "viridis", domain = mydata$value_x)

leaflet() %>% 
addProviderTiles("OpenStreetMap.Mapnik") %>%
setView(lat = 39.8283, lng = -98.5795, zoom = 4) %>%
addPolygons(data = USA, stroke = FALSE, smoothFactor = 0.2, fillOpacity = 0.3,
            fillColor = ~mypal(mydata$value_x),
            popup = paste("Region: ", USA$NAME_2, "<br>",
                          "Value X: ", mydata$value_x, "<br>")) %>%
 addLegend(position = "bottomleft", pal = mypal, values = mydata$value_x,
           title = "Value X",
           opacity = 1)

Upvotes: 2

Views: 5868

Answers (1)

jazzurro
jazzurro

Reputation: 23574

I do not know how your data is like. So I tailored the following demo under the condition that you have data points for counties that have an identical name only. You may need to modify the following code.

The key thing here is to merge your data set with the polygon data (i.e., USA). When you use leaflet, there are two ways to fill in polygons. You can have a fill variable in your polygon data or another data frame containing the variable. When you have counties with an identical name, I think having the fill variable in the polygon data set may be better. This approach makes sure that right fill values assigned to right polygons. In order to do this, you want to merge your data set (i.e., mydata) with the polygon data (i.e., USA). When you merge them, you need to specify which columns you use for the operation.

In this case, you have two counties with an identical name (i.e., Adair). You have different column names in USA and mydata. You need to tell R which columns are matching with which columns. NAME_1 is matching with state, for example. You handle this in merge(). The following map has fill for Adair only. The one in Oklahoma has 100 in value, not 20; the merge process went right. I hope this helps you. (By the way, I could have only two counties under the name of Adair.)

library(raster)
library(leaflet)
library(viridis)

# Get USA polygon data
USA <- getData("GADM", country = "usa", level = 2)

# Prepare data

mydata <- data.frame(state = c("Iowa", "Oklahoma"),
                     county = "Adair",
                     value = c(20, 100),
                     stringsAsFactors = FALSE)

# I do not know how your actual data is like. In this demonstration,
# I have data points for Adair in Iowa and Oklahoma. So 

temp <- merge(USA, mydata,
              by.x = c("NAME_1", "NAME_2"), by.y = c("state", "county"),
              all.x = TRUE)

# Create a color palette
mypal <- colorNumeric(palette = "viridis", domain = temp$value, na.color = "grey")

leaflet() %>% 
addProviderTiles("OpenStreetMap.Mapnik") %>%
setView(lat = 39.8283, lng = -98.5795, zoom = 4) %>%
addPolygons(data = USA, stroke = FALSE, smoothFactor = 0.2, fillOpacity = 0.3,
            fillColor = ~mypal(temp$value),
            popup = paste("Region: ", temp$NAME_2, "<br>",
                          "Value: ", temp$value, "<br>")) %>%
addLegend(position = "bottomleft", pal = mypal, values = temp$value,
          title = "Value",
          opacity = 1)

enter image description here

Upvotes: 4

Related Questions