Leaflet removeMarker by non-index layerId

I've seen a lot of examples of leaflet apps that removeMarkers by a layerId that is assigned from the dataframe index, but if the layerId is assigned from an arbitrary unique identifier, it doesn't seem to work. Has anyone else had any luck manipulating individual layers with ids that are not the index? Below is my reprex

# Quake Map Marker Removal
library(shiny)
library(leaflet)
library(tidyverse)

ui <- fluidPage(
    fluidRow(
        column(
            width = 12,
            verbatimTextOutput("clicked_id"),
            leafletOutput("map")
        )
    )
)

server <- function(input, output, session) {
    
    # create quake tibble with quake_id column
    # randomly select 20 quakes to reduce number of markers
    quake_df <- as_tibble(quakes) %>% 
        mutate(quake_id = sample(1000:99999, nrow(.))) %>% 
        .[sample(1:nrow(.), 20), ]

    # in the interest of illustrating the point the dataframe below
    # generates the desired outcome because the layerId comes 
    # from the dataframe index
    #
    # quake_df <- quakes[sample(1:nrow(quakes), 20), ] %>% 
    #     as_tibble(rownames = "quake_id")

    
    # create quake map with markers 
    output$map <- renderLeaflet(
        leaflet(data = quake_df) %>% 
            addProviderTiles(providers$Esri.WorldGrayCanvas) %>% 
            addCircleMarkers(
                lng = ~long,
                lat = ~lat,
                layerId = ~quake_id,
                stroke = FALSE,
                radius = 6,
                fillOpacity = 0.5
            )
    )
    
    # display the layerId of the clicked marker
    output$clicked_id <- renderPrint({
        if (!is.null(input$map_marker_click)) {
            print(paste("Tried to remove quake_id",input$map_marker_click$id))
        }
    })
    
    # attempt to remove the clicked marker
    observeEvent(input$map_marker_click, {
        leafletProxy("map") %>% 
            removeMarker(layerId = input$map_marker_click$id)
    })
}

shinyApp(ui = ui, server = server)

I noticed in the example that works, the quake_id is a character vector. If you convert your original quake_id to be a character, it should work:

# Quake Map Marker Removal
library(shiny)
library(leaflet)
library(tidyverse)

ui <- fluidPage(
  fluidRow(
    column(
      width = 12,
      verbatimTextOutput("clicked_id"),
      leafletOutput("map")
    )
  )
)

server <- function(input, output, session) {
  
  # create quake tibble with quake_id column
  # randomly select 20 quakes to reduce number of markers
  quake_df <- as_tibble(quakes) %>%
    mutate(quake_id = as.character(sample(1000:99999, nrow(.)))) %>%
    .[sample(1:nrow(.), 20), ]
  
  # in the interest of illustrating the point the dataframe below
  # generates the desired outcome because the layerId comes 
  # from the dataframe index
  #
  # quake_df <- quakes[sample(1:nrow(quakes), 20), ] %>%
  #     as_tibble(rownames = "quake_id")
  
  
  # create quake map with markers 
  output$map <- renderLeaflet(
    leaflet(data = quake_df) %>% 
      addProviderTiles(providers$Esri.WorldGrayCanvas) %>% 
      addCircleMarkers(
        lng = ~long,
        lat = ~lat,
        layerId = ~quake_id,
        stroke = FALSE,
        radius = 6,
        fillOpacity = 0.5
      )
  )
  
  # display the layerId of the clicked marker
  output$clicked_id <- renderPrint({
    if (!is.null(input$map_marker_click)) {
      print(paste("Tried to remove quake_id",input$map_marker_click$id))
    }
  })
  
  # attempt to remove the clicked marker
  observeEvent(input$map_marker_click, {
    leafletProxy("map") %>% 
      removeMarker(layerId = input$map_marker_click$id)
  })
}

shinyApp(ui = ui, server = server)
1 Like

So it's a vector class issue...leaflet assigns layerIds as character values, which is what the index becomes in the course of generating a new column using the rownames argument in as_tibble. Thanks a bunch Michael.

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.