我正在RStudio中使用R,并创建了一个闪亮的仪表板。在仪表板中,我正在使用leaflet()函数绘制地图。现在,我正在尝试在地图上放置标记,以显示芝加哥的犯罪情况。我正在使用selectInput()和sliderInput()函数来选择不同的犯罪类型,位置和年份。如果我在输入字段中选择了某些内容,则标记会显示在芝加哥地图上,并且效果很好。但是我希望当我启动闪亮的应用程序时,所有标记都显示为不基于selectInput()进行过滤。这是我的ui.R代码:
tabItem(tabName = "map",
div(class="outer",
tags$head(
tags$style(type = "text/css", "#map {height: calc(100vh - 80px) !important;}"))),
leafletOutput("map", width = "100%", height = "100%"),
absolutePanel(id = "mapControls", fixed = TRUE, draggable = TRUE, top = 150, left = "auto", right = 15, bottom = "auto", width = 200, height = "auto",
selectInput("mapCrimeType", label= "Select Crime Type", choices = unique(cc$Primary.Type), multiple = TRUE),
selectInput("mapLocation", label= "Select Location", choices = unique(cc$Location.Description), multiple = TRUE),
sliderInput("mapYear", label = "Select Year", min = 2001, max = 2016, step = 1, sep = '', value = c(2001,2016))
)
),
这是我的server.R代码:
server <- function(input, output) {
### Draw Map ###
output$map = renderLeaflet({
leaflet() %>%
addProviderTiles(providers$Esri.WorldStreetMap) %>%
setView(lng = -87.6105, lat = 41.8947, zoom=11)
})
reactMap = reactive({
cc %>%
filter(Primary.Type %in% input$mapCrimeType &
Location.Description %in% input$mapLocation &
Year %in% cbind(input$mapYear[1],input$mapYear[2]))
})
observe({
proxy = leafletProxy("map", data = reactMap()) %>%
clearMarkers() %>%
clearMarkerClusters() %>%
addCircleMarkers(clusterOptions = markerClusterOptions(),
lng =~ Longitude, lat =~ Latitude, radius = 5, group = 'Cluster',
popup =~ paste('<b><font color="Black">', 'Crime Information',
'</font></b><br/>', 'Crime Type:', Primary.Type,'<br/>',
'Date:', Date,'<br/>', #'Time:', Time,'<br/>',
'Location:', Location.Description,'<br/>', 'Block:', Block, '<br/>', 'Arrest:', Arrest, '<br/>'))
})
我想我必须在server.R文件中的反应函数中进行一些更改。我希望有人能帮助我。
答案 0 :(得分:0)
没有示例数据很难进行测试,但是您可以尝试以下两种方法之一:
第一个选项是通过分别添加selected = unique(cc$Primary.Type)
和selected = unique(cc$Location.Description)
来预选择mapCrimeType和mapLocation的所有选项。我在下面添加了mapYear,但是您已经选择value = c(2001,2016)
来选择整个范围了。
selectInput("mapCrimeType", label= "Select Crime Type", choices = unique(cc$Primary.Type), multiple = TRUE, selected = unique(cc$Primary.Type)),
selectInput("mapLocation", label= "Select Location", choices = unique(cc$Location.Description), multiple = TRUE, selected = unique(cc$Location.Description)),
sliderInput("mapYear", label = "Select Year", min = 2001, max = 2016, step = 1, sep = '', value = c(2001,2016))
如果那太乱了(我不确定他们有多少选择),可以尝试以下操作:
reactMap = reactive({
if (is.null(input$mapCrimeType)) {
mapCrimeType = unique(cc$Primary.Type)
} else {
mapCrimeType = input$mapCrimeType
}
if (is.null(input$mapLocation)) {
mapLocation = unique(cc$Location.Description)
} else {
mapLocation = input$mapLocation
}
cc %>%
filter(Primary.Type %in% mapCrimeType &
Location.Description %in% mapLocation &
Year %in% cbind(input$mapYear[1],input$mapYear[2]))
})
基本上,每当一个selectInputs为NULL时,我们都将包括该selectInput的所有选择(或当两个均为NULL时都包括)。 让我知道是否有帮助。
更新
请尝试下面的完整答案。我上面有一个错误。
if (is.null(input$mapLocation)) {
mapLocation = unique(cc$Location.Description)
} else {
mapLocation = input$mapLocation
}
从上一个if语句复制了is.null(input$mapCrimeType)
。
此处已测试答案:
library(shiny)
library(shinydashboard)
library(leaflet)
library(dplyr)
ui <- tabItem(tabName = "map",
div(class="outer",
tags$head(
tags$style(type = "text/css", "#map {height: calc(100vh - 80px) !important;}"))),
leafletOutput("map", width = "100%", height = "100%"),
absolutePanel(id = "mapControls", fixed = TRUE, draggable = TRUE, top = 150, left = "auto", right = 15, bottom = "auto", width = 200, height = "auto",
selectInput("mapCrimeType", label= "Select Crime Type", choices = unique(cc$Primary.Type), multiple = TRUE),
selectInput("mapLocation", label= "Select Location", choices = unique(cc$Location.Description), multiple = TRUE),
sliderInput("mapYear", label = "Select Year", min = 2001, max = 2016, step = 1, sep = '', value = c(2001,2016))
)
)
server <- function(input, output) {
### Draw Map ###
output$map = renderLeaflet({
leaflet() %>%
addProviderTiles(providers$Esri.WorldStreetMap) %>%
setView(lng = -87.6105, lat = 41.8947, zoom=11)
})
reactMap = reactive({
if (is.null(input$mapCrimeType)) {
mapCrimeType = unique(cc$Primary.Type)
} else {
mapCrimeType = input$mapCrimeType
}
if (is.null(input$mapLocation)) {
mapLocation = unique(cc$Location.Description)
} else {
mapLocation = input$mapLocation
}
cc %>%
filter(Primary.Type %in% mapCrimeType &
Location.Description %in% mapLocation &
between(Year, input$mapYear[1], input$mapYear[2]))
})
observe({
proxy = leafletProxy("map", data = reactMap()) %>%
clearMarkers() %>%
clearMarkerClusters() %>%
addCircleMarkers(clusterOptions = markerClusterOptions(),
lng =~ Longitude, lat =~ Latitude, radius = 5, group = 'Cluster',
popup =~ paste('<b><font color="Black">', 'Crime Information',
'</font></b><br/>', 'Crime Type:', Primary.Type,'<br/>',
'Date:', Date,'<br/>', #'Time:', Time,'<br/>',
'Location:', Location.Description,'<br/>', 'Block:', Block, '<br/>', 'Arrest:', Arrest, '<br/>'))
})
}
shinyApp(ui = ui, server = server)
我从lbusett添加了一点,即您的Year过滤器仅显示最小和最大年份中的数据,而不显示之间的年份,这是我使用between
中的dplyr
函数完成的。 / p>
您可以合并lbusett的答案,该答案更整洁,如下所示:
reactMap <- reactive({
out_cc <- cc %>%
dplyr::filter(., Year >= input$mapYear[1] &
Year <= input$mapYear[2])
if (!is.null(input$mapCrimeType)) {
out_cc <- out_cc %>%
dplyr::filter(., Primary.Type %in% input$mapCrimeType)
}
if (!is.null(input$mapLocation)) {
out_cc <- out_cc %>%
dplyr::filter(., Location.Description %in% input$mapLocation)
}
out_cc
})
答案 1 :(得分:0)
未经测试,但这应该可行。只需将反应式更改为:
reactMap <- reactive({
out_cc <- cc %>%
dplyr::filter(., Year %in% cbind(input$mapYear[1],input$mapYear[2]))
if (!is.null(input$mapCrimeType)) {
out_cc <- out_cc %>%
dplyr::filter(., Primary.Type %in% input$mapCrimeType)
}
if (!is.null(input$mapLocation)) {
out_cc <- out_cc %>%
dplyr::filter(., Location.Description %in% input$mapLocation)
}
out_cc
})
在没有“选定”值且使用multiple = TRUE
的情况下调用时,选择器在开始时或取消选择所有内容时具有NULL
值。因此,仅当给定变量的相应输入为NULL
时,才需要跳过对它的过滤。
顺便说一句:我可能错了,但是我认为您可能需要将“年”过滤器更改为类似以下内容:
dplyr::filter(., Year >= input$mapYear[1] &
Year <= input$mapYear[2])
,否则您将只获得所选的最小和最大年份的值,而不是中间年份的值。