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.
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.
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)
For some reason this works if the layerId
in the addCirleMarkers
and in the removeMarker
are characters, you could try, for the server part:
server <- shinyServer(function(input, output, session) {
output$map <- renderLeaflet(
leaflet() %>%
addTiles() %>% addCircleMarkers(layerId=as.character(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(c("1","2"))
}
})
observeEvent(input$delete3, {
proxy <- leafletProxy('map')
if (input$delete3){ proxy %>% removeMarker("3")}
})
})
I think grouping the IDs is still the way to go. That grouping variable can then be added to your data frame and you can use that to toggle showing/hiding the points as I illustrate below. It's really not any different than what you were trying originally because you still had to specifically identify which IDs you wanted to remove. You still have to do that, but now you have to put them in defined groups.
require(shiny)
require(leaflet)
require(dplyr)
ui <- shinyUI(fluidPage(
sidebarLayout(
sidebarPanel(
#Set value = TRUE so points are shown by default
checkboxInput("delete1", "Toggle ID 1 and 2", value = TRUE),
checkboxInput("delete3", "Toggle ID 3", value = TRUE)
),
mainPanel(
leafletOutput("map")
)
)
))
df <- data.frame(
id = c(1,2,3),
#Add grouping variable
group = c("one", "one", "two"),
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() %>%
#Add markers with group
addCircleMarkers(group = df$group, df$lng, df$lat, radius=2, fill = TRUE, color = 'red')
)
observeEvent(input$delete1, {
proxy <- leafletProxy('map')
#Always clear the group first on the observed event
proxy %>% clearGroup(group = "one")
#If checked
if (input$delete1){
#Filter for the specific group
df <- filter(df, group == "one")
#Add the specific group's markers
proxy %>% addCircleMarkers(group = df$group, df$lng, df$lat, radius=2, fill = TRUE, color = 'red')
}
})
#Repeat for the other groups
observeEvent(input$delete3, {
proxy <- leafletProxy('map')
proxy %>% clearGroup(group = "two")
if (input$delete3){
df <- filter(df, group == "two")
proxy %>% addCircleMarkers(group = df$group, df$lng, df$lat, radius=2, fill = TRUE, color = 'red')
}
})
})
shinyApp(ui, server)
Another idea that you could use is instead of a checkboxInput
is a selectInput
where you can select multiples at one. That will save having to observeEvents
for each group. That's shown below. I set it up so it defaults to all points being shown, and if you select a group it removes it from the plot.
require(shiny)
require(leaflet)
require(dplyr)
df <- data.frame(
id = c(1,2,3),
#Add grouping variable
group = c("one", "one", "two"),
lng = rnorm(3, -106.1039361, 0.5) ,
lat = rnorm(3, 50.543981, 0.5)
)
ui <- shinyUI(fluidPage(
sidebarLayout(
sidebarPanel(
#Set value = TRUE so points are shown by default
selectInput("toggle", "Toggle Groups", choices = unique(df$group), multiple = TRUE)
),
mainPanel(
leafletOutput("map")
)
)
))
server <- shinyServer(function(input, output, session) {
output$map <- renderLeaflet(
leaflet() %>%
addTiles() %>%
addCircleMarkers(df$lng, df$lat, radius=2, fill = TRUE, color = 'red')
)
observe({
proxy <- leafletProxy('map')
if(is.null(input$toggle)){
proxy %>% clearMarkers() %>%
addCircleMarkers(df$lng, df$lat, radius=2, fill = TRUE, color = 'red')
} else {
#Always clear the shapes on the observed event
proxy %>% clearMarkers()
#Filter for the specific group
df <- filter(df, !(group %in% input$toggle))
#Add the specific group's markers
proxy %>% addCircleMarkers(group = df$group, df$lng, df$lat, radius=2, fill = TRUE, color = 'red')
}
})
})
shinyApp(ui, server)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With