rfor-loopleafletflexdashboard

R flexdashboard leaflet for loop


For a leaflet app, I have created multiple groups from my 'sf' polygon object based on an attribute value. Then I'm trying to use a 'for loop' to add these groups to the map, which is where the code below fails. I need to thematically symbolize values of another attribute for which I'm trying to add my colour table to these groups. Also I need each group to appear in legend with option to turn on/off checkboxes. Reproducible code below.

---
title: "try"
date: "`r Sys.Date()`"
output:
  flexdashboard::flex_dashboard:
  vertical_layout: fill
runtime: shiny
---
  
```{r setup, include = FALSE}
knitr::opts_chunk$set(echo=FALSE)
library(flexdashboard)
library(shiny)
library(tidyverse)
library(sf)
library(leaflet)

pdf(NULL)

nc <- st_read(system.file("shape/nc.shp", package="sf"))

subset <- nc %>% filter(SID74 <=5)

# Split data into multiple groups based on value of 'SID74'

splitField <- "SID74"
years <-  unique(subset[[splitField]])
# assign these multiple groups to different 'sf' objects, namely 'year1', 'year2'...  
for (i in 1:length(years)) {
  tmp <- subset[subset[[splitField]] == years[i], ]
  assign(paste0("year", i), tmp)
}

```

Map
===========================================================
  
Row
-----------------------------------------------------------
### Map

```{r}
renderLeaflet({

# Create custom colour palette

  colour6 <- tibble(
    severity = c("0", "1", "2", "3", "4","5"),
    Color = c("darkred", "#CC9966", "yellow", "#99CC33", "grey","black"))
  
  leaflet() %>% 
    setView(lng = -79.5, lat = 36,zoom =7) %>% 
  addTiles(group = "OSM (default)") %>% 
    for (i in 1:length(years)) {
      dat_col <- merge( x = get(paste0("year",i)), y =colour6, by.x ="SID74", by.y="severity")
      addPolygons(data =dat_col,
                  group = paste0("Year ",i),
                  fillColor = dat_col$Color,
                  opacity = 1,
                  color =  NA,
                  fillOpacity = 0.7) } %>% 
    addLayersControl(
      baseGroups = "OSM (default)",
      options = layersControlOptions(collapsed = FALSE)) %>% 
    addLegend(colors = colour6$Color, labels = colour6$severity)
})

```

Solution

  • I wasn't able to run this as a flex dashboard but this works for generating the leaflet object.

    Define some elements before hand

      colour6 <- tibble(
        severity = c("0", "1", "2", "3", "4","5"),
        Color = c("darkred", "#CC9966", "yellow", "#99CC33", "grey","black"))
    

    Including a basic map object

      m1 <- leaflet() %>% 
        setView(lng = -79.5, lat = 36,zoom =7) %>% 
        addTiles(group = "OSM (default)") 
    

    Use a for loop to redefined that map object, adding a new layer at each itoration

       for(i in 1:length(years)){
          dat_col <- merge( x = get(paste0("year",i)), y =colour6, by.x ="SID74", by.y="severity")
          
          m1 <- m1 %>%
          addPolygons(data =dat_col,
                      group = paste0("Year ",i),
                      fillColor = dat_col$Color,
                      opacity = 1,
                      color =  NA,
                      fillOpacity = 0.7) }
    

    End with assigning the legend and stuff.

      m1 <- m1 %>%
        addLayersControl(
          baseGroups = "OSM (default)",
          overlayGroups = paste0("Year ",seq(1:length(years))),
          options = layersControlOptions(collapsed = FALSE)) %>% 
        addLegend(colors = colour6$Color, labels = colour6$severity)
    

    Returning the map object 'm1' here should allow it to be passed into the reactive elements within the shiny structure, but I haven't tested that directly.

    m1
    

    enter image description here