Shiny应用实现带预测、分组功能的地点选择输入组件
在Shiny中实现带预测的地点输入与分组选择框
一、带输入预测和滚动条的地点选择组件
对于大量地点列表的输入预测需求,selectizeInput是比textInput更合适的选择——它原生支持实时搜索预测、滚动加载,无需额外复杂配置就能满足需求。
以下是实现代码,包含一个模拟的大量地点数据集:
library(shiny) # 模拟大量地点数据(1000条示例) set.seed(123) locations <- paste0( sample(c("New", "Old", "North", "South"), 1000, replace = TRUE), " ", sample(c("York", "Haven", "Town", "City"), 1000, replace = TRUE), " (", round(runif(1000, -90, 90), 2), ", ", round(runif(1000, -180, 180), 2), ")" ) ui <- fluidPage( titlePanel("地点选择组件演示"), sidebarLayout( sidebarPanel( # 带预测和滚动的地点输入 selectizeInput( inputId = "location_search", label = "搜索地点", choices = locations, selected = NULL, multiple = FALSE, options = list( placeholder = "输入地点名称搜索", # 限制下拉显示选项数量,超出则显示滚动条 maxOptions = 20, # 启用滚动 scroll = TRUE, # 实时搜索匹配 searchField = "value", # 匹配规则:包含匹配 score = I("function(search) { return function(item) { return item.value.toLowerCase().indexOf(search.toLowerCase()) !== -1; }; }") ) ) ), mainPanel( verbatimTextOutput("selected_location") ) ) ) server <- function(input, output) { output$selected_location <- renderPrint({ input$location_search }) } shinyApp(ui, server)
关键配置说明:
maxOptions = 20:限制下拉框最多显示20个选项,超出时自动出现滚动条scroll = TRUE:强制启用滚动功能- 自定义
score函数:实现模糊匹配,输入任意字符即可匹配包含该字符的地点
二、按州分组的城市选择框(值为经纬度)
如果需要基于给定的data.frame构建按州分组的选择框,可先将数据转换为分组列表结构,再用selectizeInput或pickerInput(来自shinyWidgets包)实现。以下示例将纬度作为valueField:
library(shiny) library(shinyWidgets) # 若用pickerInput需安装:install.packages("shinyWidgets") # 示例data.frame city_data <- data.frame( state = c(rep("California", 3), rep("Texas", 3), rep("New York", 3)), city = c("Los Angeles", "San Francisco", "San Diego", "Houston", "Dallas", "Austin", "New York City", "Buffalo", "Rochester"), lat = c(34.0522, 37.7749, 32.7157, 29.7604, 32.7767, 30.2672, 40.7128, 42.8864, 43.1610), lon = c(-118.2437, -122.4194, -117.1611, -95.3698, -96.7970, -97.7431, -74.0060, -78.8784, -77.6109) ) # 将data.frame转换为分组列表:州名作为组键,城市名+经纬度作为选项 grouped_choices <- split( setNames(city_data$lat, city_data$city), # value为纬度,label为城市名 city_data$state ) ui <- fluidPage( titlePanel("分组城市选择框演示"), sidebarLayout( sidebarPanel( # 按州分组的选择框,value为纬度 pickerInput( inputId = "city_select", label = "选择城市(按州分组)", choices = grouped_choices, selected = NULL, multiple = FALSE, options = list( title = "选择城市", liveSearch = TRUE # 支持实时搜索 ) ), # 若不想用shinyWidgets,也可使用原生selectizeInput selectizeInput( inputId = "city_select_native", label = "选择城市(原生分组)", choices = grouped_choices, selected = NULL, multiple = FALSE, options = list( placeholder = "选择城市", liveSearch = TRUE ) ) ), mainPanel( verbatimTextOutput("selected_lat"), verbatimTextOutput("selected_city_native") ) ) ) server <- function(input, output) { output$selected_lat <- renderPrint({ paste0("选中城市的纬度:", input$city_select) }) output$selected_city_native <- renderPrint({ paste0("选中城市的纬度(原生组件):", input$city_select_native) }) } shinyApp(ui, server)
关键说明:
grouped_choices通过split()函数构建,将州作为分组名称,城市名显示为选项标签,纬度作为选项值- 使用
pickerInput可获得更美观的分组样式和搜索体验;若依赖包受限,原生selectizeInput也支持分组结构 - 若需要将经度作为值,只需把
setNames(city_data$lat, city_data$city)替换为setNames(city_data$lon, city_data$city)即可
内容的提问来源于stack exchange,提问作者Brian Collins
相关产品推荐
相关产品推荐

