glor
glor

Reputation: 109

Shiny selecting ranges and numeric variable (as inputs) with leaflet

On shiny, I would like to show a list of numerical variables and a slide bar so that a user could choose a numerical variable and a range. Then, observations below that number would show up as green, and observations between that range would be orange, and observations above that range would be red.

The codes below work fine before I put them into shiny. But my shiny codes don't work and all observations are red.

library(Rcpp)
library(ggmap)
library(htmlwidgets)
library(leaflet)

crime2 <- crime[1:50,]

getColor <- function(crime2) {
 sapply(crime2$hour, function(hour) {
 if(hour< 1) {
   "green"
 } else if(hour <= 1) {
   "orange"
 } else {
   "red"
  } })
}

icons <- awesomeIcons(
  icon = 'ios-close',
  iconColor = 'black',
  library = 'ion',
  markerColor = getColor(crime2)
)

leaflet(crime2) %>%
  addTiles() %>%
  addAwesomeMarkers(~lon, ~lat, icon=icons)

This is the shiny code that doesn't work

ui <- fluidPage(
  titlePanel("Unusual Observations"),

  sidebarLayout(
    sidebarPanel(
      helpText("Create maps with 
        information from the Crime Data"),
  
      selectInput("var", 
                  label = "Choose a variable to display",
                  choices = c("Hour",
                              "Number"),
                  selected = "Hour"),
  
      sliderInput("range", 
                  label = "Range of interest:",
                  min = 0, max = 10, value = c(1, 2))
    ),

    mainPanel(leafletOutput("map"))
  )
)


server <- function(input, output) {
  output$map <- renderLeaflet({
    data <- switch(input$var,
                   "hour" = crime2$hour,
                   "number" = crime2$number)

    getColor <- function(data){sapply(data, function(var){
       if(input$var< input$range[1]) {
         "green"
       } else if(input$var <= input$range[2]) {
         "orange"
       } else {
         "red"
        } })
    }

  icons <- awesomeIcons(
  icon = 'ios-close',
  iconColor = 'black',
  library = 'ion',
  markerColor = getColor(crime2)
)

    leaflet(crime2) %>%
  addTiles() %>%
  addAwesomeMarkers(~lon, ~lat, icon=icons)

  })
}

shinyApp(ui=ui, server=server)

Does anyone know how to fix 'all points showing up as red' problem?

Upvotes: 0

Views: 840

Answers (1)

Wil
Wil

Reputation: 3188

A few changes:

  1. When you create the selectInput the choices (and selected) need to be lowercase to match the column names in crime2.

    selectInput("var", 
                  label = "Choose a variable to display",
                  choices = c("hour",
                              "number"),
                  selected = "hour"),
    
  2. Inside of your getColor function you want to loop over the values in data, not input$var, so you should call var rather than input$var inside the lambda function.

    getColor <- function(data){sapply(data, function(var){
          if(var< input$range[1]) {
            "green"
          } else if(var <= input$range[2]) {
            "orange"
          } else {
            "red"
          } })
        }
    
  3. When you actually go to create your icons, you want them to be created based on the values in data, not the values in the entire crime2 dataset.

    icons <- awesomeIcons(
          icon = 'ios-close',
          iconColor = 'black',
          library = 'ion',
          markerColor = getColor(data)
        )
    

Putting it all together:

ui <- fluidPage(
  titlePanel("Unusual Observations"),

  sidebarLayout(
    sidebarPanel(
      helpText("Create maps with 
        information from the Crime Data"),

      selectInput("var", 
                  label = "Choose a variable to display",
                  choices = c("hour",
                              "number"),
                  selected = "hour"),

      sliderInput("range", 
                  label = "Range of interest:",
                  min = 0, max = 10, value = c(1, 2))
    ),

    mainPanel(leafletOutput("map"))
  )
)


server <- function(input, output) {
  output$map <- renderLeaflet({
    data <- switch(input$var,
                   "hour" = crime2$hour,
                   "number" = crime2$number)

    getColor <- function(data){sapply(data, function(var){
      if(var< input$range[1]) {
        "green"
      } else if(var <= input$range[2]) {
        "orange"
      } else {
        "red"
      } })
    }

    icons <- awesomeIcons(
      icon = 'ios-close',
      iconColor = 'black',
      library = 'ion',
      markerColor = getColor(data)
    )

    leaflet(crime2) %>%
      addTiles() %>%
      addAwesomeMarkers(~lon, ~lat, icon=icons)

  })
}

shinyApp(ui=ui, server=server)

Upvotes: 1

Related Questions