glin / reactable

Interactive data tables for R
https://glin.github.io/reactable
Other
613 stars 79 forks source link

Aggregated values not updating when using built-in aggregators in combination with crosstalk #219

Open KuzMaxOriginal opened 2 years ago

KuzMaxOriginal commented 2 years ago

I'm not sure if it belongs to crosstalk or this, but I believe I've chosen the proper repository.

Take two code snippets:

library(crosstalk)

cars <- MASS::Cars93[, c("Manufacturer", "Model", "Type", "Price")]
data <- SharedData$new(cars)

bscols(
  widths = c(3, 9),
  list(
    filter_checkbox("type", "Manufacturer", data, ~Manufacturer)
  ),
  reactable(
    data,
    minRows = 10,
    groupBy = "Type",
    columns = list(
      Price = colDef(
        aggregate = "sum"
      )
    )
  )
)
library(crosstalk)

cars <- MASS::Cars93[, c("Manufacturer", "Model", "Type", "Price")]
data <- SharedData$new(cars)

bscols(
  widths = c(3, 9),
  list(
    filter_checkbox("type", "Manufacturer", data, ~Manufacturer)
  ),
  reactable(
    data,
    minRows = 10,
    groupBy = "Type",
    columns = list(
      Price = colDef(
        aggregated = JS("function(cellInfo) {
            const values = cellInfo.subRows.map(function(row) { return row['Price'] })
            const sum = values.reduce((a, b) => (a + b), 0)

            return Math.round(sum * 100) / 100
        }"),
      )
    )
  )
)

The first one will not calculate filtered rows properly, as it will only use the initial, unfiltered by Manufacturer data set. The second one works as expected, since it dynamically updates every time the user changes the filters.

I propose to add the ability to set aggregated parameter with the built-in "mean", "sum", "max", "min", "median", "count", "unique", "frequency" functions.

glin commented 2 years ago

Hi, try out the latest development version (0.2.3.9000). This was one of the bigger changes in 0.2.3.9000:

  • Aggregated cell values are now recalculated when filtering or searching the table.
tylerlittlefield commented 1 year ago

Note that this doesn't work on footers however:

Just kidding, found this issue for a solution: https://github.com/glin/reactable/issues/78

library(crosstalk)

cars <- MASS::Cars93[, c("Manufacturer", "Model", "Type", "Price")]
data <- SharedData$new(cars)

bscols(
  widths = c(3, 9),
  list(
    filter_checkbox("type", "Manufacturer", data, ~Manufacturer)
  ),
  reactable(
    data,
    minRows = 10,
    groupBy = "Type",
    columns = list(
      Price = colDef(
        footer = function(values) sum(values, na.rm = TRUE)
      )
    )
  )
)