allow tidyselect for columGroups
As previously mentioned, wonderful package! thx again.
It would be very convenient if columnGroups would allow selecting columns with tidyselect (contains, starts_with etc). Using the example from the pkg site, something like:
reactable(
iris,
columns = list(
Sepal.Length = colDef(name = "Length"),
Sepal.Width = colDef(name = "Width"),
Petal.Length = colDef(name = "Length"),
Petal.Width = colDef(name = "Width")
),
columnGroups = list(
colGroup(name = "Sepal", columns = contains("Sepal"),
colGroup(name = "Petal", columns = contains("Petal")
)
)
Hi, that's an interesting idea, and it does look convenient. Could you use tidyselect to select columns outside of reactable? I'm totally unfamiliar with tidyselect and just skimmed the vignette at https://tidyselect.r-lib.org/articles/tidyselect.html. But it might be possible to write your own wrapper of reactable() that supports tidyselect syntax for the column groups:
# Wrapper for reactable that supports tidyselect syntax in columnGroups
# Based on https://cran.r-project.org/web/packages/tidyselect/vignettes/tidyselect.html
# NOTE: not sure if this is totally correct but it seems to work
reactable <- function(data, columnGroups = NULL, ...) {
groups <- rlang::enquo(columnGroups)
groups <- rlang::get_expr(groups)[-1]
groups <- lapply(groups, function(group) {
pos <- tidyselect::eval_select(group$columns, data = data)
group$columns <- names(pos)
rlang::eval_tidy(group)
})
reactable::reactable(data, columnGroups = groups, ...)
}
Then you could use the drop-in reactable() replacement like:
library(reactable)
library(tidyselect)
reactable(
iris,
columns = list(
Sepal.Length = colDef(name = "Length"),
Sepal.Width = colDef(name = "Width"),
Petal.Length = colDef(name = "Length"),
Petal.Width = colDef(name = "Width")
),
columnGroups = list(
colGroup(name = "Sepal", columns = contains("Sepal")),
colGroup(name = "Petal", columns = contains("Petal"))
)
)
While the syntax is convenient, I don't feel particularly strongly about building it into reactable. For this specific example, you could also use grep() to select columns that contain or start with some pattern like:
reactable(
iris,
columns = list(
Sepal.Length = colDef(name = "Length"),
Sepal.Width = colDef(name = "Width"),
Petal.Length = colDef(name = "Length"),
Petal.Width = colDef(name = "Width")
),
columnGroups = list(
colGroup(name = "Sepal", columns = grep("Sepal", names(iris), value = TRUE)),
colGroup(name = "Petal", columns = grep("^Petal", names(iris), value = TRUE))
)
)
A simple workaround that has helped me is using str_subset() on the column names e.g.
reactable(
iris,
columns = list(
Sepal.Length = colDef(name = "Length"),
Sepal.Width = colDef(name = "Width"),
Petal.Length = colDef(name = "Length"),
Petal.Width = colDef(name = "Width")
),
columnGroups = list(
colGroup(name = "Sepal", columns = str_subset(colnames(iris), "Sepal"),
colGroup(name = "Petal", columns = str_subset(colnames(iris), "Petal")
)
)