[英]Most efficient way to control filtering of points on leaflet map in shiny
I'm developing a shiny
app that features a leaflet
map. 我正在开发一个具有
leaflet
地图的shiny
应用程序。 The source dataset for the map includes latitude, longitude, and several other variables. 地图的源数据集包括纬度,经度和其他几个变量。 I am giving users of the app radio buttons, sliders, checkboxes, etc. which relate to these other variables with the effect of controlling which points appear on the map.
我正在向用户提供与这些其他变量相关的app单选按钮,滑块,复选框等,以控制哪些点出现在地图上。
I am including a basic example of my code below. 我在下面提供了我的代码的基本示例。 I am currently pre-splitting my dataset into subsets which can then be called into
leaflet
via a reactive expression (based on what the user selects). 我目前正在将我的数据集预分割成子集,然后可以通过反应式表达式(基于用户选择的内容)将其调用到
leaflet
。 This is just a simple example with only 4 subsets, so it may not seem bad here. 这只是一个只有4个子集的简单示例,因此在这里看起来可能并不坏。 However, in my actual use case, the potential combinations of filters that the app-user could select will be much more.
但是,在我的实际使用案例中,app-user可以选择的过滤器的潜在组合将更多。
Is it advisable to create ALL the potential sub-datasets that might be filtered to in a Global.R script? 是否建议在Global.R脚本中创建可能被过滤的所有潜在子数据集? Or should filtering be done on the fly within a reactive expression?
或者应该在反应式表达式中即时过滤?
Additionally, is there an alternative to using a giant nested ifelse expression (like the relatively small one I have below)? 另外,有没有替代使用巨大的嵌套ifelse表达式(就像我下面相对较小的表达式)? That has been getting out of hand as I add more user filtering options to my actual app.
当我向我的实际应用添加更多用户过滤选项时,这已经失去控制。 I don't fully understand the order in which a reactive expression is updated, when it could depend on multiple inputs.
我不完全理解反应表达式更新的顺序,它可能依赖于多个输入。
The motivation for my question may be clearer if I shared a giant piece of code with all the filtering permutations, but wanted to provide a simpler example first: 如果我与所有过滤排列共享一大段代码,我的问题的动机可能会更清楚,但是想先提供一个更简单的例子:
library(shiny)
library(leaflet)
library(dplyr)
# Generating dummy data for demonstration
member <- 1:10
lat <- c(39.8, 39.6, 39.7, 39.78, 39.82, 39.74, 39.72, 38.9, 37.43, 38.0)
lon <- c(-86.1, -86.2, -86.3,-86.4,-86.5,-86.6,-86.7,-86.8,-86.9, -87)
group <- c("a","a","a","b","b","a","a","a","b","b")
year <- c(1,0,0,1,0,1,0,0,1,0)
data <- data.frame(member, lat, lon, group, year)
# Creating data subsets for plotting
groupA_y1 <- data %>% filter(group == "a", year == 1)
groupA_y0 <- data %>% filter(group=="a", year == 0)
groupB_y1 <- data %>% filter(group=="b", year == 1)
groupB_y0<-data %>% filter(group=="b", year == 0)
ui <- fluidPage(
leafletOutput("mymap"),
radioButtons("group", "Group:", c("A", "B"), selected = "A"),
radioButtons("year", "Year", c(1,0), selected = 1)
)
server <- function(input, output, session) {
output$mymap <- renderLeaflet({
leaflet() %>%
addProviderTiles("CartoDB.Positron",
options = providerTileOptions(noWrap = TRUE)) %>%
setView(lng = -85.00, lat = 39.00, zoom = 6)
})
zerg <-reactive({
test<-ifelse(input$group=="A" & input$year==1, return(groupA_y1),
ifelse(input$group=="A" & input$year==0, return(groupA_y0),
ifelse(input$group=="B" & input$year==1, return(groupB_y1),
return(groupB_y0))))
return(test)
})
observe({
dataset<- zerg()
leafletProxy("mymap", data = dataset) %>%
clearMarkers() %>%
addCircleMarkers(~lon, ~lat, layerId=~member,
stroke=FALSE, fillOpacity=0.9, fillColor="Red")
})
}
shinyApp(ui, server)
For the filtering, I guess it depends how much time each filtering actually takes. 对于过滤,我想这取决于每次过滤实际花费的时间。 If it only takes a few seconds, it's probably ok for the user to wait.
如果它只需要几秒钟,那么用户可能会等待。 If it takes 20s and you need to wait every time you change a parameter, it could be good to do the filtering at the beginning where you can have a loading sign for a minute or so.
如果需要20秒并且每次更改参数都需要等待,那么最好在开始时进行过滤,这样您可以在一分钟左右的时候进行加载。
For the ifelse
, you could use a dataframe
to directly get the dataset you want. 对于
ifelse
,您可以使用dataframe
ifelse
直接获取所需的数据集。 For example, using the code you posted, you could do, in the global part: 例如,使用您发布的代码,您可以在全局部分中执行以下操作:
chooseDataset <- data.frame(group=rep(c("a","b"),each=2),year=rep(c(1,0),2))
chooseDataset$dataset <- paste0("group",toupper(chooseDataset$group),"_y",chooseDataset$year)
and in the observe
where you have the leafletProxy
: 并在
observe
中你有leafletProxy
:
dataset<- with(chooseDataset,chooseDataset[group==input$group & year=input$year,"dataset"])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.