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

R Shiny实现直方图百分比/数量切换与水平布局配置

解决方案

核心调整逻辑如下:

  • 删除原有两个独立的绘图输出容器,仅保留单个绘图输出位,通过单选输入控件切换统计展示形式
  • 基于Shiny内置的栅格布局系统实现三列水平排布,按顺序放置输入控件、直方图、说明文本
  • 服务端通过响应式逻辑监听输入选择,动态调整ggplot的绘图参数,无需重复维护两套绘图代码
  • 修复原代码中UI函数括号不闭合、样式属性笔误的语法问题

完整可运行代码

注:代码中补充了泰坦尼克号数据集的预处理逻辑,如果你本地已经有预处理完成的survivalMutate对象,可以直接删除对应预处理段。

# 加载依赖包
library(shiny)
library(ggplot2)
library(bslib)
library(dplyr)

# 数据预处理(已有survivalMutate可删除此段)
data("Titanic")
survivalMutate <- as.data.frame(Titanic) %>%
  group_by(Sex, Survived) %>%
  summarise(Count = sum(Freq), .groups = "drop") %>%
  mutate(Status = ifelse(Survived == "Yes", "Survived", "Died"))

ui <- fluidPage(
  theme = bs_theme(version = 4, bootswatch = "minty"),
  titlePanel("Titanic"),
  
  # 原有头部图片区域
  sidebarLayout(
    sidebarPanel(),
    mainPanel(
      img(src = "titanicPic.jpg", height = 182, width = 520)
    )
  ),
  p(""),
  h4("乘客生存情况分布", style = "font-family: 'times'; font-size:16pt"),
  
  # 原有标签页区域
  tabsetPanel(
    tabPanel("x", tableOutput("")), 
    tabPanel("y", verbatimTextOutput("")), 
    tabPanel("z", tableOutput(""))
  ),
  br(),
  
  # 三列水平布局区域:控件-图-说明文本
  fluidRow(
    # 第一列:输入选择控件
    column(
      width = 2,
      radioButtons(
        inputId = "plot_type",
        label = "选择展示形式",
        choices = c("百分比占比" = "fill", "绝对数量" = "stack"),
        selected = "fill"
      )
    ),
    # 第二列:直方图
    column(
      width = 6,
      plotOutput(outputId = "survival_plot", width = "100%")
    ),
    # 第三列:数据说明文本
    column(
      width = 4,
      h5("图表说明"),
      p("本图统计泰坦尼克号不同性别乘客的生存情况:深灰色代表遇难乘客,浅白色代表幸存乘客。"),
      p("选择「百分比占比」时,纵轴展示不同性别下幸存/遇难乘客的比例;选择「绝对数量」时,纵轴展示对应分类的实际乘客人数。")
    )
  )
)

server <- function(input, output) {
  # 单个响应式绘图对象,根据输入动态调整参数
  output$survival_plot <- renderPlot({
    # 根据选择动态设置标签
    plot_config <- if (input$plot_type == "fill") {
      list(title = "不同性别乘客生存占比", y_label = "占比")
    } else {
      list(title = "不同性别乘客生存人数", y_label = "人数")
    }
    
    ggplot(survivalMutate, aes(x = Sex, fill = Status, weight = Count)) +
      geom_bar(position = input$plot_type) +
      ggtitle(plot_config$title) +
      scale_fill_manual(values = c("grey24", "snow")) +
      labs(y = plot_config$y_label) +
      theme_bw(base_size = 14)
  })
}

shinyApp(ui = ui, server = server)

关键实现说明

  • 水平对齐:Shiny的fluidRow和column基于Bootstrap栅格系统实现,总宽度固定为12,你可以根据需要调整三列的width参数修改占比,元素默认顶部对齐
  • 切换逻辑:不需要渲染两个独立ggplot对象,仅把会变化的position参数、标题、y轴标签和输入控件做绑定即可,代码冗余度更低,渲染速度更快
  • 文本说明:直接在第三列的column内添加任意文本、标题元素即可,会自动和同row内的其他元素保持水平对齐,需要调整样式可以直接给文本标签加style属性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 23:27:10