% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/picks.R
\name{picks}
\alias{picks}
\alias{datasets}
\alias{variables}
\alias{values}
\title{Choices/selected settings}
\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{
\item{...}{for \code{picks(...)}: hierarchical structure that contains \code{datasets()} as first element
and optionally \code{variables()} and \code{values()}

for \code{variables(...)} and \code{values(...)}: additional arguments delivered to \code{pickerInput}}

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

\item{choices}{(\code{tidyselect::language} or \code{character})
Available values to choose.}

\item{selected}{(\code{tidyselect::language} or \code{character})
Choices to be selected.}

\item{fixed}{(\code{logical(1)}) selection will be fixed and not possible to change interactively.}

\item{multiple}{(\code{logical(1)}) if more than one selection is possible.}

\item{ordered}{(\code{logical(1)}) if the selected should follow the selection order. If \code{FALSE}
\code{selected} returned from \code{srv_module_input()} would be ordered according to order in \code{choices}.}
}
\value{
For \code{picks()} it returns an object of \code{picks} class, which is a list of \code{pick} objects with additional
attributes for Shiny interactivity.
For \code{datasets()}, \code{variables()}, and \code{values()} it returns a \code{pick} object with
class corresponding to the type of selection including the choices and selected values.
}
\description{
Define choices and default selection for variables. \code{picks} allows app-developer to specify
\code{datasets}, \code{variables} and \code{values} to be selected by app-user during Shiny session.
Functions are based on the idea of \code{choices/selected} where app-developer provides \code{choices}
and what is \code{selected} by default. App-user changes \code{selected} interactively (see \code{\link{picks_module}}).
}
\section{\code{tidyselect} support}{
Both \code{choices} and \code{selected} parameters support \code{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.
\subsection{Using \code{tidyselect} for \code{choices} and \code{selected}}{

When \code{choices} uses \code{tidyselect}, the available options are determined dynamically based on actually
selected data:
\itemize{
\item \code{tidyselect::everything()} - All variables/datasets
\item \code{tidyselect::starts_with("prefix")} - Variables starting with a prefix
\item \code{tidyselect::ends_with("suffix")} - Variables ending with a suffix
\item \code{tidyselect::contains("pattern")} - Variables containing a pattern
\item \code{tidyselect::matches("regex")} - Variables matching a regular expression
\item \code{tidyselect::where(predicate)} - Variables/datasets satisfying a predicate function
\item \code{tidyselect::all_of(vars)} - All specified variables (error if missing)
\item \code{tidyselect::any_of(vars)} - Any specified variables (silent if missing)
\item Range selectors like \code{Sepal.Length:Petal.Width} - Variables between two positions
\item Integer indices (e.g., \code{1L}, \code{1L:3L}, \code{c(1L, 3L, 5L)}) - Select by position. Be careful, must be integer!
}

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

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

\section{Structure and element dependencies}{
The \code{picks()} function creates a hierarchical structure where elements depend on their
predecessors, enabling cascading reactive updates during Shiny sessions.
\subsection{Element hierarchy}{

A \code{picks} object must follow this order:
\enumerate{
\item \strong{\code{datasets()}} - to select a dataset. Always the first element (required).
\item \strong{\code{variables()}} - To select columns from the chosen dataset.
\item \strong{\code{values()}} - To select specific values from the chosen variable(s).
}

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

\subsection{How dependencies work}{
\itemize{
\item \strong{Fixed dataset}: When \code{datasets(choices = "iris")} specifies one dataset, the
\code{variables()} choices are evaluated against that dataset columns.
\item \strong{Multiple dataset choices}: When \code{datasets(choices = c("iris", "mtcars"))} allows multiple
options, \code{variables()} choices are re-evaluated each time the user selects a different
dataset. This creates a reactive dependency where variable choices update automatically.
\item \strong{Dynamic dataset choices}: When using \code{datasets(choices = tidyselect::where(is.data.frame))},
all available data frames are discovered at runtime, and variable choices adapt to
whichever dataset the user selects.
\item \strong{Variable to values}: Similarly, \code{values()} choices are evaluated based on the
selected variable(s), allowing users to filter specific levels or values. When multiple
variables are selected, then values will be a concatenation of the columns.
}
}

\subsection{Best practices}{
\itemize{
\item Always start with \code{datasets()} - this is enforced by validation
\item Use dynamic \code{choices} in \code{variables()} when working with multiple datasets to ensure
compatibility across different data structures
\item Prefer \code{tidyselect::everything()} or \code{tidyselect::where()} predicates for flexible
variable selection that works across datasets with different schemas
\item Use numeric indices for \code{selected} when \code{choices} are dynamic to avoid referencing
variables that may not exist in all datasets
}
}

\subsection{Important: \code{values()} requires type-aware configuration}{
\subsection{Why \code{values()} is different from \code{datasets()} and \code{variables()}}{

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

\code{values()} is fundamentally different because it operates on the \strong{actual data content} within a
selected variable (column). The type of data in the column determines what kind of filtering makes sense:
\itemize{
\item \strong{\code{numeric} columns} (e.g., \code{age}, \code{height}, \code{price}) contain numbers
\item \strong{\code{character}/\code{factor} columns} (e.g., \code{country}, \code{category}, \code{status}) contain categorical values
\item \strong{\code{Date}/\code{POSIXct} columns} contain temporal data
\item \strong{\code{logical} columns} contain TRUE/FALSE values
}
}

\subsection{Type-specific UI controls}{

The \code{values()} function automatically renders different UI controls based on data type:
\itemize{
\item \strong{\code{numeric} data}: Creates a \code{sliderInput} for range selection
\itemize{
\item \code{choices} must be a numeric vector of length 2: \code{c(min, max)}
\item \code{selected} must be a numeric vector of length 2: \code{c(selected_min, selected_max)}
}
\item \strong{Categorical data} (\code{character}/\code{factor}): Creates a \code{pickerInput} for discrete selection
\itemize{
\item \code{choices} can be a character vector or predicate function
\item \code{selected} can be specific values or a predicate function
}
\item \strong{\code{Date}/\code{POSIXct} data}: Creates date/datetime range selectors
\itemize{
\item \code{choices} must be a Date or \code{POSIXct} vector of length 2
}
\item \strong{\code{logical} data}: Creates a checkbox or picker for TRUE/FALSE selection
}
}

\subsection{Developer responsibility}{

\strong{App developers must ensure \code{values()} configuration matches the variable type:}
\enumerate{
\item \strong{Know your data}: Understand what type of variable(s) users might select
\item \strong{Configure appropriately}: Set \code{choices} and \code{selected} to match expected data types
\item \strong{Use predicates for flexibility}: When variable type is dynamic, use predicate functions
like \code{function(x) !is.na(x)} (the default) to handle multiple types safely
}
}

\subsection{Examples of correct usage}{

\if{html}{\out{<div class="sourceCode r">}}\preformatted{# 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))
)
}\if{html}{\out{</div>}}
}

\subsection{Common mistakes to avoid}{

\if{html}{\out{<div class="sourceCode r">}}\preformatted{# 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!
}\if{html}{\out{</div>}}
}

}

\subsection{Example: Three-level hierarchy}{

\if{html}{\out{<div class="sourceCode r">}}\preformatted{picks(
  datasets(choices = c("iris", "mtcars"), selected = "iris"),
  variables(choices = tidyselect::where(is.numeric), selected = 1L),
  values(choices = tidyselect::everything(), selected = seq_len(10))
)
}\if{html}{\out{</div>}}

In this example:
\itemize{
\item User first selects a dataset (\code{iris} or \code{mtcars})
\item Variable choices update to show only numeric columns from selected dataset
\item After selecting a variable, value choices show all unique values from that column
}
}
}

\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))
)

}
