Search code examples
rreactable

R reactable Grouped Columns programaticaly


I have this dataset in R. I'd like to transform it with R package reacatable.

dt <-
  data.table(
    month = seq(1, 12),
    aa_2019 = seq(1, 12),
    bb_2019 = seq(1, 12),
    
    aa_2020 = seq(1, 12),
    bb_2020 = seq(1, 12),
    
    aa_2021 = seq(1, 12),
    bb_2021 = seq(1, 12),
    
    aa_2022 = seq(1, 12),
    bb_2022 = seq(1, 12)
)

Desired output looks like this. Is there a way how to make it automatically? Imagine having sequence of years from 1900 to 2023.

reactable(
  dt,
  columns = list(
    aa_2019 = colDef(name = "aa"),
    bb_2019 = colDef(name = "bb"),
    
    aa_2020 = colDef(name = "aa"),
    bb_2020 = colDef(name = "bb"),
    
    aa_2021 = colDef(name = "aa"),
    bb_2021 = colDef(name = "bb"),
    
    aa_2022 = colDef(name = "aa"),
    bb_2022 = colDef(name = "bb")
  ),
  columnGroups = list(
    colGroup(name = "2019", columns = c("aa_2019", "bb_2019")),
    colGroup(name = "2020", columns = c("aa_2020", "bb_2020")),
    colGroup(name = "2021", columns = c("aa_2021", "bb_2021")),
    colGroup(name = "2022", columns = c("aa_2022", "bb_2022"))
  )
)

Solution

  • Here is one approach to create your colDefs and colGroups dynamically:

    library(reactable)
    
    cols <- names(dt)[-1]
    cols_split <- strsplit(cols, "_")
    
    cols <- data.frame(
      name = cols,
      group = sapply(cols_split, `[[`, 1),
      year = sapply(cols_split, `[[`, 2)
    )
    
    col_defs <- lapply(
      cols$group,
      \(x) {
        colDef(name = x)
      }
    ) |>
      setNames(cols$name)
    
    col_groups <- cols |>
      split(~year) |>
      lapply(\(x) {
        colGroup(name = unique(x$year), columns = x$name)
      }) |> 
      unname()
    
    reactable(
      dt,
      columns = col_defs,
      columnGroups = col_groups
    )
    

    enter image description here