如何在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
相关产品推荐
相关产品推荐

