2016-09-21 93 views
2

我試圖根據兩個類別「材質」和「應用程序」創建過濾器貼圖。用戶可以選擇4種不同的材料和4種不同的應用。一些數據點有多個值(即「水,沙」)。 我有兩個問題掙扎:使用R Leaflet和Shiny(多條件)在地圖上過濾數據點

  1. 兩個點(ID = 2和3)出現在地圖上,如果我選擇的應用程序= c和材料=沙子而不是隻有一個點(ID = 3)。我不知何故必須檢查兩個篩選條件是否分別適用於每個數據點(id),但我無法找到如何執行此操作的信息。

  2. 取決於檢查方塊的順序是否選擇了點。

如果有人能給我一些提示,我會很高興。

這是我最小的例子:

library(data.table) 
library(shiny) 
library(dplyr) 
library(leaflet) 

mydat <- data.table(id=c(1,2,3,4), 
        londd=c(20, 38, 96, 32), 
        latdd=c(60, 56, 30, 31), 
        material=c("stone", "water,sand", "sand", "wood"), 
        application=c("a","b","c","d")) 

#Set up ui 
ui <- shinyUI(fluidPage(
    sidebarPanel(h5("", width=2), 
       checkboxGroupInput(inputId="MatFlag",label=h4("Material"), 
            choices=setNames(object=c("stone","water","sand", "wood"), 
                nm=c("stone", "water", "sand", "wood")), 
       ), 
       checkboxGroupInput(inputId="AppFlag",label=h4("Application"), 
            choices=setNames(object=c("a","b","c","d"), 
                nm=c("a","b","c","d")), 
       ), 
       position="left"), 

    #App mainPanel content and styles 
    mainPanel(fluidRow(leafletOutput(outputId="lmap"))) 
)) 

#Set up server 
server <- function(input, output){ 
    #Build leaflet map 
    lmap <- leaflet(data=mydat)%>% 
    addProviderTiles("Stamen.TonerLite", 
        options =providerTileOptions(noWrap = TRUE)) %>% 
    fitBounds(~min(londd), ~min(latdd), ~max(londd), ~max(latdd)) 

    #Filter data 
    datFilt <- reactive({ 
    filterName <- ifelse(length(input$MatFlag) == 0, 'none', input$MatFlag) 
    mydat[grepl(filterName,material) & input$AppFlag%in%application] 
    }) 

    #Add markers based on selected flags 
    observe({ 
    if(nrow(datFilt())==0) { 
     print("Nothing selected") 
     leafletProxy("lmap") %>% 
     clearShapes()} 
    else{ #print(paste0("Selected: ", unique(input$InFlags&input$InFlags2))) 
     leafletProxy("lmap", data=datFilt()) %>% clearShapes() %>% 
     addCircleMarkers(lng=~londd, lat=~latdd, 
         clusterOptions=markerClusterOptions(), weight=3, 
         color="#33CC33", opacity=1, fillColor="#FF9900", 
         fillOpacity=0.8) %>% clearShapes() 
    } 
    }) 

    output$lmap <- renderLeaflet(lmap) 
} 

#Run app 
shinyApp(ui = ui, server = server) 

回答

0

好了,一對夫婦的問題在這裏:

Grepl不工作,你覺得它的方式 - 像%in%確實無法將兩個向量放在一起比較。您需要先使用|(正則表達式OR)進行concantenate,然後使用grepl。 datFilt應該是:

datFilt <- reactive({ 
    MatSearch <- paste0(c('xxx',input$MatFlag),collapse = "|") 
    MatSearch <- gsub(",","|",MatSearch) 
    mydat[grepl(MatSearch,material) & application %in% input$AppFlag] 
    }) 

下一個問題與clearShapes。首先,沒有理由在addCircleMarkers中調用第二個clearShapes()。如果clearShapes()按預期工作,這實際上只會清除您創建的任何地圖。但是,ClearShapes在MarkerClusters中的工作方式似乎存在一個錯誤 - 與文檔相反,它無法清除它們。使用clearMarkerClusters()做工作:

observe({ 
    if(nrow(datFilt())==0) { 
     print("Nothing selected") 
     leafletProxy("lmap") %>% 
     clearMarkerClusters() 
    } else { #print(paste0("Selected: ", unique(input$InFlags&input$InFlags2))) 
     print("Something Selected") 
     leafletProxy("lmap", data=datFilt()) %>% 
     clearMarkerClusters() %>% 
     addCircleMarkers(lng=~londd, lat=~latdd, 
         clusterOptions=markerClusterOptions(), weight=3, 
         color="#33CC33", opacity=1, fillColor="#FF9900", 
         fillOpacity=0.8) 
    } 
    }) 

底塗到你的代碼,這允許您正在尋找的雙過濾

+0

非常感謝你,克里斯!還有一件事我完全不明白。如果我只選擇一種材料,則不會發生任何事情,但如果我只選擇一個應用程序,則數據點將顯示在地圖上。如果兩個標準都滿足,這個觀點是否可能會出現? – ChMoe

+0

@ChMoe你是完全正確的 - 這是我的代碼中的一個錯誤。如果更改爲'MatSearch < - paste0(c('xxx',輸入$ MatFlag),collapse =「|」)'它應該可以工作 – Chris

+0

是的。非常感謝! – ChMoe

相關問題