Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

filtering and selecting points in R shiny and leaflet

Tags:

r

shiny

r-leaflet

I have a bunch of points on a map with some associated data.

First, I want to filter those points by their attributes. That works fine, but recently when I run the app and fiddle with the filters, eventually it stops removing the previously filtered points and just loads the newly filtered points on top. This has been happening after about 10 adjustments to the filter. It is as if the clearMarkers() function stops working. The filtered data will also show up in a reactive data.table (that part works fine, didn't include it in the example).

Second, I want to click on points to select them. Data from the selected points will go in to some graphs later. I can definitely select one point, but I am having trouble keeping a reactive variable of all clicked points. Also, a selected point should become unselected if clicked again. The selected points will be highlighted on the map (by adding bigger brighter markers on them), and in the reactive data.table, and the selection should update following clicks in the map and clicks in the table. But that is a few steps down the line.

Here is some sample code, which does not work.

library(sp)
library(leaflet)
library(shiny)

data <- data.frame(x = c(10,20,30,10,40), y = c(20,20,10,30,30), z = c(1,2,3,4,5))
points <- SpatialPointsDataFrame(data[,1:2],data[3])

server <- function(input, output, session) {
  filtered <- reactive({
    z.in <- input$z
    points[points@data$z > z.in,]
  })
  selected <- reactiveValues()
  output$map <- renderLeaflet({leaflet()})
  observe({ # This observer works, but it seems to stop working about about 10 tries
    leafletProxy("map") %>%
      clearMarkers() %>%
      addCircleMarkers(data = filtered())
  })
  observe({ # This observer does not work, and the app won't run unless you comment it out
    clicked <- unlist(input$map_marker_click[3:4])
    if (is.na(clicked)) {selected <- clicked}
    else if (clicked %in% selected) {selected <- selected[-clicked]}
    else {selected <- append(selected, clicked)}
  })
}

ui <- bootstrapPage(
  tags$style(type = "text/css", "html, body {width:100%;height:100%}"),
  leafletOutput("map", width = "100%", height = "100%"), 
  absolutePanel(top = 10,left = 10,
                sliderInput("z", "z",0,6,0)
  ))

shinyApp(ui = ui, server = server)
like image 809
Alex P Avatar asked Sep 06 '25 03:09

Alex P


1 Answers

The crosstalk package addresses this.

https://rstudio.github.io/crosstalk/

like image 74
Alex P Avatar answered Sep 07 '25 20:09

Alex P