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

如何在R Shiny的DT RowGroup扩展中显示列合计值?

在DT RowGroup扩展中添加分组合计(无需大量JS代码)

问题概述

使用DT的RowGroup扩展实现表格分组时,希望在分组内添加合计值,支持两种展示形式:

  • 分组下方新增合计行,展示该组各数值列的总计
  • 直接在分组标题行内嵌入对应列的合计值

现有RowGroup示例代码:

output$my_table2 <- DT::renderDataTable({
  datatable(iris[1:100, c(1:5)],
          rownames = FALSE, 
          extensions = 'RowGroup', 
          options = list(rowGroup = list(dataSrc=c(4))
          )
  )})

以下是两种需求的实现方案,均无需编写大量JS代码:


方案1:新增分组合计行

通过预处理数据,给每个分组追加合计行,再结合DT的样式设置区分合计行,同时保留RowGroup的分组效果:

library(shiny)
library(DT)
library(dplyr)

ui <- fluidPage(
  DTOutput("my_table2")
)

server <- function(input, output) {
  # 预处理数据:为每个分组添加合计行
  processed_data <- iris[1:100, ] %>%
    group_by(Species) %>%
    group_modify(~ bind_rows(
      .x,
      tibble(
        Sepal.Length = sum(.x$Sepal.Length),
        Sepal.Width = sum(.x$Sepal.Width),
        Petal.Length = sum(.x$Petal.Length),
        Petal.Width = sum(.x$Petal.Width),
        Species = "合计"
      )
    )) %>%
    ungroup()

  output$my_table2 <- DT::renderDataTable({
    datatable(
      processed_data,
      rownames = FALSE,
      extensions = 'RowGroup',
      options = list(
        rowGroup = list(dataSrc = 5),
        columnDefs = list(list(visible = FALSE, targets = 5)) # 可选:隐藏原始分组列
      ),
      callback = JS("
        table.on('draw.dt', function() {
          $('tr.dtrg-group').nextUntil('tr.dtrg-group').filter(':contains(合计)').addClass('total-row');
        });
      ")
    ) %>%
      formatStyle("total-row", fontWeight = "bold", backgroundColor = "#f5f5f5")
  })
}

shinyApp(ui, server)

说明:

  • 用group_modify为每个分组追加合计行,标记为"合计"
  • 通过JS回调给合计行添加样式类,再用formatStyle设置加粗和背景色
  • RowGroup会自动将合计行归入对应分组下

方案2:在分组行内显示合计值

预计算分组合计,通过RowGroup的startRender选项自定义分组标题,直接嵌入合计值:

library(shiny)
library(DT)
library(dplyr)
library(jsonlite)

ui <- fluidPage(
  DTOutput("my_table2")
)

server <- function(input, output) {
  # 预计算每个分组的合计值
  group_totals <- iris[1:100, ] %>%
    group_by(Species) %>%
    summarise(
      Sepal.Length = sum(Sepal.Length),
      Sepal.Width = sum(Sepal.Width),
      .groups = "drop"
    )

  output$my_table2 <- DT::renderDataTable({
    datatable(
      iris[1:100, c(1:5)],
      rownames = FALSE,
      extensions = 'RowGroup',
      options = list(
        rowGroup = list(
          dataSrc = 4,
          # 自定义分组标题渲染逻辑
          startRender = JS("
            function(row) {
              var groupName = row[4];
              var totals = ", toJSON(group_totals), ";
              var targetTotal = totals.find(item => item.Species === groupName);
              return `${groupName} | Sepal.Length合计: ${targetTotal.Sepal.Length.toFixed(1)}, Sepal.Width合计: ${targetTotal.Sepal.Width.toFixed(1)}`;
            }
          ")
        )
      )
    )
  })
}

shinyApp(ui, server)

说明:

  • 先通过dplyr计算分组合计,转成JSON传给前端JS
  • 利用RowGroup的startRender函数,将分组名称与合计值拼接成新的分组标题
  • 仅需少量JS逻辑实现值的嵌入,无需复杂操作

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 12:53:33