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

如何修改Shiny代码实现导入文件时的动态过滤功能?

支持CSV/XLSX上传的动态过滤Shiny应用代码

完整修改后代码

library(dplyr)
library(shiny)
library(purrr)
library(readxl) # 用于读取XLSX格式文件

make_ui <- function(x, var) {
  if (is.numeric(x)) {
    rng <- range(x, na.rm = TRUE)
    sliderInput(var, var, min = rng[1], max = rng[2], value = rng)
  } else if (is.factor(x)) {
    levs <- levels(x)
    selectInput(var, var, choices = levs, selected = levs, multiple = TRUE)
  } else if (is.character(x)) {
    # 支持字符型变量,生成多选选择框
    levs <- unique(x)
    selectInput(var, var, choices = levs, selected = levs, multiple = TRUE)
  } else {
    # 不支持的数据类型返回空控件
    NULL
  }
}

filter_var <- function(x, val) {
  if (is.numeric(x)) {
    !is.na(x) & x >= val[1] & x <= val[2]
  } else if (is.factor(x) || is.character(x)) {
    x %in% val
  } else {
    # 无对应过滤控件时,返回全部数据
    TRUE
  }
}

ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      fileInput('inputFile', '选择CSV/XLSX文件',
                multiple = FALSE,
                accept = c('text/csv',
                           'text/comma-separated-values',
                           'application/vnd.ms-excel',
                           'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
                           '.csv', '.xlsx')),
      # 动态生成过滤控件的容器
      uiOutput("filter_controls")
    ),
    mainPanel(
      tableOutput("data")
    )
  )
)

server <- function(input, output, session) {
  # 响应式读取上传的文件
  uploaded_data <- reactive({
    req(input$inputFile) # 等待文件上传完成
    file_path <- input$inputFile$datapath
    ext <- tools::file_ext(file_path)
    
    # 根据文件扩展名选择读取方式
    switch(ext,
           csv = read.csv(file_path, stringsAsFactors = TRUE),
           xlsx = read_excel(file_path),
           stop("仅支持CSV或XLSX格式文件")
    )
  })
  
  # 动态生成过滤控件
  output$filter_controls <- renderUI({
    req(uploaded_data()) # 确保数据已读取
    map(names(uploaded_data()), ~ make_ui(uploaded_data()[[.x]], .x))
  })
  
  # 响应式筛选数据
  selected <- reactive({
    req(uploaded_data())
    each_var <- map(names(uploaded_data()), ~ filter_var(uploaded_data()[[.x]], input[[.x]]))
    reduce(each_var, ~ .x & .y)
  })
  
  # 渲染筛选后的表格(显示前12行)
  output$data <- renderTable({
    req(selected(), uploaded_data())
    head(uploaded_data()[selected(), ], 12)
  })
} 

shinyApp(ui, server)

关键修改说明

  • 新增依赖:引入readxl包,实现XLSX文件的读取支持
  • UI结构调整:
    • 添加fileInput组件作为文件入口
    • 替换原固定的iris数据集控件为uiOutput,实现过滤控件的动态生成
  • 数据读取逻辑:
    • 创建uploaded_data()响应式对象,根据文件扩展名自动适配读取方法
    • 使用req()确保仅在文件上传完成后才执行后续逻辑
  • 过滤逻辑优化:
    • 扩展make_ui函数,支持字符型变量的过滤控件生成
    • 更新filter_var函数,兼容字符型和因子型变量的筛选规则
  • 响应式关联:所有依赖数据集的逻辑均从静态iris改为动态的uploaded_data()对象

测试用代码

# 生成测试用CSV文件(基于iris数据集)
write.csv(iris, "my_example.csv", row.names = FALSE)

内容的提问来源于stack exchange,提问作者Abbas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 06:03:19