Search code examples
rshinyr-leaflet

How can I use a sliderInput value to select column and use it to change a map?


I'm working with ShinyApps in R. I use and sliderInput which values are between 2010 and 2015 because you select the year. My data is like:

> data     
     nomMun    2010 2011 2012 2013 2014 2015  lon   lat
1    ABRERA     0    0    5    3    2    0    1.12  40.1
2    AGER       2    0    1    1    0    0    1.54  40.2
3    AGRAMUNT   1    1    0    2    0    1    1.36  40.3

I want to use the column which name is the same that the input value (like data$2010 if slider value is 2010). I need to select the value of this column to indicate the radius of the circle that I add in the map too.

 output$MapPlot1<-renderLeaflet({
 any<-input$any1
 content<-paste(data$nomMun,paste("Accidents",data$any))
 leaflet(data) %>% addTiles() %>%
  addCircles(lng = ~lon, lat = ~lat, weight = 1, stroke=TRUE,radius = 
  ~sqrt(any)*100,popup = content, fillOpacity = 0.2)
 })

Solution

  • You can select it with [[ after converting the numeric value to character:

    addCircles(
        lng         = ~lon
      , lat         = ~lat
      , weight      = 1
      , stroke      = TRUE
      , radius      = ~sqrt(data[[paste0(input$any1)]])*1000
      , popup       = paste(data$nomMun, paste("Accidents", data[[paste0(any)]]))
      , fillOpacity = 0.2
    )
    

    A better way

    A better way would be to melt the data so you filter on a year column, that way you always reference the same column in the leaflet functions, and the data drives the differences.

    library("shiny")
    library("data.table")
    library("purrr")
    library("leaflet")
    
    data <- fread('nomMun,2010,2011,2012,2013,2014,2015,lon,lat
    ABRERA,0,0,5,3,2,0,1.12,40.1
    AGER,2,0,1,1,0,0,1.54,40.2
    AGRAMUNT,1,1,0,2,0,1,1.36,40.3', sep = ",", header = TRUE)
    
    # set any 0 values to NA so they'll be dropped when we convert to long form
    data[data == 0] <- NA
    
    molten_data <- melt.data.table(
        data            = data
      , id.vars         = c("nomMun", "lon", "lat")
      , variable.name   = "year"
      , variable.factor = FALSE
      , na.rm           = TRUE 
    )
    
    molten_data[, `:=`(
        year    = as.integer(year)
      , content = paste(nomMun, paste("Accidents", value))
    )]
    
    year_range <- range(molten_data$year)
    
    
    ui <- fluidPage(
    
      sliderInput(
          inputId = "any1"
        , label   = "Year"
        , min     = year_range[1]
        , max     = year_range[2]
        , value   = year_range[1]
        , step    = 1
        , sep     = ""
      )
      , leafletOutput("MapPlot1")
    
    )
    
    server <- function(input, output, session) {
    
      year_data <- reactive({
        molten_data[year == input$any1]
      })
    
      output$MapPlot1 <- renderLeaflet({
    
        year_data() %>%
          leaflet() %>% 
          addTiles() %>%
          addCircles(
              lng         = ~lon
            , lat         = ~lat
            , weight      = 1
            , stroke      = TRUE
            , radius      = ~sqrt(value)*1000
            , popup       = ~content
            , fillOpacity = 0.2
          )
    
      })
    
    }
    
    shinyApp(ui, server)
    

    enter image description here