My first interactive map with {leaflet}
I have tried creating a map with ggplot2 previously. In this post, I will try to create an interactive map using leaflet package in R.
These are the required packages.
library(tidyverse)
library(tidygeocoder)
library(leaflet)
library(htmltools)
So, I’m going to use a clinics location data in Malaysia. I already uploaded this data tomy GitHub repo. I will skip the explanation for the pre-processing part, but it is the same pre-processing as my previous post.
# Read the data
clinic1m <- read.csv("https://raw.githubusercontent.com/tengku-hanis/clinic-data/main/clinic1m.csv")
clinicDesa <- read.csv("https://raw.githubusercontent.com/tengku-hanis/clinic-data/main/clinicdesa.csv")
Show code for pre-processing
# Get the missing coordinate based on postal codes
clinic1m2 <-
clinic1m %>%
mutate(country = "malaysia") %>%
select(name, postcode, country) %>%
mutate(postcode = ifelse(nchar(postcode) == 4, paste0(0, postcode), postcode)) %>%
geocode(postalcode = postcode, country = country, method = "osm")
# Add coordinate from external sources for the still missing coordinates
add_coord <-
read.table(header = T, text = "
postal_code latitude longitude
16070 6.0334 102.3499
26060 3.6228 102.3926
90700 5.8456 118.0571
26060 3.6228 102.3926")
# Drop clinics with the still missing coordinate
clinic1m2 <-
clinic1m2 %>%
mutate(lat = ifelse(postcode %in% add_coord$postal_code, add_coord$latitude, lat),
long = ifelse(postcode %in% add_coord$postal_code, add_coord$longitude, long)) %>%
drop_na() #drop 2 clinic1m
# Bind the 2 data
all_clinic <-
clinic1m2 %>%
mutate(Type = "1Malaysia") %>%
select(name, Type, lat, long) %>%
bind_rows(clinicDesa %>%
mutate(Type = "Desa",
lat = latitude,
long = longitude) %>%
select(name, Type, lat, long)) %>%
mutate(name = str_to_title(name))
First, we going to plot the coordinates to see if there is anything strange.
ggplot(all_clinic, aes(long, lat, color = Type)) +
geom_point() +
theme_minimal()

So, we are going to remove the two isolated points as seen from the plot.
all_clinic2 <- all_clinic %>% filter(long > 25)
Once we have our data ready, we can supply to leaflet. We can choose the type of map from addProviderTiles(). Some need an api, but the one we choose here does not. We supply the longitude and latitude of our data to addCircleMarkers(), and clusterOptions to cluster our data.
leaflet(all_clinic2) %>%
addProviderTiles(providers$Stamen.Watercolor) %>%
addProviderTiles(providers$Stamen.TerrainLabels) %>%
addCircleMarkers(~long, ~lat,
clusterOptions = markerClusterOptions())
Next, we can add a label.
labels <-
sprintf("<strong>%s</strong>", all_clinic$name) %>%
lapply(htmltools::HTML)
Also, we can add a mini map to our map. Here, I change the type of map to a more appropriate one.
leaflet(all_clinic2) %>%
addProviderTiles(providers$OpenStreetMap) %>%
addCircleMarkers(~long, ~lat, popup = ~labels, # popup add the label
clusterOptions = markerClusterOptions()) %>%
# add a mini map
addMiniMap(tiles = providers$OpenStreetMap, zoomLevelOffset = -3)
Notice that the coordinates look more accurate as compared to the map I created with ggplot2 previously.
References: