[英]Shiny Leaflet map renders twice on switching input
I'm trying to produce a Shiny app with Leaflet that renders a choropleth map based on different input criteria. 我正在尝试使用Leaflet生成Shiny应用程序,该应用程序可根据不同的输入条件来渲染一个Choropleth贴图。 The map displays incidents of different types (
input$type
) and backgrounds ( input$background
). 该地图显示不同类型(
input$type
)和背景( input$background
)的事件。 When additional types or backgrounds are specified, polygons are filled with updated incident data. 指定其他类型或背景时,多边形将填充有更新的入射数据。 It is working correctly with one snag.
一键正常工作。 When I switch the date input from date range (
input$dateInput
) to presidential period ( input$president
), the choropleth for presidential period renders once, displaying polygons with no data, and then again with the polygons filled with the correct data for the pre-selected period ("President1"). 当我将日期输入从日期范围(
input$dateInput
)切换到总统期间( input$president
)时,总统期间的choropleth渲染一次,显示没有数据的多边形,然后再次填充具有正确数据的多边形预选时段(“ President1”)。 How do I avoid the map rendering twice like this when the Presidency tab is pressed? 当按下“主席”选项卡时,如何避免两次这样的地图渲染?
Question also listed here on RStudio Community. 问题也列在这里的RStudio社区。
The raw data and shapefile used can be accessed here: https://github.com/cjbarrie/shiny_egy . 可以在这里访问使用的原始数据和shapefile: https : //github.com/cjbarrie/shiny_egy 。
Working example: 工作示例:
Name of raw data: wikiraw
原始数据名称:
wikiraw
Name of shapefile: shapefile
shapefile的名称:
shapefile
Global: 全球:
library(shiny)
library(shinydashboard)
library(shinythemes)
library(leaflet)
library(rgdal)
library(rmapshaper)
library(sp)
library(dplyr)
library(lubridate)
wikiraw <-read.csv("~/wikisample_SO.csv")
shapefile <- readOGR("~/EGY_adm2.shp")
shapefile<-spTransform(shapefile, CRS("+init=epsg:4326"))
## Simplify shapefile to speed up rendering
shapefile <- ms_simplify(shapefile, keep = 0.01, keep_shapes = TRUE)
wikbounds<-bbox(shapefile)
wikiraw$incident_date <- as.Date(wikiraw$incident_date,
format = "%m/%d/%Y")
wikiraw$presidency <- rep(NA, nrow(wikiraw))
wikiraw$incident_date1 <- as.numeric(wikiraw$incident_date)
wikiraw$event <- rep(1,nrow(wikiraw))
## Generate presidency categorical var.
wikiraw$presidency <- cut(wikiraw$incident_date1,
breaks = c(-Inf, 15016, 15521, 15889, 16229, Inf),
labels = c("President1", "President2", "President3", "President4", "President5"),
right = FALSE)
Snippet of data.frame wikiraw
: data.frame
wikiraw
片段:
ID_2 incident_date incident_background incident_type presidency event
1 168 2013-11-26 Cultural Group President4 1
2 133 2013-11-29 Cultural Group President4 1
3 137 2014-01-25 Cultural Group President4 1
4 168 2011-01-28 Cultural Collective President1 1
5 168 2016-04-25 Cultural Group President5 1
6 163 2015-02-08 Political Individual President5 1
UI: 用户界面:
ui <- dashboardPage(
dashboardHeader(title = "Map tool"),
dashboardSidebar(sidebarMenu(menuItem("Map", tabName = "map"),
selectInput("input_type", "Date input type",
c("Date", "Presidency")),
uiOutput("dateSelect"),
uiOutput("typeSelect"),
uiOutput("backgroundSelect"),
uiOutput("presidentSelect"))),
dashboardBody(tabItems(
tabItem(tabName = "map",
leafletOutput("mymap", height=500)))))
Server: 服务器:
server <- function(input, output, session) {
output$dateSelect <- renderUI({
switch(input$input_type,
"Date" = dateRangeInput("dateInput", "Dates:",
min=min(wikiraw$incident_date), max = max(wikiraw$incident_date),
start = min(wikiraw$incident_date), end = max(wikiraw$incident_date)),
"Presidency" = checkboxGroupInput("president", "Presidency",
choices = levels(wikiraw$presidency),
selected = "President1"))
})
output$typeSelect <- renderUI({
selectInput("type", "Incident type",
choices = unique(wikiraw$incident_type), multiple = TRUE,
selected = wikiraw$incident_type[1])})
output$backgroundSelect <- renderUI({
checkboxGroupInput("background", "Incident background",
choices = unique(wikiraw$incident_background),
selected = wikiraw$incident_background[1])})
selected <- reactive({
wikiagg <- wikiraw %>% group_by(ID_2, incident_date, incident_type, incident_background, presidency) %>%
summarize(sum_event = sum(event))
if(input$input_type=="Date"){wikiagg <- filter(wikiagg,
incident_date >= min(input$dateInput),
incident_date <= max(input$dateInput),
incident_type%in%input$type,
incident_background%in%input$background)}
if(input$input_type=="Presidency"){wikiagg <- filter(wikiagg,
incident_type%in%input$type,
incident_background%in%input$background,
presidency%in%input$president)}
wikiagg <- wikiagg %>% group_by(ID_2) %>%
summarize(sum_event = sum(sum_event))
wikiagg
})
output$mymap <- renderLeaflet({
leaflet() %>%
addTiles() %>%
setView(mean(wikbounds[1,]),
mean(wikbounds[2,]),
zoom=6
)
})
observe({
if(!is.null(input$dateInput)){
shapefile@data <- left_join(shapefile@data, selected(), by="ID_2")
##Define palette across range of data
wikiaggpal <- wikiraw %>% group_by(ID_2) %>%
summarize(sum_event = sum(event))
pal <- colorBin("YlOrRd", wikiaggpal$sum_event, bins=5, na.color = "#bdbdbd")
leafletProxy("mymap", data = shapefile) %>%
addTiles() %>%
clearShapes() %>%
addPolygons(data = shapefile, fillColor = ~pal(sum_event), fillOpacity = 0.7,
color = "white", weight = 2)
}})
}
shinyApp(ui, server)
Gif of issue: 问题的Gif:
https://imgur.com/a/FnfOGKi https://imgur.com/a/FnfOGKi
Any help would be hugely appreciated! 任何帮助将不胜感激!
What if you change the reactive
to a reactiveValue
and assign the data in an observe
? 如果将
reactive
更改为reactiveValue
并在observe
分配数据怎么办? I don't know if it is working correctly as I dont know which shapes & colors to expect, but I am not seeing that double rendering anymore. 我不知道它是否能正常工作,因为我不知道期望使用哪种形状和颜色,但是我再也看不到这种双重渲染。
( Data & Preparation from question is used ) ( 使用来自问题的数据和准备 )
library(shiny)
library(shinydashboard)
library(shinythemes)
library(leaflet)
library(rgdal)
library(rmapshaper)
library(sp)
library(dplyr)
library(lubridate)
ui <- dashboardPage(
dashboardHeader(title = "Map tool"),
dashboardSidebar(sidebarMenu(menuItem("Map", tabName = "map"),
selectInput("input_type", "Date input type",
c("Date", "Presidency")),
uiOutput("dateSelect"),
uiOutput("typeSelect"),
uiOutput("backgroundSelect"),
uiOutput("presidentSelect"))),
dashboardBody(tabItems(
tabItem(tabName = "map",
leafletOutput("mymap", height=500)))))
server <- function(input, output, session) {
output$dateSelect <- renderUI({
switch(input$input_type,
"Date" = dateRangeInput("dateInput", "Dates:",
min=min(wikiraw$incident_date), max = max(wikiraw$incident_date),
start = min(wikiraw$incident_date), end = max(wikiraw$incident_date)),
"Presidency" = checkboxGroupInput("president", "Presidency",
choices = levels(wikiraw$presidency),
selected = "President1"))
})
output$typeSelect <- renderUI({
selectInput("type", "Incident type",
choices = unique(wikiraw$incident_type), multiple = TRUE,
selected = wikiraw$incident_type[1])})
output$backgroundSelect <- renderUI({
checkboxGroupInput("background", "Incident background",
choices = unique(wikiraw$incident_background),
selected = wikiraw$incident_background[1])})
sel_reactval = reactiveValues(s = NULL)
# selected <- reactive({
observe({
wikiagg <- wikiraw %>% group_by(ID_2, incident_date, incident_type, incident_background, presidency) %>%
summarize(sum_event = sum(event))
if(input$input_type=="Date"){wikiagg <- filter(wikiagg,
incident_date >= min(input$dateInput),
incident_date <= max(input$dateInput),
incident_type%in%input$type,
incident_background%in%input$background)}
if(input$input_type=="Presidency"){wikiagg <- filter(wikiagg,
incident_type%in%input$type,
incident_background%in%input$background,
presidency%in%input$president)}
wikiagg <- wikiagg %>% group_by(ID_2) %>%
summarize(sum_event = sum(sum_event))
sel_reactval$s = wikiagg
# wikiagg
})
output$mymap <- renderLeaflet({
leaflet() %>%
addTiles() %>%
setView(mean(wikbounds[1,]),
mean(wikbounds[2,]),
zoom=6
)
})
observe({
req(!is.null(input$dateInput))
req(nrow(as.data.frame(sel_reactval$s))!=0)
# if(!is.null(input$dateInput)){
# shapefile@data <- left_join(shapefile@data, selected(), by="ID_2")
shapefile@data <- left_join(shapefile@data, sel_reactval$s, by="ID_2")
##Define palette across range of data
wikiaggpal <- wikiraw %>% group_by(ID_2) %>%
summarize(sum_event = sum(event))
pal <- colorBin("YlOrRd", wikiaggpal$sum_event, bins=5, na.color = "#bdbdbd")
leafletProxy("mymap") %>%
addTiles() %>%
clearShapes() %>%
addPolygons(data = shapefile, fillColor = ~pal(sum_event), fillOpacity = 1,
color = "white", weight = 2)
# }
})
}
shinyApp(ui, server)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.