我需要使用传单包创建一个交互式地图,在这里我可以使用selectInput
控制要在地图上显示的数据点。我还想使用图层控制按钮选择一个或两个图层(数据点)以显示在地图上。我的代码如下所示。
我希望地图仅在单击selectInput
按钮时才响应go
。
当我在selectInput
中选择一项时,我的代码有效(当我单击go
时,地图刷新)。选择第二项时发现,最初看到错误:subscript out of bounds
。单击go
时,两个标记均出现。当我删除所选的两个项目之一时,地图会在点击操作按钮之前做出响应。
[似乎selectInput
未正确响应action button
。有人知道为什么会这样吗?我做错什么了?我花了数小时试图弄清楚,但没有运气。。。
library(shiny)
library(leaflet)
hotels <- read.table(text = "Hotel Year latitude longitude
A 2000 41.886337 -87.628472
B 2005 41.88819 -87.635199
C 2010 41.891113 -87.63301",
header = TRUE)
ui <- fluidPage(
selectizeInput(inputId = 'year', label='Choose Year:',
choices = c(2000,2005,2010),
multiple=TRUE,
options = list(
maxItems = 2,
placeholder = '',
onInitialize = I("function() { this.setValue(''); }"))),
actionButton("go", "go"),
leafletOutput("mymap")
)
server <- function(input, output, session) {
df_list = reactive ({
input$go
isolate(
if (length(input$year)>1) {
list(hotels[hotels$Year == input$year[1],],
hotels[hotels$Year == input$year[2],])
} else {
list(hotels[hotels$Year == input$year[1],])
}
)
})
output$mymap <- renderLeaflet({
map = leaflet() %>%
addProviderTiles("OpenStreetMap.Mapnik") %>%
addCircleMarkers( data = df_list()[[1]] ,
group = 'Data Markers 1',
lng = ~longitude,
lat = ~latitude,
radius = 10,
stroke = F,
fillOpacity = 0.9,
color = 'red')
if ( length(input$year)>1){
map = map %>%
addCircleMarkers( data = df_list()[[2]] ,
group = 'Data Markers 2',
lng = ~longitude,
lat = ~latitude,
radius = 10,
stroke = F,
fillOpacity = 0.9,
color = 'blue')
}
if ( length(input$year)>1) {
map = map %>%
addLayersControl(
overlayGroups = c('Data Markers 1', 'Data Markers 2'),
options = layersControlOptions(collapsed = FALSE) )
} else {
map = map %>%
addLayersControl(
overlayGroups = c('Data Markers 1'),
options = layersControlOptions(collapsed = FALSE) )
}
})
}
shinyApp(ui, server)
主要要点是在使用操作按钮时应使用observeEvent()
。您混合了被动路径,因此值的更改顺序与您假定的顺序不同。
library(shiny)
library(leaflet)
hotels <- read.table(text = "Hotel Year latitude longitude
A 2000 41.886337 -87.628472
B 2005 41.88819 -87.635199
C 2010 41.891113 -87.63301",
header = TRUE)
ui <- fluidPage(
selectizeInput(inputId = 'year', label='Choose Year:',
choices = c(2000,2005,2010),
multiple=TRUE,
options = list(
maxItems = 2,
placeholder = '',
onInitialize = I("function() { this.setValue(''); }"))),
actionButton("go", "go"),
leafletOutput("mymap")
)
server <- function(input, output, session) {
# use the button for observeEvent
# ignore values ensure an empty map is loading in the beginning
observeEvent(input$go, ignoreInit = FALSE, ignoreNULL = FALSE, {
# no need for a reactive list here
if (length(input$year)>1) {
df_list <- list(hotels[hotels$Year == input$year[1],],
hotels[hotels$Year == input$year[2],])
} else {
df_list <- list(hotels[hotels$Year == input$year[1],])
}
output$mymap <- renderLeaflet({
map <- leaflet() %>%
addProviderTiles("OpenStreetMap.Mapnik") %>%
addCircleMarkers( data = df_list[[1]] ,
group = 'Data Markers 1',
lng = ~longitude,
lat = ~latitude,
radius = 10,
stroke = F,
fillOpacity = 0.9,
color = 'red')
# not using input does not invoke reactiveness
if ( length(df_list) > 1){
map <- map %>%
addCircleMarkers( data = df_list[[2]] ,
group = 'Data Markers 2',
lng = ~longitude,
lat = ~latitude,
radius = 10,
stroke = F,
fillOpacity = 0.9,
color = 'blue')
}
if ( length(input$year)>1) {
map <- map %>%
addLayersControl(
overlayGroups = c('Data Markers 1', 'Data Markers 2'),
options = layersControlOptions(collapsed = FALSE) )
} else {
map <- map %>%
addLayersControl(
overlayGroups = c('Data Markers 1'),
options = layersControlOptions(collapsed = FALSE) )
}
map
})
})
}
shinyApp(ui, server)
希望这会有所帮助
注意:使用分配箭头进行分配;)