在R Shiny中实现三元柱状图切换为指定二元柱状图
问题解决:在Shiny中动态切换二元柱状图变量
问题背景
我有包含国家、市中心一居室房租(x48)、郊区一居室房租(x49)、月平均薪资(x54)的数据集,原本用ggplot生成了三元柱状图,但现在需要固定保留月平均薪资的柱子,同时通过Shiny输入控件选择显示x48或x49其中一个,实现二元柱状图的动态切换。
数据集结构如下:
data <- structure(list(country = c("Andorra", "Austria", "Belgium", "Denmark", "Finland", "France", "Germany", "Greece"), x48 = c(811.73, 710.0385, 765.8359, 961.434, 701.9176, 716.7308, 701.6187, 468.1942), x49 = c(655.2433, 607.8058, 628.3675, 692.426, 575.4287, 587.7711, 544.2052, 370.2103), x54 = c(2801.597, 2224.757, 2320.216, 3130.023, 2582.625, 2399.011, 2621.368, 804.5603)), class = "data.frame", row.names = c(NA, -8L))
解决方案
核心思路是根据Shiny输入筛选需要保留的两个变量(固定x54+选中的x48/x49),再进行数据重塑和绘图。以下是完整的可运行Shiny代码:
library(shiny) library(tidyverse) # 加载数据集 data <- structure(list(country = c("Andorra", "Austria", "Belgium", "Denmark", "Finland", "France", "Germany", "Greece"), x48 = c(811.73, 710.0385, 765.8359, 961.434, 701.9176, 716.7308, 701.6187, 468.1942), x49 = c(655.2433, 607.8058, 628.3675, 692.426, 575.4287, 587.7711, 544.2052, 370.2103), x54 = c(2801.597, 2224.757, 2320.216, 3130.023, 2582.625, 2399.011, 2621.368, 804.5603)), class = "data.frame", row.names = c(NA, -8L)) # 预定义变量标签与颜色映射 var_labels <- c( x48 = "1 room in the center", x49 = "1 room outside the center", x54 = "Average Monthly Salary" ) var_colors <- c( x48 = "#108CDF", x49 = "#0DD016", x54 = "#DA560A" ) # UI界面 ui <- fluidPage( selectInput( inputId = "selected_rent", label = "选择要显示的房租变量", choices = c("市中心一居室" = "x48", "郊区一居室" = "x49"), selected = "x48" ), plotOutput("bar_plot") ) # 服务器逻辑 server <- function(input, output) { output$bar_plot <- renderPlot({ # 筛选需要的变量:固定x54 + 用户选中的房租变量 selected_vars <- c(input$selected_rent, "x54") data %>% select(country, all_of(selected_vars)) %>% pivot_longer(-country, names_to = "metric", values_to = "value") %>% ggplot(aes(x = country, y = value, fill = metric)) + geom_col(position = "dodge") + scale_fill_manual( name = "Metric", labels = var_labels[selected_vars], values = var_colors[selected_vars] ) + theme_light() + theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1)) + xlab("Country") + ylab("USD") }) } shinyApp(ui, server)
关键修改说明
- 变量筛选:通过
select(country, all_of(selected_vars))只保留需要的列,避免多余数据进入绘图流程。 - 动态匹配标签与颜色:提前定义映射表,根据选中的变量动态提取对应内容,保证图例和颜色始终匹配当前显示的变量。
- 实时响应输入:通过
input$selected_rent获取用户选择,实时更新绘图数据,实现二元柱状图的切换效果。
内容的提问来源于stack exchange,提问作者walter
相关产品推荐
相关产品推荐

