Unable to create a leaflet map which shows locations of incidents

leaflet
r

#1

I have been trying to create a leaflet map which shows locations of incidents. But so far I haven't been able to create it. The map should react to the variables - 'Date' and 'On_site' present on the sidebar panel. Here, On_site takes only binary values: True/False

Dataframe contains the following variables: incident_number, Address, latitude, longitude, Date, On_site

ui.R

library(shiny)
library(leaflet)
library(tidyverse)
library(DT)
library(dplyr)

# Dataframe
 incident <- read.csv('incident.csv')

ui <- fluidPage(

      br(),

      # Sidebar layout with a input and output definitions 
      sidebarLayout(

        # Inputs:
        sidebarPanel(

          # Text instructions
          HTML(paste("Customize the map by:")),

          dateInput("Date", label = "Date", value = "10/15/2018",
                    min = "2018-10-03", max = "2018-11-01"),
          hr(),
          fluidRow(column(3, verbatimTextOutput("value"))),

          selectInput("On_site", label = "On site",
                      choices = unique(incident$On_site)),


        ),
        # Outputs:
        mainPanel(

          # leaflet map
          leafletOutput("mymap"),
          # Show data table
          dataTableOutput(outputId = "incident_table"),
          br()
        )
      )
    )

server.R

# Define server function 
server <- function(input, output) {

  # Create map
  filtered <- reactive({
    incident %>% 
      filter(Date == input$Date & On_site == input$On_site)
  })

  output$mymap <- renderLeaflet({ 
    leaflet() %>% addTiles() %>%
    addProviderTiles(providers$Esri.NatGeoWorldMap) %>%
    fitBounds(~min(longitude), ~min(latitude), ~max(longitude), ~max(latitude))
  }) 

  observe({
    leafletProxy("mymap") %>%
      clearShapes()%>%
      clearPopups()%>%
      clearMarkers()%>%
      addMarkers(lat = filtered()$latitude,
                 lng = filtered()$longitude,
                 popup = ~paste0("<strong>", filtered()$incident_number, "</strong><br/>","On_site: ", filtered()$On_site, "<br />")
      )
  })

# Create data table 
output$incident_detail <- DT::renderDataTable({
filtered()
  })
}

# Create a Shiny app object
shinyApp(ui = ui, server = server)  

First few records of dataframe:
incident_number Address On_site Date latitude longitude
18-92482 SOUTHWEST FALSE 10/15/2018 32.70580 -97.43445
18-92362 TRINITY TRUE 10/15/2018 32.80217 -97.16269
18-91851 28TH FALSE 10/13/2018 32.79703 -97.37375
18-92375 ALTAMESA TRUE 10/15/2018 32.65049 -97.37472
18-92078 ALTA MERE FALSE 10/14/2018 32.72180 -97.44170
180092437 CRYSTAL LAKE TRUE 10/15/2018 32.85138 -97.40293
18-92344 LOOP 820 SOUTH FALSE 10/15/2018 0.00000 0.00000
18-92441 BEACH FALSE 10/15/2018 32.76173 -97.28770
18-92132 IH 20 WB GRANBURY FALSE 10/14/2018 32.67281 -97.37544
18-92368 JACKSBORO TRUE 10/15/2018 32.78689 -97.38503

I know that there is something not right in the server function. It would be great if anyone can figure it out.

Thanks!


#2

Hi @prt001

I've made an app.R with your code above. I've added comments marked with ### on changes that I've made.

Main ideas:

  • Make sure to include the data if you use a formula in leaflet
  • If you have new data to be used right away, don't use a formula. Just supply it directly
  • Make sure your output names match your UI names

- Barret

app.R

library(shiny)
library(leaflet)
library(tidyverse)
library(DT)
library(dplyr)

incident <- read.csv(textConnection(
"incident_number, Address, On_site, Date, latitude, longitude
18-92482, SOUTHWEST, FALSE, 10/15/2018, 32.70580, -97.43445
18-92362, TRINITY, TRUE, 10/15/2018, 32.80217, -97.16269
18-91851, 28TH, FALSE, 10/13/2018, 32.79703, -97.37375
18-92375, ALTAMESA, TRUE, 10/15/2018, 32.65049, -97.37472
18-92078, ALTA MERE, FALSE, 10/14/2018, 32.72180, -97.44170
18-92437, CRYSTAL LAKE, TRUE, 10/15/2018, 32.85138, -97.40293
18-92344, LOOP 820 SOUTH, FALSE, 10/15/2018, 0.00000, 0.00000
18-92441, BEACH, FALSE, 10/15/2018, 32.76173, -97.28770
18-92132, IH 20 WB GRANBURY, FALSE, 10/14/2018, 32.67281, -97.37544
18-92368, JACKSBORO, TRUE, 10/15/2018, 32.78689, -97.38503
")) %>%
  mutate(
    Date = as.Date(Date, format = "%m/%d/%Y")
  )

ui <- fluidPage(
  # Sidebar layout with a input and output definitions
  sidebarLayout(

    # Inputs:
    sidebarPanel(

      # Text instructions
      HTML(paste("Customize the map by:")),

      dateInput("Date", label = "Date", value = "10/15/2018",
                min = "2018-10-03", max = "2018-11-01"),
      hr(),
      fluidRow(column(3, verbatimTextOutput("value"))),

      selectInput("On_site", label = "On site",
                  choices = unique(incident$On_site))


    ),
    # Outputs:
    mainPanel(

      # leaflet map
      leafletOutput("mymap"),
      # Show data table
      dataTableOutput(outputId = "incident_table"),
      br()
    )
  )
)

# Define server function
server <- function(input, output) {

  # Create map
  filtered <- reactive({
    incident %>%
      filter(On_site == input$On_site, Date == input$Date)
  })

  output$mymap <- renderLeaflet({
    ### add the data frame so the fomulas below know where to pull data from
    leaflet(incident) %>%
      addTiles() %>%
      addProviderTiles(providers$Esri.NatGeoWorldMap) %>%
      fitBounds(~min(longitude), ~min(latitude), ~max(longitude), ~max(latitude))
  })

  observe({
    str(filtered())
    leafletProxy("mymap") %>%
      clearShapes() %>%
      clearPopups() %>%
      clearMarkers() %>%
      addMarkers(lat = filtered()$latitude,
                 lng = filtered()$longitude,
                 ### since you have the full data, no need to make a formula
                 popup = paste0("<strong>", filtered()$incident_number, "</strong><br/>","On_site: ", filtered()$On_site, "<br />")
      )
  })

  # Create data table
  ### make sure the output name matches the UI name
  output$incident_table <- DT::renderDataTable({
    filtered()
  })
}

# Create a Shiny app object
shinyApp(ui = ui, server = server)