rshinyplyrr-leaflet

R Shiny Leaflet - clearShapes() not working?


I have a dataset (tst_geo.csv) of the form:

lat, lon, time
10, 20, 1
10, 20, 2
10, 20, 3
40, 40, 4
40, 40, 5
40, 40, 6
0, 0, 7
0, 0, 8
0, 0, 9

R code:

library(shiny)
library(leaflet)
library(plyr)

ui <- fluidPage(
    sidebarLayout(
        
        sidebarPanel(
            uiOutput("slider")
        ),
        mainPanel(
            leafletOutput("map")
        )
    )
)

server <- function(input, output, session){
    
    df <- read.csv("tst_geo.csv", header=TRUE)
    df['time'] <- as.numeric(df$time)
    
    #make dynamic slider
    output$slider <- renderUI({
        sliderInput("time_span", "Time Span", step=1, min=min(df$time), 
                    max=max(df$time), value = c(min(df$time), max(df$time)))
    })
    
    filter_df <- reactive({
        df[df$time >= input$time_span[1] & df$time <= input$time_span[2], ]
    })
    
    output$map <- renderLeaflet(
        leaflet() %>% addTiles()
    )
    
    observe({
        points_df <- ddply(filter_df(), c("lat", "lon"), summarise, count = length(timestamp))
        cat(nrow(points_df))
        leafletProxy("map", data = points_df) %>% clearShapes() %>% addCircles()
    })
    
}

shinyApp(ui, server)

I have a slider to only show points within a certain time range.

However, inside the observe function the points are not being cleared when I call clearShapes().

Do you have any ideas why this is happening?


Solution

  • The culprit is renderUI() in this case. Because you used renderUI(), the rendering of the slider is delayed. By the time the observer runs for the first time, the slider is not there yet, and input$time_span is initially NULL, so filter_df() returns an empty data frame. I don't see a particular reason of using renderUI() in this case (perhaps you have a reason), and you can either just move sliderInput() to ui.R, or check if (is.null(input$time_span)) before you add circles to the map, or change observe() to observeEvent() (if you are using a recent version of shiny):

    observeEvent(input$time_span, {
        points_df <- ddply(filter_df(), c("lat", "lon"), summarise, count = length(timestamp))
        cat(nrow(points_df))
        leafletProxy("map", data = points_df) %>% clearShapes() %>% addCircles()
    })