参考reactable groupby聚合表达式中的其他列

问题描述 投票:0回答:1

我有一个数据框,我想利用它与可扩展的分组进行反应。我知道我可以使用 groupby 参数,然后在 colDef 中为每个指标指定聚合,但是,在某些情况下,我尝试聚合的列是其他列的函数,并应用“平均值”或“总和”等结果值不准确。

type = c("mammal", "mammal", "reptile", "reptile")
animal = c("monkey", "human", "frog", "toad")
measureCY = c(1, 4, 5, 6)
measurePY = c(3,4,5,7)
df = data.frame(type, animal, measureCY, measurePY)
df$YoY <- df$measureCY/df$measurePY

reactable(
df,
pagination=FALSE,
pagination=FALSE,
    sortable=FALSE,
    height = 600,
    defaultColDef = colDef(style = function(value) { list(height="30px",font_size="1px")},vAlign="center"),
    defaultPageSize = 25, # default 10 - just want to show entire table
groupBy=c("type", "animal"),
columns = list(
type = colDef(name = "Type"),
animal = colDef(name = "Animal"),
measureCY = colDef(name = "CY", aggregate="sum"),
measurePY = colDef(name = "PY", aggregate="sum"),
YoY = colDef(name = "YoY", aggregate = "sum")
),
showSortable = TRUE
  )

上面的代码是一个例子。这适用于这两个度量,但是 YoY 列的总和或平均值会导致值不准确。我不知何故需要引用 YoY 列的聚合函数中的 CYPY 值,但我不确定如何做到这一点。

r dplyr shiny reactable
1个回答
0
投票

您可以使用自定义 JS 聚合函数来实现您想要的结果,该函数允许使用

rows
参数访问其他列中的值(请参阅 docs
rows
属性是一个 row 对象数组,其中每个对象包含一行的数据。因此,我们可以循环遍历各行来计算
measureCY
measurePY
列中的值的聚合总和,从而计算
YoY
的正确聚合值:

library(reactable)

reactable(
  df,
  pagination = FALSE,
  sortable = FALSE,
  height = 600,
  defaultColDef = colDef(style = function(value) {
    list(height = "30px", font_size = "1px")
  }, vAlign = "center"),
  defaultPageSize = 25, # default 10 - just want to show entire table
  groupBy = c("type", "animal"),
  columns = list(
    type = colDef(name = "Type"),
    animal = colDef(name = "Animal"),
    measureCY = colDef(name = "CY", aggregate = "sum"),
    measurePY = colDef(name = "PY", aggregate = "sum"),
    YoY = colDef(
      name = "YoY",
      aggregate =
        htmlwidgets::JS("
              function(values, rows) {
                // sum of CY
                let measureCY = rows
                    .map( (row) => row.measureCY)
                    .reduce( (a, b) => a + b );
                // sum of PY
                let measurePY = rows
                    .map( (row) => row.measurePY)
                    .reduce( (a, b) => a + b );

                return measureCY / measurePY;
              }
            "),
      format = reactable::colFormat(
        digits = 2
      )
    )
  ),
  showSortable = TRUE
)

© www.soinside.com 2019 - 2024. All rights reserved.