Package {teal.picks}


Type: Package
Title: Dataset and Variable Picker and Merge Module for 'teal' Applications
Version: 0.1.0
Date: 2026-05-07
Description: Allows users to interactively select datasets, variables, and values within 'teal' applications using a 'tidyselect'-style interface. Selected picks can be merged and transformed into analysis-ready data within 'teal' modules.
License: Apache License 2.0
URL: https://github.com/insightsengineering/teal.picks/, https://insightsengineering.github.io/teal.picks/
BugReports: https://github.com/insightsengineering/teal.picks/issues
Depends: R (≥ 4.1)
Imports: bsicons, checkmate, dplyr, htmltools, logger, methods, rlang, shiny, shinyWidgets, teal, teal.code, teal.data, teal.logger, tidyselect, yaml
Suggests: jsonlite, knitr, rmarkdown, rvest, shinytest2, teal.transform, testthat (≥ 3.0), tibble, withr (≥ 3.0.0)
VignetteBuilder: knitr
Config/Needs/website: insightsengineering/nesttemplate
Config/roxygen2/version: 8.0.0
Config/testthat/edition: 3
Encoding: UTF-8
Language: en-US
NeedsCompilation: no
Packaged: 2026-05-14 20:49:46 UTC; unardid
Author: Dawid Kaledkowski ORCID iD [aut, cre], Andre Verissimo ORCID iD [aut], Marcin Kosinski [aut], LluĂ­s Revilla Sancho ORCID iD [aut], Oriol Senan ORCID iD [aut], Dony Unardi [rev], F. Hoffmann-La Roche AG [cph, fnd]
Maintainer: Dawid Kaledkowski <dawid.kaledkowski@roche.com>
Repository: CRAN
Date/Publication: 2026-05-19 09:10:02 UTC

dplyr::filter call

Description

Create a dplyr::filter call

Usage

.call_dplyr_filter(x)

Arguments

x

(list) containing variables and values

Value

call.


dplyr::select call

Description

Create dplyr::select call from dataname and variables

Usage

.call_dplyr_select(dataname, variables)

Arguments

dataname

(character(1)) name of the dataset

variables

(list of character) variables to select. If list is named then variables will be renamed if their name is different than its value (this produces a call ⁠select(..., <name> = <value>)⁠).

Value

call.


Evaluate delayed choices

Description

Evaluate delayed choices

Usage

.determine_choices(x, data)

.determine_selected(x, data, multiple = FALSE)

.determine_delayed(x, data)

.possible_choices(data)

Arguments

x

(character, quosure, ⁠function(x)⁠) to determine data elements to extract.

data

(list, data.frame, vector)

multiple

(logical(1)) whether multiple selection is possible.

Details

Various ways to evaluate choices/selected.

Function resolves x to determine choices or selected. x is matched in multiple ways with data to return valid choices:

Mechanism is robust in a sense that it never fails (tryCatch) and returns NULL if no-match found. NULL in determine() is handled gracefully, by setting NULL to all following components of picks.

In the examples below you can replace .determine_delayed with .determine_choices or .determine_selected.

Value

character containing names/levels of data elements which match x, with two differences:


Is picks delayed

Description

Determine whether list of picks/picks or pick are delayed. When "pick" is created it could be either:

Usage

.is_delayed(x)

Arguments

x

(list, ⁠list of picks⁠, picks, pick, ⁠$choices⁠, ⁠$selected⁠)

Value

A logical(1) indicating if any of the elements in picks is delayed., For a single pick, such as datasets(), variables() or values(), it checks if either choices or selected are delayed.


Is an object created using tidyselect

Description

choices and selected can be provided using tidyselect, (e.g. tidyselect::everything() tidyselect::where(), tidyselect::starts_with()). These functions can't be called independently but rather as an argument of function which consumes them. .is_tidyselect safely determines if x can be evaluated with tidyselect::eval_select()

Usage

.is_tidyselect(x)

Arguments

x

choices or selected

Value

logical(1)


Analyse selectors and concludes a merge parameters

Description

Analyse selectors and concludes a merge parameters

Usage

.merge_summary_list(selectors, join_keys)

Value

list containing:


Pick class constructor

Description

Create a pick object

Usage

.pick(
  choices,
  selected,
  multiple = length(selected) > 1,
  ordered = FALSE,
  fixed = FALSE,
  ...
)

Arguments

choices

(tidyselect::language or character) Available values to choose.

selected

(tidyselect::language or character) Choices to be selected.

multiple

(logical(1)) if more than one selection is possible.

ordered

(logical(1)) if the selected should follow the selection order. If FALSE selected returned from srv_module_input() would be ordered according to order in choices.

fixed

(logical(1)) selection will be fixed and not possible to change interactively.

...

for picks(...): hierarchical structure that contains datasets() as first element and optionally variables() and values()

for variables(...) and values(...): additional arguments delivered to pickerInput

Value

pick generic object that is used by datasets(), variables() and values() to create objects of corresponding classes.


pickerInput choices icons

Description

Icons describing a class of the choice

Usage

.picker_icon(x)

Arguments

x

(any) object which class will determine icon

Value

html-tag in form of character(1)


Resolve downstream after selected changes

Description

@description When select input at position i changes:

Usage

.resolve(selected, slot_name, picks_resolved, old_picks, data)

Arguments

selected

(vector) rather character, or factor. numeric(2) for values() based on numeric column.

slot_name

(character(1)) one of c("datasets", "variables", "values")

picks_resolved

(reactiveVal)

old_picks

(picks)

data

(any asserted further in resolver)

Value

The result of changing the picks_resolved reactiveVal given as argument. It returns NULL if it does nothing.


Update reactive values with log

Description

Update reactive values only if values differ to avoid unnecessary reactive trigger

Usage

.update_rv(rv, value, log)

Arguments

rv

(reactiveVal)

value

(vector)

log

(character(1)) message to log_debug

Value

the result of reactiveVal update if new value is different, NULL otherwise.


Check if datasets can be merged in topological order

Description

Determines the topological order from join_keys, then checks that each dataset can be joined with at least one of the previously accumulated datasets.

Usage

.validate_join_keys(selectors, join_keys)

Arguments

selectors

(⁠named list⁠) A named list of selector objects. Each element can be:

  • A picks object defining dataset and variable selections

  • A reactive expression returning a picks object The names of this list are used as identifiers for tracking which variables come from which selector.

join_keys

(join_keys) The join keys object

Value

TRUE if validation passes, otherwise raises a validation error with details on which datasets cannot be merged and why.


Convert data_extract_spec to picks

Description

[Experimental] Helper functions to ease transition between teal.transform::data_extract_spec() and picks().

Usage

as.picks(x, quiet = FALSE)

teal_transform_filter(x, label = "Filter")

Arguments

x

(data_extract_spec, select_spec, filter_spec) object to convert to picks

quiet

(logical(1)) whether to suppress warnings about non-convertible elements.

label

(character(1)) Label of the module.

Details

With introduction of picks, data_extract_spec will no longer serve a primary tool to define variable choices and default selection in teal-modules and eventually data_extract_spec will be deprecated. To ease the transition to the new tool, we provide as.picks method which can handle 1:1 conversion from data_extract_spec to picks. Unfortunately, when data_extract_spec contains filter_spec then as.picks is unable to provide reliable picks equivalent.

Value

A picks object when conversion is possible, otherwise NULL with a warning (if quiet = FALSE).

Examples

# convert des with eager select_spec
as.picks(
  teal.transform::data_extract_spec(
    dataname = "iris",
    teal.transform::select_spec(
      choices = c("Sepal.Length", "Sepal.Width", "Species"),
      selected = c("Sepal.Length", "Species"),
      multiple = TRUE,
      ordered = TRUE
    )
  )
)

# convert des with delayed select_spec
as.picks(
  teal.transform::data_extract_spec(
    dataname = "iris",
    teal.transform::select_spec(
      choices = teal.transform::variable_choices("iris"),
      selected = teal.transform::first_choice(),
      multiple = TRUE,
      ordered = TRUE
    )
  )
)

as.picks(
  teal.transform::data_extract_spec(
    dataname = "iris",
    teal.transform::select_spec(
      choices = teal.transform::variable_choices(
        "iris",
        subset = function(data) names(Filter(is.numeric, data))
      ),
      selected = teal.transform::first_choice(),
      multiple = TRUE,
      ordered = TRUE
    )
  )
)

# teal_transform_module build on teal.transform

teal_transform_filter(
  teal.transform::data_extract_spec(
    dataname = "iris",
    filter = teal.transform::filter_spec(
      vars = "Species",
      choices = c("setosa", "versicolor", "virginica"),
      selected = c("setosa", "versicolor")
    )
  )
)

teal_transform_filter(
  picks(
    datasets(choices = "iris", select = "iris"),
    variables(choices = "Species", "Species"),
    values(
      choices = c("setosa", "versicolor", "virginica"),
      selected = c("setosa", "versicolor")
    )
  )
)


Drop-down badge

Description

Drop-down button in a form of a badge with bg-primary as default style Clicking badge shows a drop-down containing any HTML element. Folded drop-down doesn't trigger display output which means that items rendered using ⁠render*⁠ will be recomputed only when drop-down is show.

Usage

badge_dropdown(id, label, content)

Arguments

id

(character(1)) shiny module's id

label

(shiny.tag) Label displayed on a badge.

content

(shiny.tag) Content of a drop-down.

Value

A shiny.tag object representing a drop-down badge component to display the options.


Fixed badge

Description

Fixed badge

Usage

badge_fixed(id, label, content)

Arguments

id

(character(1)) shiny module's id

label

(shiny.tag) Label displayed on a badge.

content

(shiny.tag) Content of a drop-down.

Value

A shiny.tag object representing a fixed badge component to display the selected option.


Checks varname argument and convert to call

Description

Checks varname type and parse if it's a character.

Usage

call_check_parse_varname(varname)

Arguments

varname

(name or call or character(1)) name of the variable

Value

the parsed varname.


Choices condition call

Description

Compose choices condition call from inputs.

Usage

call_condition_choice(varname, choices)

Arguments

varname

(name or call or character(1)) name of the variable.

choices

(vector) varname values to match using the == (single value) or %in% (vector) condition.

Details

choices can be vector of any type but for some output might be converted:

One has to be careful here as formatted date-time variable might loose some precision (see format argument in format.POSIXlt() and output call could be insufficient for exact comparison. In this case one should specify ⁠varname = trunc(<varname>)⁠ and possibly convert choices to character).

Value

call.


logical variable condition call

Description

Compose logical variable condition call from inputs.

Usage

call_condition_logical(varname, choice)

Arguments

varname

(name or character(1)) name of the variable

choice

(logical(1)) chosen value

Value

call.


numeric range condition call

Description

Compose numeric range condition call from inputs.

Usage

call_condition_range(varname, range)

Arguments

varname

(name or character(1)) name of the variable.

range

(numeric(2)) range of the variable.

Value

call.


Date range condition call

Description

Compose Date range condition call from inputs.

Usage

call_condition_range_date(varname, range)

Arguments

varname

(name or character(1)) name of the variable.

range

(Date) range of the variable.

Value

call.


POSIXct range condition call

Description

Compose POSIXct range condition call from inputs.

Usage

call_condition_range_posixct(varname, range, timezone = Sys.timezone())

Arguments

varname

(name or character(1)) name of the variable.

range

(POSIXct) range of the variable. Be aware that output uses truncated range format "%Y-%m-%d %H:%M:%S", which means that some precision might be lost.

timezone

(character(1)) specifies the time zone to be used for the conversion. By default Sys.timezone() is used.

Value

call.


Combine calls by operator

Description

Combine list of calls by specific operator.

Usage

calls_combine_by(operator, calls)

Arguments

operator

(character(1) or name) name / symbol of the operator.

calls

(list of calls) list containing calls to be combined by operator.

Value

A combined call.


Assert level

Description

Assert level

Usage

check_last_level(x, class)

assert_last_level(x, class, .var.name = checkmate::vname(x), add = NULL)

Arguments

x

picks object

class

Class of the last element of picks

.var.name

[character(1)]
The custom name for x as passed to any assert* function. Defaults to a heuristic name lookup.

add

[AssertCollection]
Collection to store assertion messages. See AssertCollection.

Value

For check_last_level a logical value or a string. For assert_last_level invisibly the object checked or an error.

Examples

x <- picks(datasets(), variables(), values())
assert_last_level(x, "values")

A method that should take a type and resolve it.

Description

Generic that makes the minimal check on spec. Responsible of subsetting/extract the data received and check that the type matches

Usage

determine(x, data)

Arguments

x

The specification to resolve.

data

The minimal data required.

Value

A list with two elements, the type resolved and the data extracted.


Helper functions to check pick attributes

Description

Helper functions for pick objects generated from datasets(), variables() or values():

Usage

is_pick_multiple(x)

is_pick_fixed(x)

is_pick_ordered(x)

Arguments

x

(datasets, variables or values) pick to check.

Value

TRUE if the pick has the attribute set to TRUE, FALSE otherwise.

Examples

p <- picks(datasets("iris"), variables(), values())

is_pick_multiple(p$variables)

is_pick_fixed(p$variables)

is_pick_ordered(p$variables)

Declare interaction variable pairs for tidyselect

Description

Used inside tidyselect expressions to declare a pair of variables that interact with each other. The pair is recorded in the selection environment and the positions of both variables within the available variables are returned.

Usage

interaction_vars(
  var1,
  var2,
  vars = tidyselect::peek_vars(fn = "interaction_vars")
)

Arguments

var1

An unquoted variable name.

var2

An unquoted variable name that interacts with var1.

vars

Character vector of available variable names, retrieved automatically via tidyselect::peek_vars().

Value

An integer vector of length 2 giving the positions of var1 and var2 in vars, or NA where a variable is not found.

Examples

picks(
  datasets("ADAE"),
  variables(
    c(AGE, RACE, interaction_vars("COUNTRY", "RACE")),
    selected = "COUNTRY:RACE",
    multiple = TRUE
  ),
  values()
)

Merge Server Function for Dataset Integration

Description

merge_srv is a powerful Shiny server function that orchestrates the merging of multiple datasets based on user selections from picks objects. It creates a reactive merged dataset (teal_data object) and tracks which variables from each selector are included in the final merged output.

This function serves as the bridge between user interface selections (managed by selectors) and the actual data merging logic. It automatically handles:

Usage

merge_srv(
  id,
  data,
  selectors,
  output_name = "anl",
  join_fun = "dplyr::inner_join"
)

Arguments

id

(character(1)) Module ID for the Shiny module namespace

data

(reactive) A reactive expression returning a teal.data::teal_data object containing the source datasets to be merged. This object must have join keys defined via teal.data::join_keys() to enable proper dataset relationships.

selectors

(⁠named list⁠) A named list of selector objects. Each element can be:

  • A picks object defining dataset and variable selections

  • A reactive expression returning a picks object The names of this list are used as identifiers for tracking which variables come from which selector.

output_name

(character(1)) Name of the merged dataset that will be created in the returned teal_data object. Default is "anl". This name will be used in the generated R code.

join_fun

(character(1)) The joining function to use for merging datasets. Must be a qualified function name (e.g., "dplyr::left_join", "dplyr::inner_join", "dplyr::full_join"). Default is "dplyr::inner_join". The function must accept by and suffix parameters.

Value

A list with two reactive elements:

How It Works

The merge_srv function performs the following steps:

  1. Receives Input Data: Takes a reactive teal_data object containing source datasets with defined join keys

  2. Processes Selectors: Evaluates each selector (whether static picks or reactive) to determine which datasets and variables are selected

  3. Determines Merge Order: Uses topological sort based on the join_keys to determine the optimal order for merging datasets.

  4. Handles Variable Conflicts: Automatically renames variables when:

    • Multiple selectors choose variables with the same name from different datasets

    • Foreign key variables would conflict with existing variables

    • Renaming follows the pattern ⁠{column-name}_{dataset-name}⁠

  5. Performs Merge: Generates and executes merge code that:

    • Selects only required variables from each dataset

    • Applies any filters defined in selectors

    • Joins datasets using specified join function and join keys

    • Maintains reproducibility through generated R code

  6. Updates Join Keys: Creates new join key relationships for the merged dataset ("anl") relative to remaining datasets in the teal_data object

  7. Tracks Variables: Keeps track of the variable names in the merged dataset

Usage Pattern

# In your Shiny server function
merged <- merge_srv(
  id = "merge",
  data = shiny::reactive(my_teal_data),
  selectors = list(
    selector1 = picks(...),
    selector2 = shiny::reactive(picks(...))
  ),
  output_name = "anl",
  join_fun = "dplyr::left_join"
)

# Access merged data
merged_data <- merged$data()  # teal_data object with merged dataset
anl <- merged_data[["anl"]]   # The actual merged data.frame/tibble

# Get variable mapping
vars <- merged$variables()
# Returns: list(selector1 = c("VAR1", "VAR2"), selector2 = c("VAR3", "VAR4_ADSL"))

# Get reproducible code
code <- teal.code::get_code(merged_data)

Merge Logic Details

Dataset Order: Datasets are merged in topological order based on join keys. The first dataset acts as the "left" side of the join, and subsequent datasets are joined one by one.

Join Keys: The function uses join keys from the source teal_data object to determine:

Variable Selection: For each dataset being merged:

Conflict Resolution: When variable names conflict:

Integration with Selectors

merge_srv is designed to work with picks_srv() which creates selector objects:

# Create selectors in server
selectors <- picks_srv(
  picks =  list(
    adsl = picks(...),
    adae = picks(...)
  ),
  data = data
)

# Pass to merge_srv
merged <- merge_srv(
  id = "merge",
  data = data,
  selectors = selectors
)

See Also

Examples

# Complete example with CDISC data
library(teal.picks)
library(teal.data)
library(shiny)

# Prepare data with join keys
data <- teal_data()
data <- within(data, {
  ADSL <- teal.data::rADSL
  ADAE <- teal.data::rADAE
})
join_keys(data) <- default_cdisc_join_keys[c("ADSL", "ADAE")]

# Create Shiny app
ui <- fluidPage(
  picks_ui("adsl", picks(datasets("ADSL"), variables())),
  picks_ui("adae", picks(datasets("ADAE"), variables())),
  verbatimTextOutput("code"),
  verbatimTextOutput("vars")
)

server <- function(input, output, session) {
  # Create selectors
  selectors <- list(
    adsl = picks_srv("adsl",
      data = shiny::reactive(data),
      picks = picks(datasets("ADSL"), variables())
    ),
    adae = picks_srv("adae",
      data = shiny::reactive(data),
      picks = picks(datasets("ADAE"), variables())
    )
  )

  # Merge datasets
  merged <- merge_srv(
    id = "merge",
    data = shiny::reactive(data),
    selectors = selectors,
    output_name = "anl",
    join_fun = "dplyr::left_join"
  )

  # Display results
  output$code <- renderPrint({
    cat(teal.code::get_code(merged$data()))
  })

  output$vars <- renderPrint({
    merged$variables()
  })
}
if (interactive()) {
  shinyApp(ui, server)
}


Choices/selected settings

Description

Define choices and default selection for variables. picks allows app-developer to specify datasets, variables and values to be selected by app-user during Shiny session. Functions are based on the idea of choices/selected where app-developer provides choices and what is selected by default. App-user changes selected interactively (see picks_module).

Usage

picks(..., check_dataset = TRUE)

datasets(choices = tidyselect::everything(), selected = 1L, fixed = NULL, ...)

variables(
  choices = tidyselect::everything(),
  selected = 1L,
  multiple = NULL,
  fixed = NULL,
  ordered = FALSE,
  ...
)

values(
  choices = function(x) !is.na(x),
  selected = function(x) !is.na(x),
  multiple = TRUE,
  fixed = NULL,
  ...
)

Arguments

...

for picks(...): hierarchical structure that contains datasets() as first element and optionally variables() and values()

for variables(...) and values(...): additional arguments delivered to pickerInput

check_dataset

(logical(1)) whether to check that the first element of picks is datasets(). This is useful to set to FALSE when creating picks objects that have a required dataset that is not selected by the user and defined in the module itself.

choices

(tidyselect::language or character) Available values to choose.

selected

(tidyselect::language or character) Choices to be selected.

fixed

(logical(1)) selection will be fixed and not possible to change interactively.

multiple

(logical(1)) if more than one selection is possible.

ordered

(logical(1)) if the selected should follow the selection order. If FALSE selected returned from srv_module_input() would be ordered according to order in choices.

Value

For picks() it returns an object of picks class, which is a list of pick objects with additional attributes for Shiny interactivity. For datasets(), variables(), and values() it returns a pick object with class corresponding to the type of selection including the choices and selected values.

tidyselect support

Both choices and selected parameters support tidyselect syntax, enabling dynamic and flexible variable selection patterns. This allows choices to be determined at runtime based on data characteristics rather than hard-coded values.

Using tidyselect for choices and selected

When choices uses tidyselect, the available options are determined dynamically based on actually selected data:

The selected parameter can use the same syntax but it will be applied to the subset defined in choices. This means that ⁠choices = is.numeric, selected = is.factor⁠ or ⁠choices = c("a", "b", "c"), selected = c("d", "e")⁠ will imply en empty selected.

Warning: Using explicit character values for selected with dynamic choices may cause issues if the selected values are not present in the dynamically determined choices. Prefer using numeric indices (e.g., 1 for first variable) when choices is dynamic.

Structure and element dependencies

The picks() function creates a hierarchical structure where elements depend on their predecessors, enabling cascading reactive updates during Shiny sessions.

Element hierarchy

A picks object must follow this order:

  1. datasets() - to select a dataset. Always the first element (required).

  2. variables() - To select columns from the chosen dataset.

  3. values() - To select specific values from the chosen variable(s).

Each element's choices are evaluated within the context of its predecessor's selection.

How dependencies work

Best practices

Important: values() requires type-aware configuration

Why values() is different from datasets() and variables()

datasets() and variables() operate on named lists of objects, meaning they work with character-based identifiers. This allows you to use text-based selectors like starts_with("S") or contains("prefix") consistently for both datasets and variable names.

values() is fundamentally different because it operates on the actual data content within a selected variable (column). The type of data in the column determines what kind of filtering makes sense:

Type-specific UI controls

The values() function automatically renders different UI controls based on data type:

Developer responsibility

App developers must ensure values() configuration matches the variable type:

  1. Know your data: Understand what type of variable(s) users might select

  2. Configure appropriately: Set choices and selected to match expected data types

  3. Use predicates for flexibility: When variable type is dynamic, use predicate functions like function(x) !is.na(x) (the default) to handle multiple types safely

Examples of correct usage
# For a numeric variable (e.g., age)
picks(
  datasets(choices = "demographic"),
  variables(choices = "age", multiple = FALSE),
  values(choices = c(0, 100), selected = c(18, 65))
)

# For a categorical variable (e.g., country)
picks(
  datasets(choices = "demographic"),
  variables(choices = "country", multiple = FALSE),
  values(choices = c("USA", "Canada", "Mexico"), selected = "USA")
)

# Safe approach when variable type is unknown - use predicates
picks(
  datasets(choices = "demographic"),
  variables(choices = tidyselect::everything(), selected = 1L),
  values(choices = function(x) !is.na(x), selected = function(x) !is.na(x))
)
Common mistakes to avoid
# WRONG: Using string selectors for numeric data
values(choices = starts_with("5"))  # Doesn't make sense for numeric data!

# WRONG: Providing categorical choices for a numeric variable
values(choices = c("low", "medium", "high"))  # Won't work if variable is numeric!

# WRONG: Providing numeric range for categorical variable
values(choices = c(0, 100))  # Won't work if variable is factor/character!

Example: Three-level hierarchy

picks(
  datasets(choices = c("iris", "mtcars"), selected = "iris"),
  variables(choices = tidyselect::where(is.numeric), selected = 1L),
  values(choices = tidyselect::everything(), selected = seq_len(10))
)

In this example:

Examples

# Select columns from iris dataset using range selector
picks(
  datasets(choices = "iris"),
  variables(choices = Sepal.Length:Petal.Width, selected = 1L)
)

# Single variable selection from iris dataset
picks(
  datasets(choices = "iris", selected = "iris"),
  variables(choices = c("Sepal.Length", "Sepal.Width"), selected = "Sepal.Length", multiple = FALSE)
)

# Dynamic selection: any variable from iris, first selected by default
picks(
  datasets(choices = "iris", selected = "iris"),
  variables(choices = tidyselect::everything(), selected = 1L, multiple = FALSE)
)

# Multiple dataset choices: variable choices will update when dataset changes
picks(
  datasets(choices = c("iris", "mtcars"), selected = "iris"),
  variables(choices = tidyselect::everything(), selected = 1L, multiple = FALSE)
)

# Select from any dataset, filter by numeric variables
picks(
  datasets(choices = c("iris", "mtcars"), selected = 1L),
  variables(choices = tidyselect::where(is.numeric), selected = 1L)
)

# Fully dynamic: auto-discover datasets and variables
picks(
  datasets(choices = tidyselect::where(is.data.frame), selected = 1L),
  variables(choices = tidyselect::everything(), selected = 1L, multiple = FALSE)
)

# Select categorical variables with length constraints
picks(
  datasets(choices = tidyselect::everything(), selected = 1L),
  variables(choices = is_categorical(min.len = 2, max.len = 15), selected = seq_len(2))
)


Interactive picks

Description

Creates UI and server components for interactive picks() in Shiny modules. The module is based on configuration provided via picks() and its responsibility is to determine relevant input values

The module supports both single and combined picks:

Usage

picks_ui(id, picks, container = "badge_dropdown")

## S3 method for class 'list'
picks_ui(id, picks, container)

## S3 method for class 'picks'
picks_ui(id, picks, container)

picks_srv(id = "", picks, data)

## S3 method for class 'list'
picks_srv(id, picks, data)

## S3 method for class 'picks'
picks_srv(id, picks, data)

Arguments

id

(character(1)) Shiny module ID

picks

(picks or list) object created by picks() or a named list of such objects

container

(character(1) or function) UI container type. Can be one of htmltools::tags functions. By default, elements are wrapped in a package-specific drop-down.

data

(reactive) Reactive expression returning the data object to be used for populating choices

Details

The module uses S3 method dispatch to handle different ways to provide picks:

The UI component (picks_ui) creates the visual elements, while the server component (picks_srv) manages the reactive logic,

Value

See Also

picks() for creating 'picks“ objects

Examples

library(shiny)

example_pick <- picks(
  datasets("ADSL"),
  variables(selected = c("SEX", "COUNTRY", "ARMCD"))
)
ui <- fluidPage(
  picks_ui("my_picks", picks = example_pick),
  h4("Resolved picks:"),
  verbatimTextOutput("result"),
  h4("Table:"),
  tableOutput("table")
)
server <- function(input, output, session) {
  data <- teal.data::teal_data("ADSL" = teal.data::rADSL)
  teal.data::join_keys(data) <- teal.data::default_cdisc_join_keys["ADSL"]
  selectors <- picks_srv(
    picks = list(my_picks = example_pick),
    data = reactive(data)
  )
  anl <- merge_srv("merge", data = reactive(data), selectors = selectors)
  output$result <- renderPrint(cat(gsub("\033\\[[0-9;]*m", "", format(selectors$my_picks()))))
  output$table <- renderTable(anl$data()$anl)
}

if (interactive()) {
  shinyApp(ui, server)
}

Select a range

Description

Helper to work with ranges. Setting choices or selected to range using ranged() in any of them will automatically create a numeric, Date or POSIXct input to filter. variables(choices) must only refer to numeric, Date, or POSIXct columns. An informative error is raised if the resolved column type is unsupported.

Usage

ranged(min = -Inf, max = Inf)

Arguments

min

(numeric(1)) Minimal value.

max

(numeric(1)) Maximal value.

Value

A function that allows the use of a range in choices or selected of values() in numeric, Date, or POSIXct variables.

Examples

p <- picks(
  datasets(choices = "mtcars"),
  variables(choices = is.numeric, selected = 1),
  values(choices = ranged(), ranged(20, 30))
)
resolver(data = list("mtcars label" = mtcars), x = p)

Resolve picks

Description

Resolve iterates through each picks element and determines values .

Usage

resolver(x, data)

Arguments

x

(picks()) settings for picks.

data

(teal_data() environment or list) any data collection supporting object extraction with [[. Used to determine values of unresolved picks.

Value

resolved picks.

Examples

x <- picks(datasets(tidyselect::where(is.data.frame)), variables("a", "a"))
data <- list(
  df1 = data.frame(a = as.factor(LETTERS[1:5]), b = letters[1:5]),
  df2 = data.frame(a = LETTERS[1:5], b = 1:5),
  m = matrix()
)
resolver(x = x, data = data)

Restore value from bookmark.

Description

Get value from bookmark or return default.

Usage

restoreValue(value, default)

Arguments

value

(character(1)) name of value to restore

default

fallback value

Details

Bookmarks can store not only inputs but also arbitrary values. These values are stored by onBookmark callbacks and restored by onBookmarked callbacks, and they are placed in the values environment in the session$restoreContext field. Using teal_data_module makes it impossible to run the callbacks because the app becomes ready before modules execute and callbacks are registered. In those cases the stored values can still be recovered from the session object directly.

Note that variable names in the values environment are prefixed with module name space names, therefore, when using this function in modules, value must be run through the name space function.

Value

In an application restored from a server-side bookmark, the variable specified by value from the values environment. Otherwise default.


tidyselect helpers

Description

#' [Experimental] Predicate functions simplifying picks specification.

Usage

is_categorical(min.len, max.len)

Arguments

min.len

(integer(1)) minimal number of unique values

max.len

(integer(1)) maximal number of unique values

Value

A tidyselector that can be used directly in choices or selected of variables() in picks().

Examples

# select factor column but exclude foreign keys
variables(choices = is_categorical(min.len = 2, max.len = 10))

# Supports tidyselect helpers, e.g. to select all categorical variables with 2 to 10 unique values
dplyr::select(iris, dplyr::where(is_categorical(2, 10)))

p <- picks(
  datasets(is.data.frame, 2L),
  variables(is_categorical(2, 10))
)
resolver(data = list(mtcars = mtcars, iris = iris), x = p)

Merge module

Description

Example teal::module containing interactive inputs and displaying results of merge.

Usage

tm_merge(label = "merge-module", picks, transformators = list())

Arguments

label

(character(1)) Label shown in the navigation item for the module or module group. For modules() defaults to "root". See Details.

picks

(list of picks)

transformators

(list of teal_transform_module) that will be applied to transform module's data input. To learn more check vignette("transform-input-data", package = "teal").

Value

A teal::module object that merges datasets based on user selections and displays the results.

Examples

library(teal)

data <- within(teal.data::teal_data(), {
  iris <- iris
  mtcars <- mtcars
})

app <- init(
  data = data,
  modules = modules(
    modules(
      label = "Testing modules",
      tm_merge(
        label = "non adam",
        picks = list(
          a = picks(
            datasets("iris", "iris"),
            variables(
              choices = c("Sepal.Length", "Species"),
              selected = "Sepal.Length"
            ),
            values()
          )
        )
      )
    )
  )
)
if (interactive()) {
  shinyApp(app$ui, app$server, enableBookmarking = "server")
}