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

R Shiny应用新增子集筛选及分组箱线图绘制功能问题求助

修改方案

核心修改点

  • 侧边栏新增通用筛选控件,支持先选筛选字段、再选该字段下要保留的取值,适配真实业务的多变量需求
  • 服务端新增动态更新筛选选项的逻辑,上传数据后自动匹配字段可选值
  • 新增数据子集过滤逻辑,用户选定筛选范围后自动应用到绘图数据源

完整可运行代码

library(shiny)
library(shinythemes)
library(dplyr)
library(readxl)
library(ggplot2)

not_sel <- "Not Selected"

main_page <- tabPanel(
  title = "Romans",
  titlePanel("Romans"),
  sidebarLayout(
    sidebarPanel(
      title = "Inputs",
      fileInput("xlsx_input", "Select XLSX file to import", accept = c(".xlsx")),
      selectInput("num_var_1", "Variable X axis", choices = c(not_sel)),
      selectInput("num_var_2", "Variable Y axis", choices = c(not_sel)),
      selectInput("factor", "Select factor", choices = c(not_sel)),
      # 新增筛选相关控件
      hr(),
      h4("数据筛选设置"),
      selectInput("filter_col", "选择筛选字段", choices = c(not_sel)),
      uiOutput("filter_values_ui"),
      br(),
      actionButton("run_button", "Run Analysis", icon = icon("play"))
    ),
    mainPanel(
      tabsetPanel(
        tabPanel(
          title = "Plot",
          plotOutput("plot_1")
        )
      )
    )
  )
)

draw_plot_1 <- function(data_input, num_var_1, num_var_2, factor){
  if(num_var_1 != not_sel & num_var_2 != not_sel & factor == not_sel){
    ggplot(data = data_input, aes(x = .data[[num_var_1]], y = .data[[num_var_2]], fill= .data[[num_var_2]])) +
      geom_boxplot() + 
      theme_bw()
  } else if(num_var_1 != not_sel & num_var_2 != not_sel & factor != not_sel){
    ggplot(data = data_input, aes(x = .data[[num_var_1]], y = .data[[num_var_2]], fill = .data[[factor]])) +
      geom_boxplot() + 
      theme_bw()
  }
}

ui <- navbarPage(
  title = "Plotter",
  theme = shinytheme("yeti"),
  main_page
)

server <- function(input, output){
  options(shiny.maxRequestSize=10*1024^2)
  
  data_input <- reactive({
    req(input$xlsx_input)
    inFile <- input$xlsx_input
    read_excel(inFile$datapath, 1)
  })
  
  # 上传数据后更新所有下拉框选项
  observeEvent(data_input(),{
    choices <- c(not_sel, names(data_input()))
    updateSelectInput(inputId = "num_var_1", choices = choices)
    updateSelectInput(inputId = "num_var_2", choices = choices)
    updateSelectInput(inputId = "factor", choices = choices)
    updateSelectInput(inputId = "filter_col", choices = choices)
  })
  
  # 动态生成筛选值多选框
  output$filter_values_ui <- renderUI({
    req(input$filter_col != not_sel)
    col_vals <- unique(data_input()[[input$filter_col]])
    checkboxGroupInput("filter_values", "选择要保留的取值", 
                       choices = col_vals, selected = col_vals)
  })
  
  # 过滤后的数据集
  filtered_data <- eventReactive(input$run_button, {
    req(data_input())
    raw_data <- data_input()
    # 没有开启筛选则返回全量数据
    if(input$filter_col == not_sel || is.null(input$filter_values)) {
      return(raw_data)
    }
    # 应用筛选条件
    raw_data %>%
      filter(.data[[input$filter_col]] %in% input$filter_values)
  })
  
  num_var_1 <- eventReactive(input$run_button, input$num_var_1)
  num_var_2 <- eventReactive(input$run_button, input$num_var_2)
  factor <- eventReactive(input$run_button, input$factor)
  
  plot_1 <- eventReactive(input$run_button,{
    req(filtered_data())
    draw_plot_1(filtered_data(), num_var_1(), num_var_2(), factor())
  })
  
  output$plot_1 <- renderPlot(plot_1())
}

shinyApp(ui = ui, server = server)

使用说明

上传包含军团字段的数据集后,在「数据筛选设置」区域的「选择筛选字段」下拉框选Legion字段,下方会自动出现两个军团的选项,勾选要展示的军团即可,绘图会自动使用筛选后的子集生成。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 21:54:06