DT RowGroup extension – (total) sum per column

huangapple go评论62阅读模式
英文:

DT RowGroup extension - (total) sum per column

问题

DT提供了一个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代码)?这主要是一个与R Shiny DT相关的可视化问题/问题(在使用RowGroup时)。

首选可视化效果(额外行):
DT RowGroup extension – (total) sum per column

组内行中的总和(例如mpg的总和为132.8):
DT RowGroup extension – (total) sum per column

英文:

DT provides a RowGroup extension.

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

It it possible to display, an extra row or within the group row, the (total) sum of all values per column (without a lot of JS lines)? It is primarily a visualization R Shiny DT question/ issue (while using RowGroup).

Prefered visualization (extra row):
DT RowGroup extension – (total) sum per column

Sum within row group (.e.g. total = 132.8 for mpg):
DT RowGroup extension – (total) sum per column

答案1

得分: 1

以下是您要翻译的代码部分的翻译:

# 计算按 'cyl' 水平的 'mpg' 的小计
byFactor <- "cyl"
variable <- "mpg"
subtotals <- sapply(split(mtcars, mtcars[[byFactor]]), function(dat) {
  sum(dat[[variable]])
})
n <- length(subtotals)

# 将 'mtcars' 的行名称移到第一列
dat0 <- mtcars
dat0 <- cbind(car = rownames(mtcars), mtcars)

# 将小计附加到此数据框 'dat0' 上
totals <- matrix(NA, nrow = n, ncol = ncol(dat0))
colnames(totals) <- colnames(dat0)
dat <- rbind(dat0, totals)
dat_tail <- (nrow(dat) - n + 1L):nrow(dat) # 新数据的行索引
dat[dat_tail, "car"] <- "Total"
dat[dat_tail, variable] <- subtotals
dat[dat_tail, byFactor] <- names(subtotals)

# 按 'cyl' 列对 'dat' 进行排序
dat <- dat[order(dat[[byFactor]]), ]

# 现在创建数据表
library(DT)
datatable(
  dat, rownames = FALSE, 
  extensions = "RowGroup", 
  options = list(
    rowGroup = list(dataSrc = list(2))
  )
)

为了得到小计的粗体行,您可以使用行回调:

# 提取要加粗的行的索引
indices <- which(dat[["car"]] == "Total") - 1L # 减去1是为了适应 JavaScript!

cb <- JS(
  "function(row, data, displayNum, index) {", 
  sprintf("var indices = [%s];", toString(indices)),
  "  if(indices.indexOf(index) > -1) {",
  "    $(row).css('font-weight', 'bold');",
  "  }",
  "}"
)

library(DT)
datatable(
  dat, rownames = FALSE, 
  extensions = "RowGroup", 
  options = list(
    rowCallback = cb,
    rowGroup = list(dataSrc = list(2))
  )
)

奖励:

# 我还会在行组标题前加上 'cyl:',并隐藏 'cyl' 列
dat[[byFactor]] <- paste0(byFactor, ": ", dat[[byFactor]])
datatable(
  dat, rownames = FALSE, 
  extensions = "RowGroup", 
  options = list(
    rowCallback = cb,
    rowGroup = list(dataSrc = list(2)),
    columnDefs = list(
      list(targets = 2, visible = FALSE)
    )
  )
)

请注意,这些翻译是代码的翻译,不包括问题的回答。如果您需要进一步的解释或信息,请提出相关问题。

英文:

A possible way:

# compute subtotals of &#39;mpg&#39; by level of &#39;cyl&#39;
byFactor &lt;- &quot;cyl&quot;
variable &lt;- &quot;mpg&quot;
subtotals &lt;- sapply(split(mtcars, mtcars[[byFactor]]), function(dat) {
  sum(dat[[variable]])
})
n &lt;- length(subtotals)

# move the rownames of &#39;mtcars&#39; to first column
dat0 &lt;- mtcars
dat0 &lt;- cbind(car = rownames(mtcars), mtcars)

# append the subtotals to this dataframe &#39;dat0&#39;
totals &lt;- matrix(NA, nrow = n, ncol = ncol(dat0))
colnames(totals) &lt;- colnames(dat0)
dat &lt;- rbind(dat0, totals)
dat_tail &lt;- (nrow(dat)-n+1L):nrow(dat) # the row indices of the new data
dat[dat_tail, &quot;car&quot;] &lt;- &quot;Total&quot;
dat[dat_tail, variable] &lt;- subtotals
dat[dat_tail, byFactor] &lt;- names(subtotals)

# sort &#39;dat&#39; by the &#39;cyl&#39; column
dat &lt;- dat[order(dat[[byFactor]]), ]


# now make the datatable
library(DT)
datatable(
  dat, rownames = FALSE, 
  extensions = &quot;RowGroup&quot;, 
  options = list(
    rowGroup = list(dataSrc = list(2))
  )
)

DT RowGroup extension – (total) sum per column


Edit

To get bold rows for the totals, you can use a row callback:

# extract indices of the rows to be bolded
indices &lt;- which(dat[[&quot;car&quot;]] == &quot;Total&quot;) - 1L # subtract 1 for JavaScript!

cb &lt;- JS(
  &quot;function(row, data, displayNum, index) {&quot;, 
  sprintf(&quot;var indices = [%s];&quot;, toString(indices)),
  &quot;  if(indices.indexOf(index) &gt; -1) {&quot;,
  &quot;    $(row).css(&#39;font-weight&#39;, &#39;bold&#39;);&quot;,
  &quot;  }&quot;,
  &quot;}&quot;
)

library(DT)
datatable(
  dat, rownames = FALSE, 
  extensions = &quot;RowGroup&quot;, 
  options = list(
    rowCallback = cb,
    rowGroup = list(dataSrc = list(2))
  )
)

Bonus:

# I would also prepend &#39;cyl:&#39; to the rowgroup headers and hide the &#39;cyl&#39; column
dat[[byFactor]] &lt;- paste0(byFactor, &quot;: &quot;, dat[[byFactor]])
datatable(
  dat, rownames = FALSE, 
  extensions = &quot;RowGroup&quot;, 
  options = list(
    rowCallback = cb,
    rowGroup = list(dataSrc = list(2)),
    columnDefs = list(
      list(targets = 2, visible = FALSE)
    )
  )
)

DT RowGroup extension – (total) sum per column

huangapple
  • 本文由 发表于 2023年3月31日 17:44:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/75897047.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定