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
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
)
)
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')
)
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)
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.
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.
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)
So we created some maps, but we can do better than that and use more of leaflet to make a prettier map.
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
)
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
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
)
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))
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))
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: