Create a choropleth map showing the unemployment rate within a
selected country. Design an appropriate legend for the map.
Step 1: Install necessary libraries
# Load the libraries
library(sf)
library(dplyr)
library(ggplot2)
library(RColorBrewer)
library(htmltools)
library(tigris)
library(leaflet)
library(htmlwidgets)
Step 2: Load and clean the dataset
# Load the dataset
data <- read.csv("/Users/ogeohia/Downloads/CleanedUnemploymentData.csv")
# Cleaning data: Rename columns and ensure the unemployment rate is numeric
data_clean <- data %>%
mutate(Unemployment_rate = as.numeric(Unemployment_rate))
# View cleaned data
head(data_clean)
## State Unemployment_rate
## 1 South Dakota 1.9
## 2 Vermont 2.4
## 3 North Dakota 2.5
## 4 New Hampshire 2.6
## 5 Nebraska 2.8
## 6 Connecticut 3.0
Step 3: Download US shapefile data for state boundaries
# Download US states shapefile (boundaries)
states <- states(cb = TRUE, progress = FALSE)
# Convert to 'sf' (simple features) format for easier handling
states_sf <- st_as_sf(states)
# View the shapefile data
head(states_sf)
## Simple feature collection with 6 features and 9 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: -179.1489 ymin: -14.5487 xmax: 179.7785 ymax: 71.36516
## Geodetic CRS: NAD83
## STATEFP STATENS AFFGEOID GEOID STUSPS NAME LSAD ALAND
## 1 56 01779807 0400000US56 56 WY Wyoming 00 2.514587e+11
## 2 02 01785533 0400000US02 02 AK Alaska 00 1.478943e+12
## 3 24 01714934 0400000US24 24 MD Maryland 00 2.515199e+10
## 4 60 01802701 0400000US60 60 AS American Samoa 00 1.977591e+08
## 5 05 00068085 0400000US05 05 AR Arkansas 00 1.346608e+11
## 6 38 01779797 0400000US38 38 ND North Dakota 00 1.786943e+11
## AWATER geometry
## 1 1867503716 MULTIPOLYGON (((-111.0546 4...
## 2 245378425142 MULTIPOLYGON (((179.4825 51...
## 3 6979074857 MULTIPOLYGON (((-76.05015 3...
## 4 1307243751 MULTIPOLYGON (((-168.1458 -...
## 5 3121950081 MULTIPOLYGON (((-94.61792 3...
## 6 4414779956 MULTIPOLYGON (((-104.0487 4...
Step 4: Merge the unemployment data with the shapefile
# Merge the shapefile with unemployment data
merged_data <- left_join(states_sf, data_clean, by = c("NAME" = "State"))
# View merged data to check for any discrepancies
head(merged_data)
## Simple feature collection with 6 features and 10 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: -179.1489 ymin: -14.5487 xmax: 179.7785 ymax: 71.36516
## Geodetic CRS: NAD83
## STATEFP STATENS AFFGEOID GEOID STUSPS NAME LSAD ALAND
## 1 56 01779807 0400000US56 56 WY Wyoming 00 2.514587e+11
## 2 02 01785533 0400000US02 02 AK Alaska 00 1.478943e+12
## 3 24 01714934 0400000US24 24 MD Maryland 00 2.515199e+10
## 4 60 01802701 0400000US60 60 AS American Samoa 00 1.977591e+08
## 5 05 00068085 0400000US05 05 AR Arkansas 00 1.346608e+11
## 6 38 01779797 0400000US38 38 ND North Dakota 00 1.786943e+11
## AWATER Unemployment_rate geometry
## 1 1867503716 3.5 MULTIPOLYGON (((-111.0546 4...
## 2 245378425142 4.7 MULTIPOLYGON (((179.4825 51...
## 3 6979074857 3.1 MULTIPOLYGON (((-76.05015 3...
## 4 1307243751 NA MULTIPOLYGON (((-168.1458 -...
## 5 3121950081 3.4 MULTIPOLYGON (((-94.61792 3...
## 6 4414779956 2.5 MULTIPOLYGON (((-104.0487 4...
# Check for missing values in the Unemployment_rate column
sum(is.na(merged_data$Unemployment_rate))
## [1] 5
# Remove rows where Unemployment_rate is NA or contains non-numeric values
merged_data <- merged_data %>% filter(!is.na(Unemployment_rate))
# Verify that the rows with missing values were removed
sum(is.na(data_clean$Unemployment_rate))
## [1] 0
# Drop unnecessary columns from merged_data
merged_data_cleaned <- merged_data %>%
select(STUSPS, NAME, Unemployment_rate, geometry)
Step 5: Create the choropleth map and legend
# Convert to sf object
merged_data_sf <- st_as_sf(merged_data_cleaned)
# Define color palette
palette <- brewer.pal(n = 7, name = "YlGnBu")
# Create breaks for the legend
breaks <- quantile(merged_data_sf$Unemployment_rate, probs = seq(0, 1, length.out = 8))
labels <- paste0(round(breaks[-length(breaks)], 2), " - ", round(breaks[-1], 2))
# Define color palette (using quantiles for breaks)
bins <- quantile(merged_data_sf$Unemployment_rate, probs = seq(0, 1, length.out = 6)) # 5 breaks
pal <- colorBin(
palette = "YlGnBu", # Or another palette of your choice
domain = merged_data_sf$Unemployment_rate,
bins = bins,
na.color = "transparent" # Handle missing values
)
# Create labels for the popup
labels <- sprintf(
"<strong>%s</strong><br/>Unemployment Rate: %g%%",
merged_data_sf$NAME, merged_data_sf$Unemployment_rate
) %>% lapply(htmltools::HTML)
# Create the title and source as HTML elements
title <- tags$h4("US State Unemployment Rates (Dec 2024)",
style = "text-align: center; font-weight: bold; margin-bottom: 0px;")
source <- tags$p(
HTML("Source: <a href='https://www.bls.gov/lau/' target='_blank'>U.S. Bureau of Labor Statistics</a>"),
style = "text-align: center; font-size: 7px; margin-top: 2px;"
)
# Reproject to WGS84
merged_data_sf_wgs84 <- st_transform(merged_data_sf, crs = 4326)
# Create the interactive map
map <- leaflet(merged_data_sf_wgs84) %>%
setView(-98.5, 39.8, zoom = 4) %>%
addPolygons(
fillColor = ~pal(Unemployment_rate), # Use the palette function
weight = 1,
color = "black",
fillOpacity = 0.7,
highlightOptions = highlightOptions(
weight = 3,
color = "white",
fillOpacity = 1,
bringToFront = TRUE
),
label = labels,
labelOptions = labelOptions(
style = list("font-weight" = "normal", padding = "3px 8px"),
textsize = "10px",
direction = "auto"
)
) %>%
addLegend(
pal = pal, # Use the palette object
values = ~Unemployment_rate, # Map values to the legend
opacity = 0.7,
title = "Unemployment Rate (%)",
position = "topright",
) %>%
addControl( # Add the title and source as a custom control
html = paste0(as.character(title), as.character(source)), # Combine title and source
position = "bottomleft" # You can adjust the position
)
map