7

I have a layer of CircleMarkers and I am trying to remove only the markers that have a certain layerId. The id's for these circle markers are in a dataframe. In reality I have millions of id's whose subset to visualize depends on a different dataset which can change over time. So I need a dynamic way to delete specific layerId's.

Below is a simple example: Suppose I have a dataframe with 3 rows with id's 1, 2 and 3. I tried to make a checkboxInput with the options to delete id's 1 and 2 or 3.

Below the inputs will trigger an ObserveEvent that use the removeMarker function. However, nothing happens. I have tried a million ways to enter the id's into the removeMarker and I have also tried several of the other ways to deletion. Either nothing happens or all disappear. I need a way to delete specific markers. Note that this in no way reflects my real life example: I have millions of points and deletion of points is not through a direct checkbox input, but based on a different dataset that can change over time.

 ui <- shinyUI(fluidPage(
sidebarLayout(
    sidebarPanel(
        checkboxInput("delete1", "Delete ID=1 and 2",value=FALSE),
    checkboxInput("delete3", "Delete ID=3",value=FALSE)
    ),
    mainPanel(
        leafletOutput("map")
    )
)
))

df <- data.frame(id=c(1,2,3),lng = rnorm(3, -106.1039361, 0.5) ,
              lat = rnorm(3, 50.543981, 0.5))

server <- shinyServer(function(input, output, session) {

output$map <- renderLeaflet(
    leaflet() %>% 
addTiles() %>% addCircleMarkers(layerId=df$id,df$lng,df$lat, group='marker', radius=2, fill = TRUE,color='red') 


    )

observeEvent(input$delete1, {
    proxy <- leafletProxy('map')
    if (input$delete1){ proxy %>% removeMarker(df[1:2,1])
 }
 })

observeEvent(input$delete3, {
    proxy <- leafletProxy('map')
    if (input$delete3){ proxy %>% removeMarker(3)}
   })
})

 shinyApp(ui, server)

1 Answer 1

6

The id column of the data.frame must be of class character or factor. I modified the id vector when creating the data.frame. Try the working code below. You will be able to add and remove markers when check/uncheck the checkboxes.

# Load libraries
library("leaflet")

ui <- shinyUI(fluidPage(sidebarLayout(
  sidebarPanel(
    checkboxInput("delete1", "Delete ID=1 and ID=2", value = FALSE),
    checkboxInput("delete3", "Delete ID=3", value = FALSE)
  ),
  mainPanel(leafletOutput("map"))
)))

# ID must be a character
df <- data.frame(
  id = as.character(c(1, 2, 3)),
  lng = rnorm(3, -106.1039361, 0.5),
  lat = rnorm(3, 50.543981, 0.5)
)

server <- shinyServer(function(input, output, session) {

  output$map <- renderLeaflet(
    leaflet() %>%
      addTiles() %>% addCircleMarkers(
        layerId = df$id,
        df$lng,
        df$lat,
        group = 'marker',
        radius = 2,
        fill = TRUE,
        color = 'red'
      )
  )

  observeEvent(input$delete1, {

    proxy <- leafletProxy('map')

    if (input$delete1) {
      proxy %>% removeMarker(layerId = df$id[1:2])
    }

    if (!input$delete1) {
      proxy %>% addCircleMarkers(
        layerId = df$id[1:2],
        df$lng[1:2],
        df$lat[1:2],
        group = 'marker',
        radius = 2,
        fill = TRUE,
        color = 'red'
      )
    }

  })

  observeEvent(input$delete3, {
    proxy <- leafletProxy('map')

    if (input$delete3) {
      proxy %>% removeMarker(layerId = df$id[3])
    }

    if (!input$delete3) {
      proxy %>% addCircleMarkers(
        layerId = df$id[3],
        df$lng[3],
        df$lat[3],
        group = 'marker',
        radius = 2,
        fill = TRUE,
        color = 'red'
      )
    }

  })
})

shinyApp(ui, server)

Edit1:

Based on Cluster markers

# Load libraries
library("leaflet")

ui <- shinyUI(fluidPage(sidebarLayout(
  sidebarPanel(
    hr(),
    h4("Remove points"),
    checkboxGroupInput(
      inputId = "removeFromMap",
      label = "",
      choices = c(1:6)
    ),
    p("Cluster1 = 1,2,3"),
    p("Cluster2 = 4,5,6"),
    hr(),
    p("Checked = removed"),
    p("Unchecked = present")
  ),
  mainPanel(leafletOutput("map"))
)))

# ID must be a character
df <- data.frame(
  id = as.character(1:6),
  lng = rnorm(6, -106.1039361, 0.5),
  lat = rnorm(6, 50.543981, 0.5)
)

server <- shinyServer(function(input, output, session) {
  output$map <- renderLeaflet(
    leaflet() %>%
      setView(-106.1039361, 50.543981, zoom = 5) %>%
      addTiles() %>%

      addCircleMarkers(
        layerId = df$id[1:3],
        df$lng[1:3],
        df$lat[1:3],
        group = 'marker',
        radius = 3,
        fill = TRUE,
        color = '#EF2929',
        clusterId = "Cluster1",
        clusterOptions = markerClusterOptions()
      ) %>%

      addCircleMarkers(
        layerId = df$id[4:6],
        df$lng[4:6],
        df$lat[4:6],
        group = 'marker',
        radius = 3,
        fill = TRUE,
        color = '#729FCF',
        clusterId = "Cluster2",
        clusterOptions = markerClusterOptions()
      )
  )

# Global ID vector
ids <- df$id

# Remove points
  observeEvent(input$removeFromMap, {
    checkedPoints <- input$removeFromMap
    checkedPoints <- checkedPoints[which(checkedPoints %in% ids)]

proxy <- leafletProxy('map')

if (length(checkedPoints) != 0) {
  if (any(checkedPoints %in% as.character(1:3))) {
    pointsC1 <- checkedPoints[which(checkedPoints %in% ids)]
    proxy %>% removeMarkerFromCluster(layerId = pointsC1, clusterId = "Cluster1")
    ids <<- ids[-which(ids == pointsC1)]

  }

  if (any(checkedPoints %in% as.character(4:6))) {
    pointsC2 <- checkedPoints[which(checkedPoints %in% ids)]
    proxy %>% removeMarkerFromCluster(layerId = pointsC2, clusterId = "Cluster2")
    ids <<- ids[-which(ids == pointsC2)]

  }
}

  })

})

shinyApp(ui, server)

map

2
  • It turns out that the mistake in my real code was not the character vector, but that I had the clusterOptions on markerClusterOptions. Is there any way I can removeMarkers while still allowing for clustering?
    – DS501
    Commented Apr 25, 2017 at 14:40
  • 1
    @DS501 I have edited my answer to use Markers in a Cluster
    – Guz
    Commented Apr 25, 2017 at 19:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.