Shiny响应式场景下,基于列值筛选多国共享的问卷答案
解决方案:基于选中国家筛选共同出现的问卷答案
核心逻辑
- 获取用户选中的国家集合,统计选中国家的总数
- 对选中国家的问卷数据,按答案分组,统计每个答案覆盖的不同国家数量
- 筛选出覆盖国家数等于选中国家总数的答案(即所有选中国家都出现过该答案)
- 若没有符合条件的答案,生成包含
None的占位数据,保证图表正常展示
Shiny 代码实现
library(shiny) library(dplyr) library(ggplot2) # 问卷数据集 survey_data <- tibble( Country = c("China", "China", "France", "France", "Italy"), Answer = c("Answer A", "Answer B", "Answer A", "Answer C", "Answer B") ) ui <- fluidPage( titlePanel("共同答案筛选图表"), sidebarLayout( sidebarPanel( selectInput( inputId = "selected_countries", label = "选择国家", choices = unique(survey_data$Country), multiple = TRUE, selected = c("China", "France") ) ), mainPanel( plotOutput("answer_plot") ) ) ) server <- function(input, output) { # 响应式数据处理 filtered_answers <- reactive({ # 确保用户选中了至少一个国家 req(input$selected_countries) selected_count <- length(input$selected_countries) # 筛选并统计符合条件的答案 common_answers <- survey_data %>% filter(Country %in% input$selected_countries) %>% group_by(Answer) %>% summarise(covered_countries = n_distinct(Country), .groups = "drop") %>% filter(covered_countries == selected_count) # 无符合条件答案时生成占位数据 if (nrow(common_answers) == 0) { tibble(Answer = "None", covered_countries = 0) } else { common_answers } }) # 生成响应式图表 output$answer_plot <- renderPlot({ filtered_answers() %>% ggplot(aes(x = Answer, y = covered_countries)) + geom_col(fill = "#3498db", width = 0.6) + labs(x = "问卷答案", y = "覆盖国家数") + theme_minimal() + theme(axis.text.x = element_text(angle = 0, vjust = 0.5)) }) } shinyApp(ui = ui, server = server)
代码关键点说明
n_distinct(Country):统计每个答案在多少个不同的选中国家出现过,避免同一国家多次提交同一答案的重复计数req(input$selected_countries):防止用户未选国家时出现报错- 空结果处理:通过生成
None占位行,保证图表始终有内容展示,符合你给出的示例场景
内容的提问来源于stack exchange,提问作者Aurel
相关产品推荐
相关产品推荐

