glin / reactable

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

Is it possible to hide child rows when using groupBy? #317

Open nameisrp opened 1 year ago

nameisrp commented 1 year ago

I’m wondering if it’s possible to hide child rows in a table. Basically I’m trying to utilize crosstalk in order to filter a column and show aggregate values based on the filter selections.

I don’t have access to a shiny server so I’m stuck using flexdashboard/rmarkdown.

Taking a simple example from the Cars93 dataset I’d like to have a filter where users can select certain Types. The table would then show the Average Price by Manufacturer, without showing the Average Price by Type.

Here’s some code although it doesn’t work obviously because it leaves blank rows for the Type.

`library(crosstalk) library(reactable) library(tidyverse)

cars <- sample_n(MASS::Cars93[23:40, ], 30, replace = TRUE) %>% mutate(Price = Price * 3, Units = sample(1:5, 30, replace = TRUE)) %>% mutate(Avg.Price = Price / Units) %>% select(Manufacturer, Type, Price, Units, Avg.Price)

data <- SharedData$new(cars)

filter_checkbox("type", "Type", data, ~Type)

reactable( data, groupBy = "Manufacturer", columns = list( Type = colDef(show = FALSE), Price = colDef(show = FALSE), Units = colDef(show = FALSE), Avg.Price = colDef(

Calculate the aggregate Avg.Price as sum(Price) / sum(Units)

  aggregate = JS("function(values, rows) {
    let totalPrice = 0
    let totalUnits = 0
    rows.forEach(function(row) {
      totalPrice += row['Price']
      totalUnits += row['Units']
    })
    return totalPrice / totalUnits
  }")
  )

) )`

glin commented 1 year ago

It's not possible to hide child rows in a table. I'm not really sure if I understand the end goal here, but it sounds like you want the table to be grouped and aggregated without having child rows?

If so, the best way to do that would probably be to pre-group and aggregate the table before it gets to reactable. For example, using dplyr's grouping features to group by Manufacturer and calculate average price:

cars <- cars %>%
  group_by(Manufacturer) %>%
  summarize(Avg.Price = sum(Price) / sum(Units))
nameisrp commented 1 year ago

Thanks for responding. The end goal would be to display the results of that dplyr group_by, but be able to filter on Type with crosstalk. If you were able to hide the child rows it would be possible, although I guess this is a niche use case because this wouldn’t be an issue if I could use shiny.