Search code examples
rshinyr-leaflet

Server Won't Change Map Output


I'm new to making maps with Shiny but my goal is to create an interactive map that changes when you select various inputs. For example: when you select the month, it will only display markers from that given month. When you select the year it will display observations from that year AND month (and so on).

Right now I am able to get my map to render but the points that appear on the map do not correspond with what the user selects in the drop down options.

Here is the code I have tried:

library(shiny)
library(dplyr)
library(leaflet)

SampleData <- data.frame(year = c('2017', '2018', '2019', '2020'),
                         lon = c(38.62893, 38.62681, 38.62797, 38.62972),
                         lat = c(-90.26233, -90.25272, -90.26232, -90.25703),
                         month = c('January', 'February', 'March', 'April', 'May'),
                         new_use = c('Industrial', 'Institutional', 'Commercial', 'Residential')

use <- sort(unique(SampleData$new_use))
years <- sort(unique(SampleData$year))
months <- sort(unique(SampleData$month))

ui <- bootstrapPage(
    tags$style(type = "text/css", "html, body {width:100%;height:100%}"),
    leafletOutput("map", width = "100%", height = "100%"),
    absolutePanel(top = 10, right = 10,
                  selectInput("month", "Month",
                              choices = sort(unique(SampleData$month))),
                  selectInput("year", "Year",
                              choices = sort(unique(SampleData$year))),
                  selectInput("new_use", "Permit Use",
                              choices = sort(unique(SampleData$new_use))),
    )
)

server <- function(input, output, session) {
    
    output$map <- renderLeaflet({
        leaflet() %>% 
            setView(lng = -90.1994, lat = 38.6270, zoom = 10)%>%
            addProviderTiles(providers$CartoDB.Positron)
    })
    
    # Reactive expression for the data subsetted to what the user selected
    filteredData <- reactive({
        dplyr::filter(SampleData, years %in% input$year & use %in% input$new_use & months %in% input$month)
    })
  
observe({
        leafletProxy("map") %>%
            clearShapes() %>%
            addMarkers(data = filteredData(), 
             ~lat, ~lon, popup = paste("<b>Year:</b> ", filteredData()$year, "<br>",
                  "<b>Permit Type:</b> ", filteredData()$new_use, "<br>")) 
    })
}    
    


shinyApp(ui, server)

Does anyone have any suggestions? What am I missing?


Solution

  • The filtering in the reactive statement needs to be done by the column names in the data frame. For example, you need 'year' not 'years'.

    So the reactive statement should read:

    filteredData <- reactive({
            dplyr::filter(SampleData, year %in% input$year & new_use %in% input$new_use & month %in% input$month)
        })
    

    And to clear the previous markers you want to use clearMarkers() not clearShapes().

    However with the sample dataframe provided, a marker will only appear when a specific combination year, month and use are selected (this is after removing 'May' to make all the columns the same length). For example, the first marker will only show when '2017', 'January' and 'Industrial' are all selected by the user as these are the corresponding values associated with the first pair of coordinates (and so on).