R reactable - expand/ungroup single item groups created by groupBy()

1.4k views Asked by At

I'm trying to produce an interactive table using reactable in Shiny that only creates expandable groups for rows that contain multiple values under the single key variable.

library(reactable)
library(data.table)

data <- setDT(MASS::Cars93[10:22, c("Manufacturer", "Model", "Type", "Price", "MPG.city")])

reactable(data, groupBy = "Manufacturer")

Example 1 The table above shows only one entry under Chrylser - I would like this to be automatically expanded or ideally not have the expand arrow at all and show all information on the one line.

Some kludgy code produces a table which shows roughly what I want:

data_unique <- unique(data, by = "Manufacturer")
data_dups <- unique(data[duplicated(data, by = "Manufacturer")]$Manufacturer)
reactable(data_unique,
          columns = list(Manufacturer = colDef(details = function(index){
                                               if(data_unique[index]$Manufacturer %in% data_dups){
                                                  reactable(data[Manufacturer == data_unique[index]$Manufacturer,
                                                                                             c("Model", "Type")])
                                                  }})))

Example 2 Chrylser now no longer has an expand button and shows all its information in the one row. The main issue is the expand button produces a separate table that doesn't line up with the main table. I like the behaviour produced by the first example using groupBy(), so ideally I would have a combination of the two. Thanks.

2

There are 2 answers

0
thothal On BEST ANSWER

As you said you want to use it in shiny, I could think of using JavaScript to automatically trigger the click event:

library(shinyjs)

ui <- fluidPage(useShinyjs(), reactable(data, groupBy = "Manufacturer"))

server <- function(input, output, session) {
   session$onFlushed(function() {
      runjs('$(".rt-td>div>span").filter(function(idx, el) {return $(el).text().includes("(1)")}).trigger("click")')
   })
}

shinyApp(ui, server)
0
Della On

You can simply use 'aggregate' function to achieve this -

example:

 reactable(data,
                 groupBy = c("Manufacturer"),
                 resizable = TRUE,
                 ......
                 columns = list("Model" = colDef(aggregate = "unique"),
                                "Type" = colDef(aggregate = "unique")))