0

I'm using checkbox filters from crosstalk to filter a reactable table.

By default, the checkboxes are ordered alphabetically. I want to override this, and sort by e.g. number of entries, or by factor level.

Here's a silly example: Below, I've got a dataframe with a bunch of fruits, and a rating for each.

As shown below, checkbox options are currently ordered alphabetically. I want to order the checkboxes for 'Fruit type' by number of entries for that type (so banana > pear > apple), and the checkboxes for 'Quality' by factor level (so amazing > okay > awful).

---
title: "Ordering checkboxes from crosstalk"
---

```{r, echo=FALSE, message=FALSE}
library(dplyr)
library(crosstalk)
library(reactable)

fruit_data <- data.frame(fruit = c(rep("apple", 4), rep("banana", 14), rep("pear", 12)),
                         quality = c(rep("awful", 10), rep("okay", 15), rep("amazing", 5))) |> 
  # add a column where the fruit name is followed by how many there are, e.g. "apple (4)"  
  group_by(fruit) |> 
  mutate(fruit_label = paste0(fruit, " (", n(), ")"))

shared_data <- SharedData$new(fruit_data)

filter_checkbox("fruit", "Type", shared_data, ~fruit_label)
filter_checkbox("fruit", "Quality", shared_data, ~quality)

reactable(shared_data,
          columns = list(
            fruit_label = colDef(show = FALSE)
          ))
```

enter image description here

What's the simplest way to do this?

Ulrik Lyngs
  • 98
  • 1
  • 5

1 Answers1

1

from ?filter_checkbox

group: A one-sided formula whose values will populate this select box. Generally this should be a character or factor column; if not, it will be coerced to character.

So in this case, the group variable is the fruit_label. Therefore, you can create the desired ordered level of fruit_label and pass the fruit_label as a factor to filter_checkbox with that ordered level specified so that checkboxes will be ordered accordingly.

---
title: "Ordering checkboxes from crosstalk"
---

```{r, echo=FALSE, message=FALSE}
library(dplyr)
library(stringr)
library(crosstalk)
library(reactable)

fruit_data <- data.frame(
    fruit = c(rep("apple", 4), rep("banana", 14), rep("pear", 12)),
    quality = c(rep("awful", 10), rep("okay", 15), rep("amazing", 5))
) |>
    group_by(fruit) |>
    mutate(fruit_label = paste0(fruit, " (", n(), ")"))

# creating ordered label for filter checkbox ---------------------------------

nord <- as.numeric(str_extract(fruit_data$fruit_label, "\\d+"))
fruit_level <- fruit_data$fruit_label[order(nord, decreasing = T)] |> unique()

# ----------------------------------------------------------------------------

shared_data <- SharedData$new(fruit_data)

filter_checkbox("fruit", "Type", shared_data, 
                ~factor(fruit_label, fruit_level)) # passing fruit_label as factor with ordered level
filter_checkbox("fruit", "Quality", shared_data, ~quality)

reactable(shared_data,
          columns = list(
            fruit_label = colDef(show = FALSE)
          ))
```

filter checkbox ordered according to number of entries per category


shafee
  • 15,566
  • 3
  • 19
  • 47