You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 05:55:15