如何基于初始数据集选择动态生成Shiny应用的UI与Server逻辑
实现方案
最优方案是使用Shiny原生conditionalPanel实现页面状态切换,无需引入额外依赖,你原有代码中关于score2的条件隐藏逻辑已经正确,仅需要补充着陆页的控制逻辑即可。
核心修改点
- 新增着陆页专属区域,应用启动时仅展示数据集选择项和确认按钮
- 新增主功能区的显示条件,仅当用户确认选择数据集后展示参数配置、表格、下载功能
- 优化下拉框选项更新逻辑,适配不同数据集的字段差异
- 增加返回按钮,支持用户回到着陆页重新选择数据集
完整可运行代码
library(dbplyr) library(dplyr) library(shiny) library(shinyWidgets) library(DT) df <- read.csv('https://raw.githubusercontent.com/datacfb123/testdata/main/sampleset_df.csv') df2 <- read.csv('https://raw.githubusercontent.com/datacfb123/testdata/main/sampleset_df.csv') ui <- fluidPage( titlePanel("Sample"), # 着陆页面板:未确认数据集时显示 conditionalPanel( condition = "input.confirm_btn == 0", wellPanel( h2("请选择要使用的数据集"), radioButtons("mydata", label = "选择数据框", choices = c("df","df2"), inline=TRUE), br(), actionButton("confirm_btn", "确认选择,进入配置页", class = "btn-primary") ) ), # 主功能面板:确认数据集后显示 conditionalPanel( condition = "input.confirm_btn > 0", sidebarLayout( sidebarPanel( actionButton("back_btn", "返回重新选择数据集"), br(),br(), selectizeInput("data1", "选择州", choices = NULL), selectizeInput("data2", "选择郡", choices = NULL), selectizeInput("data3", "选择城市", multiple = TRUE, choices = NULL), selectizeInput("data4", "选择人群分类", choices = c("All", unique(df$demo))), selectizeInput("data5", "选择状态", choices = c("All", unique(df$status))), sliderInput("age", label = h3("选择年龄范围"), 18, 35, value = c(18, 20), round = TRUE, step = 1), sliderInput("score1", label = h3("选择Score1范围"), min = 0, max = 100, value = c(20,80)), conditionalPanel(condition = "input.mydata=='df'", sliderInput("score2", label = h3("选择Score2范围"), min = 0, max = 100, value = c(20,80)) ), prettyCheckboxGroup("phones", h3("仅保留有效手机号?"), selected = "Yes", choices = list("Yes")), downloadButton("download", "下载数据") ), mainPanel( DTOutput("table") ) ) ) ) server <- function(input, output, session){ # 监听确认按钮,更新第一个下拉框选项 observeEvent(input$confirm_btn, { current_df <- get(input$mydata) updateSelectizeInput(session, "data1", "选择州", choices = c("All", unique(current_df$state))) }) # 监听返回按钮,重置状态回到着陆页 observeEvent(input$back_btn, { updateSelectizeInput(session, "data1", choices = NULL) updateSelectizeInput(session, "data2", choices = NULL) updateSelectizeInput(session, "data3", choices = NULL) updateActionButton(session, "confirm_btn", value = 0) }) mydf <- reactive({get(input$mydata)}) observeEvent(input$data1, { df <- mydf() updateSelectizeInput(session, "data2", "选择郡", server = TRUE, choices = c("All", unique(df$county[df$state == input$data1]))) }, priority = 2) observeEvent(c(input$data1, input$data2), { df <- mydf() if (input$data2 != "All") { updateSelectizeInput(session, "data3", "选择城市", multiple = TRUE, server = TRUE, choices = c("All", unique(df$city[df$county == input$data2]))) } else { updateSelectizeInput(session, "data3", "选择城市", multiple = TRUE, server = TRUE, choices = c("All", unique(df$city[df$state == input$data1]))) } }, priority = 1) filtered_data <- reactive({ temp_data <- mydf() if (!is.null(input$data1) && input$data1 != "All") { temp_data <- temp_data[temp_data$state == input$data1, ] } if (!is.null(input$data2) && input$data2 != "All") { temp_data <- temp_data[temp_data$county == input$data2, ] } if (!is.null(input$data3) && !"All" %in% input$data3) { temp_data <- temp_data[temp_data$city %in% input$data3, ] } if (input$data4 != "All") { temp_data <- temp_data[temp_data$demo == input$data4, ] } if (input$data5 != "All") { temp_data <- temp_data[temp_data$status == input$data5, ] } df2 <- temp_data %>% dplyr::filter(age >= input$age[1] & age <= input$age[2] & score1 >= input$score1[1] & score1 <= input$score1[2]) if (input$mydata=="df") df2 <- df2 %>% dplyr::filter(score2 >= input$score2[1] & score2 <= input$score2[2]) df3 <- if (is.null(input$phones)) df2 else df2 %>% dplyr::filter(!is.na(phone)) df3 %>% dplyr::select(unique_id, first_name, last_name, phone) }) output$table <- renderDT( filtered_data() ) output$download <- downloadHandler( filename = function() { paste("universe", "_", date(), ".csv", sep="") }, content = function(file) { write.csv(filtered_data() %>% distinct_all(), file, row.names = FALSE) } ) } shinyApp(ui, server)
功能说明
- 应用启动默认显示着陆页,仅提供数据集选择入口
- 确认数据集后自动跳转至参数配置页,选中
df2时自动隐藏Score2选择滑块,筛选逻辑同步适配 - 支持返回着陆页重新选择数据集,所有配置参数会自动重置
内容的提问来源于stack exchange,提问作者wizkids121
相关产品推荐
相关产品推荐

