ChMoe ChMoe - 1 year ago 146
R Question

Filter map using Leaflet and Shiny in R - multiple value attributes

I am trying to filter points on a map based on attributes. It works fine as long as one attribute contains only one value. In case that one attribute has multiple values (i.e. "water;sand") I am not able to map this point based on the filter.

Here is my minimum example:



library(data.table)
mydat <- data.table( londd=c(20, 38, 96, 32),
latdd=c(60, 56, 30, 31),
art=c("mountain", "water,sand", "sand", "forest"),
anwendung=c("a","b","c","d"))

#Set up ui
ui <- shinyUI(fluidPage(
sidebarPanel(h5("", width=2),
checkboxGroupInput(inputId="ArtFlag", label=h4("Art des Bodens"),
choices=setNames(object=c("mountain", "water", "sand", "forest"),
nm=c("mountain", "water", "sand", "forest"))),
checkboxGroupInput(inputId="AnwendungFlag", label=h4("Anwendung"),
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(mydat[art%in%input$ArtFlag & anwendung%in%input$AnwendungFlag])

#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)


I am sorry if my coding is not well formatted. I am still a beginner.

Thanks a lot,

Christina

Sam Sam
Answer Source

Well, I'm not 100% sure this solves what you're looking for, so please leave a comment if it doesn't. Your problem is in your reactive statement - you don't have a checkbox for "water,sand", so you'll never get a match for checkbox B. To get a match for checkbox B regardless of if water or sand was selected, I tried this, using grepl to get a pattern match, rather than an exact match. Try changing your datFilt call to this:

  #Filter data
  datFilt <- reactive({

    filterName <- ifelse(length(input$ArtFlag) == 0, 'none', input$ArtFlag)

    mydat[grepl(filterName, art) & anwendung%in%input$AnwendungFlag]
    })

(This is probably not the most efficient code to do this, but hopefully it will either work or get you closer to what you're looking for. In a perfect world, it might be easier to code for this if the structure of your data was different, but not sure if that's an option for you or not)

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download