Search code examples
rshinyr-leaflet

conditionally addCircleMarkers to leaflet


I have a bunch of reactive filters based on user inputs. I want to addCircleMarkers on my leaflet map only if the filters do not return a NULL value. How can I conditionally addCircleMarkers to a leaflet map in Shiny? Right now it seems that it only plots the results from the second filter instead of both even if user inputs are not NULL for both. My guess is that the second addCircleMarkers function is overwriting the first instead of adding more circles to the map. Here's my server code below:

server.R

server <- function(input, output) {


relig_pal <- colorFactor("magma", unique(all_cleaned$religion))
denom_pal <- colorFactor("viridis", unique(all_cleaned$denom))
  
output$mymap <- renderLeaflet({
  input$years_map
  input$map_button
  isolate({
    map <- leaflet() %>% addTiles() 
    if(!is.null(geography_1())) {
    marker_1 <- addCircleMarkers(map = map, data = geography_1(),
                     radius = ~ifelse(is.na(denom), log(religion_population), 
                                      log(denom_pop)),
                     color = ~ifelse(is.na(denom), relig_pal(religion),
                                     denom_pal(denom)),
                     label = ~ifelse(is.na(denom), 
                                            paste("Religion:",religion,
                                                  "Population:",religion_population),
                                            paste("Denomination:", denom,               
                                                  "Population:", denom_pop)) 
    )
    }
    if(!is.null(geography_2())) {
    marker_1 %>% addCircleMarkers(data = geography_2(),
                     radius = ~ifelse(is.na(denom), log(religion_population), 
                                      log(denom_pop)),
                   color = ~ifelse(is.na(denom), relig_pal(religion),
                                   denom_pal(denom)),
                   label = ~ifelse(is.na(denom), 
                                          paste("Religion:", religion,
                                                "Population:", religion_population),             
                                          paste("Denomination:", denom,              
                                                "Population:", denom_pop))
    )
    }
  })
})

year <- reactive({
  req(input$years_map)
  all_cleaned %>% filter(year == input$years_map)
})

religion_1 <- reactive({
  req(input$religion_1_map)
  if(input$religion_1_map == "All") {
    year()
  }
  else if(input$religion_1_map == "None") {
    return()
  }
  else {
    year() %>% filter(religion == input$religion_1_map)
  }
})

denom_1 <- reactive({
  req(input$denom_1_map)
  if(input$denom_1_map == "All") {
    religion_1()
  }
  else if(input$denom_1_map == "None") {
    religion_1() %>% filter(is.na(denom))
  }
  else {
    religion_1() %>% filter(denom == input$denom_1_map)
  }
})

geography_1 <- reactive({
  req(input$geography_1_map)
  if(input$geography_1_map == "All") {
    denom_1()
  }
  else if(input$geography_1_map == "None") {
    return()
  }
  else {
    denom_1() %>% filter(country_name == input$geography_1_map)
  }
})


religion_2 <- reactive({
  req(input$religion_2_map)
  if(input$religion_2_map == "All") {
    year()
  }
  else if(input$religion_2_map == "None") {
    return()
  }
  else {
    year() %>% filter(religion == input$religion_2_map)
  }
})

denom_2 <- reactive({
  req(input$denom_2_map)
  if(input$denom_2_map == "All") {
    religion_2()
  }
  else if(input$denom_2_map == "None") {
    religion_2() %>% filter(is.na(denom))
  }
  else {
    religion_2() %>% filter(denom == input$denom_2_map)
  }
})

geography_2 <- reactive({
  req(input$geography_2_map)
  if(input$geography_2_map == "All") {
    denom_2()
  }
  else if(input$geography_2_map == "None") {
    return()
  }
  else {
    denom_2() %>% filter(country_name == input$geography_2_map)
  }
})

}

Error message:

Error:no applicable method for 'filter_' applied to an object of class "NULL"

Solution

  • Update:

    I have managed to solve the problem using @Roman Luštrik 's suggestion of storing the first circle marker as a variable and using a placeholder to plot a point of opacity 0 instead of dealing with NULL values whenever nothing is supposed to appear on the plot, which I couldn't quite figure out.