【问题标题】:Remove specific leaflet Markers in R shiny.删除 R 闪亮中的特定传单标记。
【发布时间】:2017-04-24 19:24:58
【问题描述】:

我有一层 CircleMarkers,我试图只删除具有特定 layerId 的标记。这些圆形标记的 id 位于数据框中。

下面是一个简单的例子: 假设我有一个包含 3 行的数据框,其中 id 为 1、2 和 3。我尝试制作一个带有删除 id 1 和 2 或 3 的选项的 checkboxInput。

输入下方将触发使用 removeMarker 函数的 ObserveEvent。然而,什么也没有发生。我已经尝试了一百万种方法将 id 输入到 removeMarker 中,我还尝试了其他几种删除方法。要么什么都没有发生,要么全部消失。我需要一种删除特定标记的方法。

 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)

【问题讨论】:

    标签: r shiny leaflet marker


    【解决方案1】:

    由于某种原因,如果addCirleMarkersremoveMarker 中的layerId 是字符,则可以尝试在服务器部分:

    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")}
      })
    
    })
    

    【讨论】:

      【解决方案2】:

      您可以执行以下操作,但如果您取消选中该框,您现在设置的方式不会将标记放回原处。

      server <- shinyServer(function(input, output, session) {
      
          output$map <- renderLeaflet(
            leaflet() %>% 
            addTiles() %>%
      
            # Add circle markers in different groups
            addCircleMarkers(layerId=df$id[1:2], df$lng[1:2], df$lat[1:2], group='one', radius=2, fill = TRUE,color='red') %>%
            addCircleMarkers(layerId=df$id[3], df$lng[3], df$lat[3], group='two', radius=2, fill = TRUE,color='red') 
          )
      
          # Remove group 'one'
          observeEvent(input$delete1, {
            proxy <- leafletProxy('map')
            if (input$delete1){ proxy %>% clearGroup(group = "one")}
          })
      
          # Remove group 'two'
          observeEvent(input$delete3, {
            proxy <- leafletProxy('map')
            if (input$delete3){ proxy %>% clearGroup(group = "two")}
          })
      })
      
       shinyApp(ui, server)
      

      【讨论】:

      • 该示例适用于 3 个 id,并表明有时我必须添加/删除分组数据。真正的问题有大约一百万个 id,所以我希望避免将它们放在不同的组中。
      • 在您的示例中,即使您不这样称呼它们,您也将它们分组。 removeMarker(df[1:2,1]) 将 ID 1 和 2 组合在一起。如果您通过数据框中的某个变量将它们分组在一起,那么您可以使用我在其他答案中展示的selectInput 想法避免大量重复代码(必须为每个组使用新的observeEvent)。
      【解决方案3】:

      我认为对 ID 进行分组仍然是可行的方法。然后可以将该分组变量添加到您的数据框中,您可以使用它来切换显示/隐藏点,如下所示。这实际上与您最初尝试的没有任何不同,因为您仍然必须明确确定要删除的 ID。您仍然必须这样做,但现在您必须将它们放在已定义的组中。

      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)
      

      您可以使用的另一个想法是,而不是 checkboxInputselectInput,您可以在其中一次选择多个。这将节省每个组的observeEvents。如下所示。我将其设置为默认显示所有点,如果您选择一个组,它会将其从图中删除。

      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)
      

      【讨论】:

        猜你喜欢
        • 2018-03-13
        • 2015-05-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多