---
title: "Get started with shinyfilters"
output: rmarkdown::html_vignette
vignette: >
%\VignetteIndexEntry{Get started with shinyfilters}
%\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{UTF-8}
---
```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>"
)
library(shinyfilters)
```
```{r, eval = !getRversion() >= "4.1", include = !getRversion() >= "4.1"}
library(magrittr)
```
shinyfilters creates shiny inputs for filtering data. This article uses
`nyc_flights`, a sample of flights that left New York City in 2013.
## Filters from a data frame
`shinyfilters()` turns a data frame into a set of filters.
```{r}
filters <- shinyfilters(nyc_flights)
```
Printing it shows the input each column gets:
```{r}
filters
```
## Customizing filters
You can customize these settings on a `shinyfilters` object:
* A filter's input function
* The values used to create and update the input function
* Add a namespace
### Change a filter's input function
* Set an argument of `shinyfilters()`:
```{r}
shinyfilters(nyc_flights, range = TRUE)
```
* Use `with_defaults()`:
```{r, eval = getRversion() >= "4.1", include = getRversion() >= "4.1"}
filters |> with_defaults(range = TRUE)
```
```{r, eval = !getRversion() >= "4.1", include = !getRversion() >= "4.1"}
filters %>% with_defaults(range = TRUE)
```
* Use `with_filters()`:
```{r, eval = getRversion() >= "4.1", include = getRversion() >= "4.1"}
filters |> with_filters(date = "range")
```
```{r, eval = !getRversion() >= "4.1", include = !getRversion() >= "4.1"}
filters %>% with_filters(date = "range")
```
See `vignette("shinyfilters-catalog")` for the full list of input functions
available in `shinyfilters`.
### Change a filter's arguments
* Use `with_args()`:
```{r, eval = getRversion() >= "4.1", include = getRversion() >= "4.1"}
filters |>
with_args(dep_delay ~ list(value = range(.x)))
```
```{r, eval = !getRversion() >= "4.1", include = !getRversion() >= "4.1"}
filters %>%
with_args(dep_delay ~ list(value = range(.x)))
```
* Use `with_filters()`:
```{r, eval = getRversion() >= "4.1", include = getRversion() >= "4.1"}
filters |>
with_filters(dep_delay ~ list(value = range(.x)))
```
```{r, eval = !getRversion() >= "4.1", include = !getRversion() >= "4.1"}
filters %>%
with_filters(dep_delay ~ list(value = range(.x)))
```
* Choose the input and set its arguments together:
```{r, eval = getRversion() >= "4.1", include = getRversion() >= "4.1"}
filters |>
with_filters(dep_delay ~ "slider" ~ list(value = range(.x)))
```
```{r, eval = !getRversion() >= "4.1", include = !getRversion() >= "4.1"}
filters %>%
with_filters(dep_delay ~ "slider" ~ list(value = range(.x)))
```
```{r, eval = getRversion() >= "4.1", include = getRversion() >= "4.1"}
filters |>
with_filters(dep_delay ~ sliderInput ~ list(value = range(.x)))
```
```{r, eval = !getRversion() >= "4.1", include = !getRversion() >= "4.1"}
filters %>%
with_filters(dep_delay ~ sliderInput ~ list(value = range(.x)))
```
### Change multiple filters together
* Set multiple filters inside `with_filters()`:
```{r, eval = getRversion() >= "4.1", include = getRversion() >= "4.1"}
filters |>
with_filters(
dep_delay ~ list(value = range(.x)),
distance = 1.609344 * distance
)
```
```{r, eval = !getRversion() >= "4.1", include = !getRversion() >= "4.1"}
filters %>%
with_filters(
dep_delay ~ list(value = range(.x)),
distance = 1.609344 * distance
)
```
### Use a namespace
* Set the `ns` argument of `shinyfilters()`:
```{r}
shinyfilters(nyc_flights, ns = "sidebar-mod")
```
* Use `with_ns()`:
```{r, eval = getRversion() >= "4.1", include = getRversion() >= "4.1"}
filters |>
with_ns("sidebar-mod")
```
```{r, eval = !getRversion() >= "4.1", include = !getRversion() >= "4.1"}
filters %>%
with_ns("sidebar-mod")
```
### Use a non-shiny input function
* Use a shinyWidgets input in `with_filters()`. It comes with the function that updates it:
```{r, eval = getRversion() >= "4.1" && requireNamespace("shinyWidgets", quietly = TRUE), include = getRversion() >= "4.1", message = FALSE}
library(shinyWidgets)
filters |>
with_filters(dest = pickerInput)
```
```{r, eval = !getRversion() >= "4.1" && requireNamespace("shinyWidgets", quietly = TRUE), include = !getRversion() >= "4.1", message = FALSE}
library(shinyWidgets)
filters %>%
with_filters(dest = pickerInput)
```
* For an input from anywhere else, name the function that updates it with `.update_fn`:
```{r, eval = getRversion() >= "4.1", include = getRversion() >= "4.1"}
filters |>
with_filters(
origin ~ shiny::checkboxGroupInput ~
list(.update_fn = shiny::updateCheckboxGroupInput)
)
```
```{r, eval = !getRversion() >= "4.1", include = !getRversion() >= "4.1"}
filters %>%
with_filters(
origin ~ shiny::checkboxGroupInput ~
list(.update_fn = shiny::updateCheckboxGroupInput)
)
```
## Selecting filters
After creating your filters, you can select multiple filters or a single filter,
allowing you to place the filters anywhere in an application
### Select multiple filters
* Use `[`:
```{r}
filters[-c(carrier, origin)]
```
* Use `[` with <[`tidy-select`][tidyselect::language]>:
```{r, eval = requireNamespace("tidyselect", quietly = TRUE), message = FALSE}
library(tidyselect)
filters[starts_with("d")]
```
* Select and create with `[[`:
```{r}
filters[[c(carrier, origin)]]
```
### Select one filter
* Use `$`:
```{r}
filters$dest
```
* Use `[[`:
```{r}
filters[["dest"]]
```
## Use in a shiny app
### UI
You can place the filters directly inside a UI.
```{r, eval = FALSE}
library(bslib)
library(DT)
library(shiny)
ui <- page_sidebar(
sidebar = sidebar(
filters
),
DTOutput("data")
)
```
#### Organizing
To organize filters, you can select them individually or by group.
```{r, eval = FALSE}
library(bslib)
library(DT)
library(shiny)
ui <- page_sidebar(
sidebar = sidebar(
filters[date],
accordion(
accordion_panel(
"Airports",
filters[[c(origin, dest)]]
),
accordion_panel(
"Time",
filters[[contains("delay")]]
),
accordion_panel(
"Other",
filters[[!c(date, origin, dest, contains("delay"))]]
)
)
),
DTOutput("data")
)
```
### Server
In the server, use `shinyfilters_server()` to enable interdependency:
```{r, eval = FALSE}
server <- function(input, output, session) {
sidebar <- shinyfilters_server(filters)
output$data <- renderDT(datatable(sidebar$filtered))
}
```
### Run the app
Run the application as you normally would.
```{r, eval=FALSE}
shinyApp(ui, server)
```
## Notes
### Bookmarking
Apps that use bookmarking need `filterInput(filters)` inside their UI function
instead, so the inputs restore their bookmarked values. Placing `filters` in
their UI directly is an error.
### Custom objects
If you're filtering a custom object, you may need to extend shinyfilters. See
`vignette("extending-shinyfilters")` for details.