1 Introduction

Objective: In this lab we will go over a couple of libraries to make interactive figures with R and then implement this in out shiny app.


First we load the libraries and data we will use. In previous labs we were projecting our spatial data, for this one we will use the EPSG84 coordinate reference system (lat/long).

# Load libraries
library(dplyr)
library(sf)
library(STNet)

# Load data
data("vac") # Data for vaccination
data("vigilancia") # Data for surveillance
data("captura")

# Loading the spatial data from the package
MxShp <- st_read(system.file("data/MxShp.shp", package = "STNet")) %>% 
  filter(CVE_ENT %in% c('15', '12', '16')) %>%  # Filter the data to use the states with codes: 15, 12 y 16
  st_transform(crs = st_crs(4326)) # transform to lat/long
## Reading layer `MxShp' from data source 
##   `/Library/Frameworks/R.framework/Versions/4.2/Resources/library/STNet/data/MxShp.shp' 
##   using driver `ESRI Shapefile'
## Simple feature collection with 2471 features and 6 fields
## Geometry type: MULTIPOLYGON
## Dimension:     XY
## Bounding box:  xmin: 1058748 ymin: 319149.1 xmax: 4082958 ymax: 2349605
## Projected CRS: MEXICO_ITRF_2008_LCC

2 Tables with DT

DT is a library to create tables with some nice features such as search, sort and export the data. Lets have a look at the default table that the function datatable() returns

library(DT) # Load library

# Create a datatable
captura %>% 
  datatable()

We can be more specific with our tables, there are multiple arguments that we can specify to change how our table looks like

captura %>% 
  datatable(
    rownames = F,
    filter = 'top', # Add a filter at the top
    options = list(
      searching = F,# Remove the searchbar
      pageLength = 5 # Change the max number of rows
      )
  )

2.1 Changing column names

captura %>% 
  datatable(
    rownames = F,
    options = list(
      searching = F,# Remove the searchbar
      pageLength = 5 # Change the max number of rows
      ),
    colnames = c('Municipality', 'Location', 'location 2', 'date', 'Year', 'Captures', 'Treated', 'Lat', 'Lon')
  )

2.2 Download button

DT has a couple of extensions that introduce other functionality, one of them is to add a button to download the data. Lets have a look how to add this:

captura %>% 
  DT::datatable(
    rownames = FALSE,
    extensions = 'Buttons',
    options = list(
      dom = "Blfrtip",
      buttons = list("copy",
                     list(extend = "collection",
                          buttons = c("csv", "excel", "pdf"),
                          text = "Download")))
    )

There are other extensions you can explore in this link

3 Maps with Leaflet

Leaflet is an open source library for interactive maps implemented in R. The library allows you to use different type of objects such as simple features (sf format) or simple data.frames with lat/long columns. Lets make sure we have the library installed and then load it.

# install.packages("leaflet") # If you havent, install the library
library(leaflet)

3.1 Point data

The library is similar to ggplot2 in the sense that we first use the function leaflet() to call an empty canvas and then we add layers of information.
Lets crate an empty map with the point data we previously used. Leaflet expects by default data in Lat Lon, so we will have to make some changes to our data, which was previously projected in another CRS.

# Transform it to spatial points
capturaSp <- captura %>% 
  st_as_sf(coords = c('LONG', 'LATITUD'), crs = st_crs(4326)) 

leaflet() %>% # create the empty map
  addMarkers(data = capturaSp) # put the first layer

Now we have an empty canvas with some markers. We could add a base shapefile to have a better sense of the space, but leaflet also provides some base maps for us to use, lets add one.

3.2 Basemaps

We will use a base map from open street maps. If you want to explore other layers, you can start by typing providers$ and use the auto complete function in R to select other base maps.

leaflet() %>% 
  addProviderTiles(providers$OpenStreetMap) %>% 
  addMarkers(data = capturaSp) # put the first layer

There is also this website: Providers demo, that shows in real time some of the available provides for baes maps in leaflet.

3.3 Polygons

We can also use polygon data with leaflet. We will first aggregate all the point layer information into a polygon data. To do this we will join the points with the polygon and then summarise the number of captures by polygons to create a choropleth map.

# Agregate points per polygon
x <- MxShp %>% # This is the polygon data
  st_join(capturaSp['CAPTURADOS']) %>% # We spatial join it with the points
  data.frame() %>% # Convert it to a data.frame
  group_by(CVEGEO) %>% # Grouop by the admin ID
  summarise(CAPTURADOS = sum(CAPTURADOS, na.rm = T)) # Sum all the captures

# Join the information with the polygon data
MxShp <- MxShp %>%
  left_join(x)


leaflet() %>%
  addProviderTiles(providers$OpenStreetMap) %>%
  addPolygons(data = MxShp, fillColor = ~CAPTURADOS) 

4 Improving the visuals

So we created some maps, but we can do better than that and use more of leaflet to make a prettier map.

4.1 Labels and popups

We can add text and different attributes to our markers using labels and popups. Labels will show when we hover over our point, and popups will show when we click on them. YOu can use both in the same map, labels are meant to show short text and popups to show longer text.

Lets create a label for our markers:

 # Creating a label
leaflet() %>% 
  addProviderTiles(providers$OpenStreetMap) %>% 
  addMarkers(
    data = capturaSp, # This is the data
    label = ~NOM_LOC # The variable we are using for the label
    )

Now lets create a popup for our map.

# Creating a popup
leaflet() %>% 
  addProviderTiles(providers$OpenStreetMap) %>% 
  addMarkers(
    data = capturaSp,
    # We can format the popup using some html tags
    popup = ~paste('Name:', NOM_LOC, 
                   "<br>Captures:", CAPTURADOS) # The variable we are using for the label
    )

4.2 Creating clusters

Leaflet has a very convenient feature that allows you to create clusters with the point data. This clusters count the number of markers in an area and change when you zoom or click into the clusters

leaflet() %>% 
  addProviderTiles(providers$OpenStreetMap) %>% 
  addMarkers(data = capturaSp, clusterOptions = markerClusterOptions()) # put the first layer

4.3 Changing the icon

We can also change the icons for our markers. In the following example we will get an image from internet to use it as a marker:

# This is the url for the figure:
iu <- 'https://cdn140.picsart.com/239825197004212.png?to=crop&r=1008x948&q=85'
# Now we make an icon with the url
ic <- makeIcon(iconUrl = iu, iconHeight = 40, iconWidth = 40)

leaflet() %>% 
  addProviderTiles(providers$OpenStreetMap) %>% 
  addMarkers(
    data = capturaSp, 
    popup = ~paste('Name:', NOM_LOC, 
                   "<br>Captures:", CAPTURADOS),
    icon = ic
    )

4.4 Using other markers

We can use other type of representations for point data. Here we will use the function addCircleMarker() which will represent the point data with a circle.

leaflet() %>% 
  addProviderTiles(providers$OpenStreetMap) %>% 
  addCircleMarkers(data = capturaSp, # This is the data set
                   stroke = F, # Option to remove the outline of the circle
                   radius = ~CAPTURADOS, # use the number of captures for the size
    popup = ~paste('Name:', NOM_LOC, 
                   "<br>Captures:", CAPTURADOS))

4.5 Improving our choropleth map

There are multiple options for improving our polygon map. We can change the fill color, outline width, among others. To change the color scale we have to create a color palette based in our observations.

# Create a continuous palette 
pal <- colorNumeric(
  palette = "Reds",
  domain = MxShp$CAPTURADOS)


leaflet() %>%
  addProviderTiles(providers$OpenStreetMap) %>%
  addPolygons(data = MxShp,
              color = 'black', 
              weight = 1, fillColor = ~pal(CAPTURADOS),
              label = ~NOMGEO,
              popup = ~paste('Name:', NOMGEO, 
                   "<br>Captures:", CAPTURADOS))

5 Exercise: Implementation in Shiny

To add DT and Leaflet objects into our app, we just need to create the objects and make sure we use the correct Output and Render functions.
Lets try to add a map to the app we already have: