I want to use different icons in a leaflet plot in R based on a factor variable in a dataframe. The factor variable might have 100 different levels, but I only have icons for a few levels, maybe 10 or so. If there is an icon I want to use it, else draw CircleMarkers.
I can do this with a for loop:
library(leaflet)
# Some icons
fruits_icons <- iconList(
apple = makeIcon("apple.png", iconWidth = 20, iconHeight = 20),
banana = makeIcon("banana.png", iconWidth = 20, iconHeight = 20)
)
# Some data
latitude <- 48 + runif(20)
longitude <- 10 + runif(20)
fruit <- sample(c("banana", "apple", "pear"), 20, replace = TRUE)
df <- data.frame(latitude, longitude, fruit)
map <- leaflet(df) %>% addTiles()
# check if fruit is in names(icons), then use icons, else circles
for(i in seq_len(nrow(df))){
if(df$fruit[i] %in% names(fruits_icons)){
map <- map %>% addMarkers(lng = df$longitude[i],
lat = df$latitude[i],
icon = ~fruits_icons[df$fruit[i]])
} else {
map <- map %>% addCircleMarkers(lng = df$longitude[i],
lat = df$latitude[i])
}
}
map
Is there a better way to do this without the for loop?
You can just subset the data that you want to use in each of the add*()
methods
leaflet() %>% addTiles() %>%
addMarkers(data = df[df$fruit %in% names(fruits_icons),],
lng = ~longitude,
lat = ~latitude,
icon = ~fruits_icons[fruit]) %>%
addCircleMarkers(data = df[!df$fruit %in% names(fruits_icons), ],
lng = ~longitude,
lat = ~latitude)