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

R Shiny动态DT数据表按分组添加U、D列求和合计行

需求背景

现有shiny+DT搭建的应用已实现第一列按Population字段合并单元格的效果,需要新增以下逻辑:

  • 初始加载时,在p1分组最后一行(p1_5_b)、p2分组最后一行(p2_f)下方各插入一行
  • 插入行第二列值为total,用于统计对应Population分组下U列、D列的数值总和
  • 效果参考:
    效果示例
实现方案

核心逻辑是在响应式数据集处理环节,按筛选后的Population分组计算合计值,将合计行插入到对应分组末尾,同时兼容原有单元格合并规则,不需要额外修改JS合并逻辑。

修改点说明

  • 修复原有响应式数据集未返回结果、局部变量和全局变量重名的bug
  • 按筛选条件过滤数据后,分组计算U、D列总和,生成合计行:合计行第一列(Population)留空,避免干扰原有单元格合并逻辑,第二列(var1)固定为total
  • 将合计行按顺序插入到对应分组的尾部,保证排序后位置正确
  • 新增行样式配置,自动给合计行加粗,和普通数据行做区分

修改后完整代码

library(shiny)
library(DT)

dat<-structure(list(Population = c("p1", "p1", "p1", "p1", "p1", "p1", 
                                   "p1", "p1", "p1", "p1", "p2", "p2", "p2", "p2", "p2", "p2"), 
                    var1 = c("p1_1_a", "p1_1_b", "p1_2_a", "p1_2_b", "p1_3_a", 
                             "p1_3_b", "p1_4_a", "p1_4_b", "p1_5_a", "p1_5_b", "p2_a", 
                             "p2_b", "p2_c", "p2_d", "p2_e", "p2_f"), U = c(1, 1, 0, 0, 
                                                                            1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0), D = c(25, 12, 14, 11, 
                                                                                                                       3, 3, 2, 4, 5, 0, 0, 0, 0, 25, 12, 14)), row.names = c(NA, 
                                                                                                                                                                              -16L), class = c("tbl_df", "tbl", "data.frame"))
ui <- fluidPage(
  uiOutput("p"),
  uiOutput("pp"),
  DTOutput("table")
)

server <- function(input, output){
  output$p<-renderUI({
    selectInput("p1","P",choices = unique(dat$Population),multiple = T,selected =  unique(dat$Population))
  })
  output$pp<-renderUI({
    dat_sub<-subset(dat,dat$Population%in%input$p1)
    selectInput("p2","P",choices = unique(dat_sub$var1),multiple = T,selected =  unique(dat_sub$var1))
  })
  df<-reactive({
    # 按筛选条件过滤数据
    filtered <- subset(dat, dat$Population %in% input$p1 & dat$var1 %in% input$p2)
    # 按Population分组生成合计行
    group_ls <- split(filtered, filtered$Population)
    total_ls <- lapply(group_ls, function(g){
      data.frame(
        Population = "", # 第一列留空,不参与单元格合并
        var1 = "total",
        U = sum(g$U),
        D = sum(g$D),
        check.names = FALSE
      )
    })
    # 拼接原始数据和对应合计行
    res_ls <- mapply(function(g, total){
      rbind(g, total)
    }, g = group_ls, total = total_ls, SIMPLIFY = FALSE)
    res <- do.call(rbind, res_ls)
    rownames(res) <- NULL
    res
  })
  output[["table"]] <- renderDT({
    dtable <- datatable(df(), rownames = FALSE, 
                        options = list(
                          rowsGroup = list(0), # 合并第一列单元格
                          order = list(list(1, 'asc')),
                          pageLength=20 # 调整页长容纳合计行
                        )) %>%
      # 合计行加粗显示
      formatStyle(
        columns = "var1",
        target = "row",
        fontWeight = styleEqual("total", "bold")
      )
    # 本地RowsGroup插件路径,按实际存放位置修改
    path <- "C:/Users/User/Documents/Darya/www"
    dep <- htmltools::htmlDependency(
      "RowsGroup", "2.0.0", 
      path, script = "dataTables.rowsGroup.js")
    dtable$dependencies <- c(dtable$dependencies, list(dep))
    dtable
  })
}

shinyApp(ui, server)

注意事项

  • 代码中dataTables.rowsGroup.js的本地路径请按实际文件存放位置修改,保证插件能正常加载实现单元格合并
  • 筛选条件变化时,合计行会自动重新计算,适配选中的Population和var1范围
  • 合计行第一列留空,不会破坏原有第一列的合并效果,和参考截图效果一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 06:46:04