Overview

The purpose of this report is to provide details on how to create an interactive map in R via the leaflet package. To do this, we’ll create a map of Divvy bike stations in Chicago, Illinois.

Setup

First, let’s import the packages we’ll need.

library(dplyr)
library(leaflet)
library(sf)

Now we can import the data set we need; a shapefile of Divvy bike station locations, stored as POINT geometries. Data was sourced from the Chicago Data Portal.

stations <- st_read("divvy/", quiet = TRUE)

glimpse(stations)
## Rows: 1,040
## Columns: 9
## $ id         <chr> "a3aa5ed1-a135-11e9-9cda-0a87ae2ba916", "a3b11480-a135-11e9…
## $ station_na <chr> "Damen Ave & Charleston St", "Laramie Ave & Kinzie St", "Wa…
## $ short_name <chr> "13288", "530", "RP-001", "21312", "17660", "KP1705001026",…
## $ total_dock <dbl> 11, 11, 11, 15, 15, 19, 15, 19, 15, 11, 11, 19, 31, 15, 9, …
## $ docks_in_s <dbl> 11, 11, 11, 15, 15, 19, 15, 19, 15, 11, 11, 19, 31, 15, 9, …
## $ status     <chr> "In Service", "In Service", "In Service", "In Service", "In…
## $ latitude   <dbl> 41.92008, 41.88783, 42.00178, 41.92777, 41.90036, 41.89488,…
## $ longitude  <dbl> -87.67785, -87.75553, -87.68883, -87.75854, -87.69670, -87.…
## $ geometry   <POINT [°]> POINT (-87.67785 41.92008), POINT (-87.75553 41.88783…

Mapping

Basic Points

Let’s start by creating a very simple leaflet interactive map…

# Invoke the leaflet() function, add a CartDB basemap, & add our point markers.
leaflet(data = stations) %>%
  addProviderTiles(providers$CartoDB) %>%
  addMarkers()

Clustering

It’s very obvious straight away that there are way too many points for this geographic extent - we should’ve seen that coming! There are over 1,000 Divvy bike stations in our dataset. Fortunately, the leaflet package makes it very easy to cluster a lot of points together, and the clusters break apart as you zoom in.

# Add some point clustering to make the map much easier to navigate & read.
leaflet(data = stations) %>%
  addProviderTiles(providers$CartoDB) %>%
  addMarkers(clusterOptions = markerClusterOptions())

Labels

Much better! But our “interactive” map isn’t very interactive yet (other than zooming in & out). Let’s add the station name when you hover over a point.

# Include the bike station name whenever a user hovers over a station point.
leaflet(data = stations) %>%
  addProviderTiles(providers$CartoDB) %>%
  addMarkers(label = ~station_na, clusterOptions = markerClusterOptions())

Popups

Good start, but nothing happens when you click on an individual station. In our dataset, we have some information on each bike station that might be useful for a user to see, such as the station status & the total number of docks. Let’s include some of that in our interactive map.

# Create a column containing the HTML-formatted popup information.
stations <- stations %>%
  mutate(popup = paste(
    paste0("Status: ", status),
    paste0("Total Docks: ", total_dock),
    sep = "<br>"
  ))

# Include the popup information in the `popup` parameter.
leaflet(data = stations) %>%
  addProviderTiles(providers$CartoDB) %>%
  addMarkers(label = ~station_na, popup = ~popup, clusterOptions = markerClusterOptions())

Icons

Finally, just for fun let’s make each of the points have a bicycle icon.

icons = awesomeIcons(icon = 'bicycle', markerColor = "blue", library = 'fa')

leaflet(data = stations) %>%
  addProviderTiles(providers$CartoDB) %>%
  addAwesomeMarkers(
    label = ~station_na,
    popup = ~popup,
    clusterOptions = markerClusterOptions(),
    icon = icons
  )