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

R Shiny仪表盘无法按Gender、Cancertype过滤数据求助

问题修复方案

核心问题及修正点

  1. 静态Gender选项错误:原UI中selectInput("gender")的choices误用了R内置函数table,且数据是动态加载的,需改为动态生成选项。
  2. 过滤逻辑错误:filter中req()的用法不符合规范,过滤条件写法有误,同时未考虑Gender输入不存在的场景(如选中I_Tr_Age或I_St_Age时)。
  3. 重复读取Excel文件:每次触发reactive都重新读取文件,效率低下,需缓存已读取的工作表数据。

修正后的完整代码

library(shiny)
library(shinythemes)
library(openxlsx)
library(DT)
library(dplyr)

# 预加载Excel文件(缓存所有工作表,避免重复读取)
excel_data <- lapply(getSheetNames("incidence.xlsx"), function(sheet) {
  read.xlsx("incidence.xlsx", sheet = sheet)
})
names(excel_data) <- getSheetNames("incidence.xlsx")

ui <- tagList(
  navbarPage(id = "home",
             title = actionLink("title", "Home"),
             navbarMenu("Statistics",
                        tabPanel("Incidence",
                                 sidebarLayout(
                                   sidebarPanel(
                                     selectInput(
                                       "incidence", "Select Cancer Incidence Rates By:",
                                       choices = c("Age" = "I_Age",
                                                   "Cancer Type" = "I_Site",
                                                   "Trends" = "I_Trend",
                                                   "Trend By Age" = "I_Tr_Age",
                                                   "Admission Type" = "I_Admin",
                                                   "Stage" = "I_Stage",
                                                   "Stage By Age" = "I_St_Age"
                                       )
                                     ),
                                     selectInput("cancer", "Cancer Type",
                                                 choices = c("All cancers", 
                                                             "All cancers ex NMSC", 
                                                             "Bladder cancer",
                                                             "Brain cancer",
                                                             "Breast cancer",
                                                             "Brain non-invasive tumours",
                                                             "Brain tumours"
                                                 )
                                     ),
                                     # 动态生成Gender选择框
                                     conditionalPanel(
                                       condition = "input.incidence != 'I_Tr_Age' && input.incidence != 'I_St_Age'",
                                       uiOutput("gender_select")
                                     )
                                   ),
                                   mainPanel(
                                     tabsetPanel(id = "mp",
                                                 tabPanel("Plot", plotlyOutput("plot"), value = 1),
                                                 tabPanel("Data", DT::dataTableOutput("data"), value = 2)
                                     )
                                   )
                                 )
                        )
             ),
             tabPanel("Survival"),
             tabPanel("Mortality"),
             tabPanel("Prevalence")
  )
)

server <- function(input, output, session) {
  # 获取当前选中的工作表数据
  current_data <- reactive({
    req(input$incidence)
    excel_data[[input$incidence]]
  })
  
  # 动态生成Gender选项
  output$gender_select <- renderUI({
    data <- current_data()
    req(data$Gender)
    selectInput("gender", "Gender", choices = unique(data$Gender))
  })
  
  # 过滤后的数据
  filtered_data <- reactive({
    data <- current_data()
    req(data, input$cancer)
    
    # 基础过滤:Cancer类型
    data_filtered <- data %>% filter(Cancertype == input$cancer)
    
    # 如果Gender输入存在,添加Gender过滤
    if (!is.null(input$gender)) {
      data_filtered <- data_filtered %>% filter(Gender == input$gender)
    }
    
    data_filtered
  })
  
  output$data <- renderDataTable({
    DT::datatable(filtered_data())
  })
}

shinyApp(ui = ui, server = server)

关键修改说明

  • 预加载Excel数据:启动时一次性读取所有工作表并缓存到excel_data列表中,避免重复IO操作,提升性能。
  • 动态Gender选择框:用uiOutput和renderUI根据当前选中的工作表数据生成Gender选项,确保选项与实际数据匹配。
  • 修正过滤逻辑:
    • 先确保input$cancer和当前数据存在,再执行Cancer类型过滤。
    • 判断input$gender是否存在(即是否显示条件面板),仅当存在时才添加Gender过滤,避免报错。
    • 用==替代%in%(当前为单选选择框,若改为多选可换回%in%)。
  • 规范req()用法:req()用于确保依赖对象存在,而非嵌入过滤条件中。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 09:15:34