Type: Package
Title: Filter Module for 'teal' Applications
Version: 0.6.0
Date: 2025-01-31
Description: Data filtering module for 'teal' applications. Allows for interactive filtering of data stored in 'data.frame' and 'MultiAssayExperiment' objects. Also displays filtered and unfiltered observation counts.
License: Apache License 2.0
URL: https://insightsengineering.github.io/teal.slice/, https://github.com/insightsengineering/teal.slice/
BugReports: https://github.com/insightsengineering/teal.slice/issues
Depends: R (≥ 4.0)
Imports: bslib (≥ 0.4.0), checkmate (≥ 2.1.0), dplyr (≥ 1.0.5), grDevices, htmltools (≥ 0.5.4), jsonlite, lifecycle (≥ 0.2.0), logger (≥ 0.3.0), methods, plotly (≥ 4.9.2.2), R6 (≥ 2.2.0), rlang (≥ 1.0.0), shiny (≥ 1.6.0), shinycssloaders (≥ 1.0.0), shinyjs, shinyWidgets (≥ 0.6.2), teal.data (≥ 0.7.0), teal.logger (≥ 0.3.1), teal.widgets (≥ 0.4.3), utils
Suggests: knitr (≥ 1.42), MultiAssayExperiment, rmarkdown (≥ 2.23), SummarizedExperiment, testthat (≥ 3.2.2), withr (≥ 3.0.2)
VignetteBuilder: knitr, rmarkdown
RdMacros: lifecycle
Config/Needs/verdepcheck: rstudio/shiny, rstudio/bslib, mllg/checkmate, tidyverse/dplyr, rstudio/htmltools, jeroen/jsonlite, r-lib/lifecycle, daroczig/logger, plotly/plotly, r-lib/R6, daattali/shinycssloaders, daattali/shinyjs, dreamRs/shinyWidgets, insightsengineering/teal.data, insightsengineering/teal.logger, insightsengineering/teal.widgets, yihui/knitr, bioc::MultiAssayExperiment, bioc::SummarizedExperiment, rstudio/rmarkdown, r-lib/testthat, r-lib/withr, bioc::matrixStats
Config/Needs/website: insightsengineering/nesttemplate
Encoding: UTF-8
Language: en-US
RoxygenNote: 7.3.2
NeedsCompilation: no
Packaged: 2025-02-03 22:48:04 UTC; unardid
Author: Dawid Kaledkowski ORCID iD [aut, cre], Pawel Rucki [aut], Aleksander Chlebowski ORCID iD [aut], Andre Verissimo ORCID iD [aut], Kartikeya Kirar [aut], Marcin Kosinski [aut], Chendi Liao [rev], Dony Unardi [rev], Andrew Bates [aut], Mahmoud Hallal [aut], Nikolas Burkoff [aut], Maciej Nasinski [aut], Konrad Pagacz [aut], Junlue Zhao [aut], F. Hoffmann-La Roche AG [cph, fnd]
Maintainer: Dawid Kaledkowski <dawid.kaledkowski@roche.com>
Repository: CRAN
Date/Publication: 2025-02-03 23:40:02 UTC

teal.slice: Interactive Exploration of Clinical Trials Data

Description

teal.slice is an R library used in the development of teal shiny modules.

Author(s)

Maintainer: Dawid Kaledkowski dawid.kaledkowski@roche.com (ORCID)

Authors:

Other contributors:

See Also

Useful links:


Destroys inputs and observers stored in private$session_bindings

Description

Call a destroy method to remove observer and input from obsolete session which happens when filter_panel_srv is called again in new FilteredData object. Inputs are not stored directly in a field as they don't have destroy method. Instead, we store callback destroy function for inputs which removes bindings from a session.

Usage

.finalize_session_bindings(self, private)

Arguments

self, private

slots of a R6 class

Value

NULL invisibly


table handling POSIXlt

Description

table handling POSIXlt

Usage

.table(x)

Arguments

x

(vector) variable to get counts from.

Value

vector of counts named by unique values of x.


FilterState object for categorical data

Description

Manages choosing elements from a set.

Super class

teal.slice::FilterState -> ChoicesFilterState

Methods

Public methods

Inherited methods

Method new()

Initialize a FilterState object.

Usage
ChoicesFilterState$new(
  x,
  x_reactive = reactive(NULL),
  slice,
  extract_type = character(0)
)
Arguments
x

(character) variable to be filtered.

x_reactive

(reactive) returning vector of the same type as x. Is used to update counts following the change in values of the filtered dataset. If it is set to reactive(NULL) then counts based on filtered dataset are not shown.

slice

(teal_slice) specification of this filter state. teal_slice is stored in the object and set_state directly manipulates values within teal_slice. get_state returns teal_slice object which can be reused in other places. Note that teal_slice is a reactiveValues, which means it has reference semantics, i.e. changes made to an object are automatically reflected in all places that refer to the same teal_slice.

extract_type

(character) specifying whether condition calls should be prefixed by dataname. Possible values:

  • character(0) (default) varname in the condition call will not be prefixed

  • "list" varname in the condition call will be returned as ⁠<dataname>$<varname>⁠

  • "matrix" varname in the condition call will be returned as ⁠<dataname>[, <varname>]⁠

Returns

Object of class ChoicesFilterState, invisibly.


Method get_call()

Returns reproducible condition call for current selection. For this class returned call looks like ⁠<varname> %in% c(<values selected>)⁠ with optional ⁠is.na(<varname>)⁠.

Usage
ChoicesFilterState$get_call(dataname)
Arguments
dataname

(character(1)) name of data set; defaults to private$get_dataname()

Returns

call or NULL


Method clone()

The objects of this class are cloneable with this method.

Usage
ChoicesFilterState$clone(deep = FALSE)
Arguments
deep

Whether to make a deep clone.

Examples

# use non-exported function from teal.slice
include_css_files <- getFromNamespace("include_css_files", "teal.slice")
include_js_files <- getFromNamespace("include_js_files", "teal.slice")
ChoicesFilterState <- getFromNamespace("ChoicesFilterState", "teal.slice")

library(shiny)

filter_state <- ChoicesFilterState$new(
  x = c(LETTERS, NA),
  slice = teal_slice(varname = "var", dataname = "data")
)
isolate(filter_state$get_call())
filter_state$set_state(
  teal_slice(
    dataname = "data",
    varname = "var",
    selected = "A",
    keep_na = TRUE
  )
)
isolate(filter_state$get_call())

# working filter in an app
library(shinyjs)

data_choices <- c(sample(letters[1:4], 100, replace = TRUE), NA)
attr(data_choices, "label") <- "lowercase letters"
fs <- ChoicesFilterState$new(
  x = data_choices,
  slice = teal_slice(
    dataname = "data", varname = "variable", selected = c("a", "c"), keep_na = TRUE
  )
)

ui <- fluidPage(
  useShinyjs(),
  include_css_files(pattern = "filter-panel"),
  include_js_files(pattern = "count-bar-labels"),
  column(4, tags$div(
    tags$h4("ChoicesFilterState"),
    fs$ui("fs")
  )),
  column(4, tags$div(
    tags$h4("Condition (i.e. call)"), # display the condition call generated by this FilterState
    textOutput("condition_choices"), tags$br(),
    tags$h4("Unformatted state"), # display raw filter state
    textOutput("unformatted_choices"), tags$br(),
    tags$h4("Formatted state"), # display human readable filter state
    textOutput("formatted_choices"), tags$br()
  )),
  column(4, tags$div(
    tags$h4("Programmatic filter control"),
    actionButton("button1_choices", "set drop NA", width = "100%"), tags$br(),
    actionButton("button2_choices", "set keep NA", width = "100%"), tags$br(),
    actionButton("button3_choices", "set selection: a, b", width = "100%"), tags$br(),
    actionButton("button4_choices", "deselect all", width = "100%"), tags$br(),
    actionButton("button0_choices", "set initial state", width = "100%"), tags$br()
  ))
)

server <- function(input, output, session) {
  fs$server("fs")
  output$condition_choices <- renderPrint(fs$get_call())
  output$formatted_choices <- renderText(fs$format())
  output$unformatted_choices <- renderPrint(fs$get_state())
  # modify filter state programmatically
  observeEvent(
    input$button1_choices,
    fs$set_state(
      teal_slice(dataname = "data", varname = "variable", keep_na = FALSE)
    )
  )
  observeEvent(
    input$button2_choices,
    fs$set_state(
      teal_slice(dataname = "data", varname = "variable", keep_na = TRUE)
    )
  )
  observeEvent(
    input$button3_choices,
    fs$set_state(
      teal_slice(dataname = "data", varname = "variable", selected = c("a", "b"))
    )
  )
  observeEvent(
    input$button4_choices,
    fs$set_state(
      teal_slice(dataname = "data", varname = "variable", selected = character(0), keep_na = TRUE)
    )
  )
  observeEvent(
    input$button0_choices,
    fs$set_state(
      teal_slice(dataname = "data", varname = "variable", selected = c("a", "c"), keep_na = TRUE)
    )
  )
}

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


FilterStates subclass for data frames

Description

Handles filter states in a data.frame.

Super class

teal.slice::FilterStates -> DFFilterStates

Methods

Public methods

Inherited methods

Method new()

Initializes DFFilterStates object by setting dataname and initializing state_list (shiny::reactiveVal). This class contains a single state_list with no specified name, which means that when calling the subset function associated with this class (dplyr::filter), a list of conditions is passed to unnamed arguments (...).

Usage
DFFilterStates$new(
  data,
  data_reactive = function(sid = "") NULL,
  dataname,
  datalabel = NULL,
  keys = character(0)
)
Arguments
data

(data.frame) the R object which dplyr::filter function will be applied on.

data_reactive

(⁠function(sid)⁠) should return a data.frame object or NULL. This object is needed for the FilterState counts being updated on a change in filters. If function returns NULL then filtered counts are not shown. Function has to have sid argument being a character.

dataname

(character) name of the data used in the subset expression. Passed to the function argument attached to this FilterStates.

datalabel

(character(1)) optional text label.

keys

(character) key column names.


Method clone()

The objects of this class are cloneable with this method.

Usage
DFFilterStates$clone(deep = FALSE)
Arguments
deep

Whether to make a deep clone.

Examples

# use non-exported function from teal.slice
include_css_files <- getFromNamespace("include_css_files", "teal.slice")
include_js_files <- getFromNamespace("include_js_files", "teal.slice")
init_filter_states <- getFromNamespace("init_filter_states", "teal.slice")

library(shiny)
library(shinyjs)

# create data frame to filter
data_df <- data.frame(
  NUM1 = 1:100,
  NUM2 = round(runif(100, min = 20, max = 23)),
  CHAR1 = sample(LETTERS[1:6], size = 100, replace = TRUE),
  CHAR2 = sample(c("M", "F"), size = 100, replace = TRUE),
  DATE = seq(as.Date("2020-01-01"), by = 1, length.out = 100),
  DATETIME = as.POSIXct(seq(as.Date("2020-01-01"), by = 1, length.out = 100))
)
data_na <- data.frame(
  NUM1 = NA,
  NUM2 = NA,
  CHAR1 = NA,
  CHAR2 = NA,
  DATE = NA,
  DATETIME = NA
)
data_df <- rbind(data_df, data_na)

# initiate `FilterStates` object
filter_states_df <- init_filter_states(
  data = data_df,
  dataname = "dataset",
  datalabel = ("label")
)

ui <- fluidPage(
  useShinyjs(),
  include_css_files(pattern = "filter-panel"),
  include_js_files(pattern = "count-bar-labels"),
  column(4, tags$div(
    tags$h4("Active filters"),
    filter_states_df$ui_active("fsdf")
  )),
  column(4, tags$div(
    tags$h4("Manual filter control"),
    filter_states_df$ui_add("add_filters"), tags$br(),
    tags$h4("Condition (i.e. call)"), # display the subset expression generated by this FilterStates
    textOutput("call_df"), tags$br(),
    tags$h4("Formatted state"), # display human readable filter state
    textOutput("formatted_df"), tags$br()
  )),
  column(4, tags$div(
    tags$h4("Programmatic filter control"),
    actionButton("button1_df", "set NUM1 < 30", width = "100%"), tags$br(),
    actionButton("button2_df", "set NUM2 %in% c(20, 21)", width = "100%"), tags$br(),
    actionButton("button3_df", "set CHAR1 %in% c(\"B\", \"C\", \"D\")", width = "100%"), tags$br(),
    actionButton("button4_df", "set CHAR2 == \"F\"", width = "100%"), tags$br(),
    actionButton("button5_df", "set DATE <= 2020-02-02", width = "100%"), tags$br(),
    actionButton("button6_df", "set DATETIME <= 2020-02-02", width = "100%"), tags$br(),
    tags$hr(),
    actionButton("button7_df", "remove NUM1", width = "100%"), tags$br(),
    actionButton("button8_df", "remove NUM2", width = "100%"), tags$br(),
    actionButton("button9_df", "remove CHAR1", width = "100%"), tags$br(),
    actionButton("button10_df", "remove CHAR2", width = "100%"), tags$br(),
    actionButton("button11_df", "remove DATE", width = "100%"), tags$br(),
    actionButton("button12_df", "remove DATETIME", width = "100%"), tags$br(),
    tags$hr(),
    actionButton("button0_df", "clear all filters", width = "100%"), tags$br()
  ))
)

server <- function(input, output, session) {
  filter_states_df$srv_add("add_filters")
  filter_states_df$srv_active("fsdf")

  output$call_df <- renderPrint(filter_states_df$get_call())
  output$formatted_df <- renderText(filter_states_df$format())

  observeEvent(input$button1_df, {
    filter_state <- teal_slices(teal_slice("dataset", "NUM1", selected = c(0, 30)))
    filter_states_df$set_filter_state(state = filter_state)
  })
  observeEvent(input$button2_df, {
    filter_state <- teal_slices(teal_slice("dataset", "NUM2", selected = c(20, 21)))
    filter_states_df$set_filter_state(state = filter_state)
  })
  observeEvent(input$button3_df, {
    filter_state <- teal_slices(teal_slice("dataset", "CHAR1", selected = c("B", "C", "D")))
    filter_states_df$set_filter_state(state = filter_state)
  })
  observeEvent(input$button4_df, {
    filter_state <- teal_slices(teal_slice("dataset", "CHAR2", selected = c("F")))
    filter_states_df$set_filter_state(state = filter_state)
  })
  observeEvent(input$button5_df, {
    filter_state <- teal_slices(
      teal_slice("dataset", "DATE", selected = c("2020-01-01", "2020-02-02"))
    )
    filter_states_df$set_filter_state(state = filter_state)
  })
  observeEvent(input$button6_df, {
    filter_state <- teal_slices(
      teal_slice("dataset", "DATETIME", selected = as.POSIXct(c("2020-01-01", "2020-02-02")))
    )
    filter_states_df$set_filter_state(state = filter_state)
  })

  observeEvent(input$button7_df, {
    filter_state <- teal_slices(teal_slice("dataset", "NUM1"))
    filter_states_df$remove_filter_state(filter_state)
  })
  observeEvent(input$button8_df, {
    filter_state <- teal_slices(teal_slice("dataset", "NUM2"))
    filter_states_df$remove_filter_state(filter_state)
  })
  observeEvent(input$button9_df, {
    filter_state <- teal_slices(teal_slice("dataset", "CHAR1"))
    filter_states_df$remove_filter_state(filter_state)
  })
  observeEvent(input$button10_df, {
    filter_state <- teal_slices(teal_slice("dataset", "CHAR2"))
    filter_states_df$remove_filter_state(filter_state)
  })
  observeEvent(input$button11_df, {
    filter_state <- teal_slices(
      teal_slice("dataset", "DATE")
    )
    filter_states_df$remove_filter_state(filter_state)
  })
  observeEvent(input$button12_df, {
    filter_state <- teal_slices(
      teal_slice("dataset", "DATETIME", selected = as.POSIXct(c("2020-01-01", "2020-02-02")))
    )
    filter_states_df$remove_filter_state(filter_state)
  })

  observeEvent(input$button0_df, filter_states_df$clear_filter_states())
}

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

The DataframeFilteredDataset R6 class

Description

The DataframeFilteredDataset R6 class

The DataframeFilteredDataset R6 class

Super class

teal.slice::FilteredDataset -> DataframeFilteredDataset

Methods

Public methods

Inherited methods

Method new()

Initializes this DataframeFilteredDataset object.

Usage
DataframeFilteredDataset$new(
  dataset,
  dataname,
  keys = character(0),
  parent_name = character(0),
  parent = NULL,
  join_keys = character(0),
  label = character(0)
)
Arguments
dataset

(data.frame) single data.frame for which filters are rendered.

dataname

(character(1)) syntactically valid name given to the dataset.

keys

(character) optional vector of primary key column names.

parent_name

(character(1)) name of the parent dataset.

parent

(reactive) that returns a filtered data.frame from other FilteredDataset named parent_name. Passing parent results in a reactive link that causes re-filtering of this dataset based on the changes in parent.

join_keys

(character) vector of names of columns in this dataset to join with parent dataset. If column names in the parent do not match these, they should be given as the names of this vector.

label

(character(1)) label to describe the dataset.

Returns

Object of class DataframeFilteredDataset, invisibly.


Method get_call()

Gets the subset expression.

This function returns subset expressions equivalent to selected items within each of filter_states. Configuration of the expressions is constant and depends on filter_states type and order which are set during initialization. This class contains single FilterStates which contains single state_list and all FilterState objects apply to one argument (...) in a dplyr::filter call.

Usage
DataframeFilteredDataset$get_call(sid = "")
Arguments
sid

(character) when specified, the method returns code containing conditions calls of FilterState objects with sid different to that of this sid argument.

Returns

Either a list of length 1 containing a filter call, or NULL.


Method set_filter_state()

Set filter state.

Usage
DataframeFilteredDataset$set_filter_state(state)
Arguments
state

(teal_slices)

Returns

NULL, invisibly.


Method remove_filter_state()

Remove one or more FilterState form a FilteredDataset.

Usage
DataframeFilteredDataset$remove_filter_state(state)
Arguments
state

(teal_slices) specifying FilterState objects to remove; teal_slices may contain only dataname and varname, other elements are ignored

Returns

NULL, invisibly.


Method ui_add()

UI module to add filter variable for this dataset.

Usage
DataframeFilteredDataset$ui_add(id)
Arguments
id

(character(1)) shiny module instance id.

Returns

shiny.tag


Method get_filter_overview()

Creates row for filter overview in the form of
dataname -- observations (remaining/total) - data.frame

Usage
DataframeFilteredDataset$get_filter_overview()
Returns

A data.frame.


Method clone()

The objects of this class are cloneable with this method.

Usage
DataframeFilteredDataset$clone(deep = FALSE)
Arguments
deep

Whether to make a deep clone.

Examples

# use non-exported function from teal.slice
DataframeFilteredDataset <- getFromNamespace("DataframeFilteredDataset", "teal.slice")

library(shiny)

ds <- DataframeFilteredDataset$new(iris, "iris")
ds$set_filter_state(
  teal_slices(
    teal_slice(dataname = "iris", varname = "Species", selected = "virginica"),
    teal_slice(dataname = "iris", varname = "Petal.Length", selected = c(2.0, 5))
  )
)
isolate(ds$get_filter_state())
isolate(ds$get_call())

## set_filter_state
dataset <- DataframeFilteredDataset$new(iris, "iris")
fs <- teal_slices(
  teal_slice(dataname = "iris", varname = "Species", selected = "virginica"),
  teal_slice(dataname = "iris", varname = "Petal.Length", selected = c(2.0, 5))
)
dataset$set_filter_state(state = fs)
isolate(dataset$get_filter_state())


FilterState object for Date data

Description

Manages choosing a range of Dates.

Super class

teal.slice::FilterState -> DateFilterState

Methods

Public methods

Inherited methods

Method new()

Initialize a FilterState object.

Usage
DateFilterState$new(
  x,
  x_reactive = reactive(NULL),
  slice,
  extract_type = character(0)
)
Arguments
x

(Date) variable to be filtered.

x_reactive

(reactive) returning vector of the same type as x. Is used to update counts following the change in values of the filtered dataset. If it is set to reactive(NULL) then counts based on filtered dataset are not shown.

slice

(teal_slice) specification of this filter state. teal_slice is stored in the object and set_state directly manipulates values within teal_slice. get_state returns teal_slice object which can be reused in other places. Note that teal_slice is a reactiveValues, which means it has reference semantics, i.e. changes made to an object are automatically reflected in all places that refer to the same teal_slice.

extract_type

(character) specifying whether condition calls should be prefixed by dataname. Possible values:

  • character(0) (default) varname in the condition call will not be prefixed

  • "list" varname in the condition call will be returned as ⁠<dataname>$<varname>⁠

  • "matrix" varname in the condition call will be returned as ⁠<dataname>[, <varname>]⁠

Returns

Object of class DateFilterState, invisibly.


Method get_call()

Returns reproducible condition call for current selection. For this class returned call looks like ⁠<varname> >= <min value> & <varname> <= <max value>⁠ with optional ⁠is.na(<varname>)⁠.

Usage
DateFilterState$get_call(dataname)
Arguments
dataname

(character(1)) containing possibly prefixed name of data set

Returns

call or NULL


Method clone()

The objects of this class are cloneable with this method.

Usage
DateFilterState$clone(deep = FALSE)
Arguments
deep

Whether to make a deep clone.

Examples

# use non-exported function from teal.slice
include_css_files <- getFromNamespace("include_css_files", "teal.slice")
include_js_files <- getFromNamespace("include_js_files", "teal.slice")
DateFilterState <- getFromNamespace("DateFilterState", "teal.slice")

library(shiny)

filter_state <- DateFilterState$new(
  x = c(Sys.Date() + seq(1:10), NA),
  slice = teal_slice(varname = "x", dataname = "data"),
  extract_type = character(0)
)
isolate(filter_state$get_call())
filter_state$set_state(
  teal_slice(
    dataname = "data",
    varname = "x",
    selected = c(Sys.Date() + 3L, Sys.Date() + 8L),
    keep_na = TRUE
  )
)
isolate(filter_state$get_call())

# working filter in an app
library(shinyjs)

dates <- c(Sys.Date() - 100, Sys.Date())
data_date <- c(seq(from = dates[1], to = dates[2], length.out = 100), NA)
fs <- DateFilterState$new(
  x = data_date,
  slice = teal_slice(
    dataname = "data", varname = "x", selected = data_date[c(47, 98)], keep_na = TRUE
  )
)

ui <- fluidPage(
  useShinyjs(),
  include_css_files(pattern = "filter-panel"),
  include_js_files(pattern = "count-bar-labels"),
  column(4, tags$div(
    tags$h4("DateFilterState"),
    fs$ui("fs")
  )),
  column(4, tags$div(
    id = "outputs", # div id is needed for toggling the element
    tags$h4("Condition (i.e. call)"), # display the condition call generated by this FilterState
    textOutput("condition_date"), tags$br(),
    tags$h4("Unformatted state"), # display raw filter state
    textOutput("unformatted_date"), tags$br(),
    tags$h4("Formatted state"), # display human readable filter state
    textOutput("formatted_date"), tags$br()
  )),
  column(4, tags$div(
    tags$h4("Programmatic filter control"),
    actionButton("button1_date", "set drop NA", width = "100%"), tags$br(),
    actionButton("button2_date", "set keep NA", width = "100%"), tags$br(),
    actionButton("button3_date", "set a range", width = "100%"), tags$br(),
    actionButton("button4_date", "set full range", width = "100%"), tags$br(),
    actionButton("button0_date", "set initial state", width = "100%"), tags$br()
  ))
)

server <- function(input, output, session) {
  fs$server("fs")
  output$condition_date <- renderPrint(fs$get_call())
  output$formatted_date <- renderText(fs$format())
  output$unformatted_date <- renderPrint(fs$get_state())
  # modify filter state programmatically
  observeEvent(
    input$button1_date,
    fs$set_state(teal_slice(dataname = "data", varname = "x", keep_na = FALSE))
  )
  observeEvent(
    input$button2_date,
    fs$set_state(teal_slice(dataname = "data", varname = "x", keep_na = TRUE))
  )
  observeEvent(
    input$button3_date,
    fs$set_state(teal_slice(dataname = "data", varname = "x", selected = data_date[c(34, 56)]))
  )
  observeEvent(
    input$button4_date,
    fs$set_state(teal_slice(dataname = "data", varname = "x", selected = dates))
  )
  observeEvent(
    input$button0_date,
    fs$set_state(
      teal_slice("data", "variable", selected = data_date[c(47, 98)], keep_na = TRUE)
    )
  )
}

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


FilterState object for date time data

Description

Manages choosing a range of date-times.

Super class

teal.slice::FilterState -> DatetimeFilterState

Methods

Public methods

Inherited methods

Method new()

Initialize a FilterState object. This class has an extra field, private$timezone, which is set to Sys.timezone() by default. However, in case when using this module in teal app, one needs timezone of the app user. App user timezone is taken from session$userData$timezone and is set only if object is initialized in shiny.

Usage
DatetimeFilterState$new(
  x,
  x_reactive = reactive(NULL),
  extract_type = character(0),
  slice
)
Arguments
x

(POSIXct or POSIXlt) variable to be filtered.

x_reactive

(reactive) returning vector of the same type as x. Is used to update counts following the change in values of the filtered dataset. If it is set to reactive(NULL) then counts based on filtered dataset are not shown.

extract_type

(character) specifying whether condition calls should be prefixed by dataname. Possible values:

  • character(0) (default) varname in the condition call will not be prefixed

  • "list" varname in the condition call will be returned as ⁠<dataname>$<varname>⁠

  • "matrix" varname in the condition call will be returned as ⁠<dataname>[, <varname>]⁠

slice

(teal_slice) specification of this filter state. teal_slice is stored in the object and set_state directly manipulates values within teal_slice. get_state returns teal_slice object which can be reused in other places. Note that teal_slice is a reactiveValues, which means it has reference semantics, i.e. changes made to an object are automatically reflected in all places that refer to the same teal_slice.

Returns

Object of class DatetimeFilterState, invisibly.


Method get_call()

Returns reproducible condition call for current selection. For this class returned call looks like ⁠<varname> >= as.POSIXct(<min>) & <varname> <= <max>)⁠ with optional ⁠is.na(<varname>)⁠.

Usage
DatetimeFilterState$get_call(dataname)
Arguments
dataname

name of data set; defaults to private$get_dataname()

Returns

call


Method clone()

The objects of this class are cloneable with this method.

Usage
DatetimeFilterState$clone(deep = FALSE)
Arguments
deep

Whether to make a deep clone.

Examples

# use non-exported function from teal.slice
include_css_files <- getFromNamespace("include_css_files", "teal.slice")
include_js_files <- getFromNamespace("include_js_files", "teal.slice")
DatetimeFilterState <- getFromNamespace("DatetimeFilterState", "teal.slice")

library(shiny)

filter_state <- DatetimeFilterState$new(
  x = c(Sys.time() + seq(0, by = 3600, length.out = 10), NA),
  slice = teal_slice(varname = "x", dataname = "data"),
  extract_type = character(0)
)
isolate(filter_state$get_call())
filter_state$set_state(
  teal_slice(
    dataname = "data",
    varname = "x",
    selected = c(Sys.time() + 3L, Sys.time() + 8L),
    keep_na = TRUE
  )
)
isolate(filter_state$get_call())

# working filter in an app
library(shinyjs)

datetimes <- as.POSIXct(c("2012-01-01 12:00:00", "2020-01-01 12:00:00"))
data_datetime <- c(seq(from = datetimes[1], to = datetimes[2], length.out = 100), NA)
fs <- DatetimeFilterState$new(
  x = data_datetime,
  slice = teal_slice(
    varname = "x", dataname = "data", selected = data_datetime[c(47, 98)], keep_na = TRUE
  )
)

ui <- fluidPage(
  useShinyjs(),
  include_css_files(pattern = "filter-panel"),
  include_js_files(pattern = "count-bar-labels"),
  column(4, tags$div(
    tags$h4("DatetimeFilterState"),
    fs$ui("fs")
  )),
  column(4, tags$div(
    id = "outputs", # div id is needed for toggling the element
    tags$h4("Condition (i.e. call)"), # display the condition call generated by this FilterState
    textOutput("condition_datetime"), tags$br(),
    tags$h4("Unformatted state"), # display raw filter state
    textOutput("unformatted_datetime"), tags$br(),
    tags$h4("Formatted state"), # display human readable filter state
    textOutput("formatted_datetime"), tags$br()
  )),
  column(4, tags$div(
    tags$h4("Programmatic filter control"),
    actionButton("button1_datetime", "set drop NA", width = "100%"), tags$br(),
    actionButton("button2_datetime", "set keep NA", width = "100%"), tags$br(),
    actionButton("button3_datetime", "set a range", width = "100%"), tags$br(),
    actionButton("button4_datetime", "set full range", width = "100%"), tags$br(),
    actionButton("button0_datetime", "set initial state", width = "100%"), tags$br()
  ))
)

server <- function(input, output, session) {
  fs$server("fs")
  output$condition_datetime <- renderPrint(fs$get_call())
  output$formatted_datetime <- renderText(fs$format())
  output$unformatted_datetime <- renderPrint(fs$get_state())
  # modify filter state programmatically
  observeEvent(
    input$button1_datetime,
    fs$set_state(teal_slice(dataname = "data", varname = "x", keep_na = FALSE))
  )
  observeEvent(
    input$button2_datetime,
    fs$set_state(teal_slice(dataname = "data", varname = "x", keep_na = TRUE))
  )
  observeEvent(
    input$button3_datetime,
    fs$set_state(
      teal_slice(dataname = "data", varname = "x", selected = data_datetime[c(34, 56)])
    )
  )
  observeEvent(
    input$button4_datetime,
    fs$set_state(
      teal_slice(dataname = "data", varname = "x", selected = datetimes)
    )
  )
  observeEvent(
    input$button0_datetime,
    fs$set_state(
      teal_slice(
        dataname = "data", varname = "x", selected = data_datetime[c(47, 98)], keep_na = TRUE
      )
    )
  )
}

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


DefaultFilteredDataset R6 class

Description

Stores any object as inert entity. Filtering is not supported.

Super class

teal.slice::FilteredDataset -> DefaultFilteredDataset

Methods

Public methods

Inherited methods

Method new()

Initializes this DefaultFilteredDataset object.

Usage
DefaultFilteredDataset$new(dataset, dataname, label = character(0))
Arguments
dataset

any type of object; will not be filtered.

dataname

(character(1)) syntactically valid name given to the dataset.

label

(character(1)) label to describe the dataset.

Returns

Object of class DefaultFilteredDataset, invisibly.


Method format()

Returns a formatted string representing this DefaultFilteredDataset object.

Usage
DefaultFilteredDataset$format(show_all, trim_lines = FALSE)
Arguments
show_all

(logical(1)) for method consistency, ignored.

trim_lines

(logical(1)) flag specifying whether to trim lines if class names are too long.

Returns

The formatted string.


Method get_call()

Usage
DefaultFilteredDataset$get_call(sid)
Arguments
sid

(character(1)) for method consistency, ignored.

Returns

NULL, invisibly.


Method get_filter_state()

Usage
DefaultFilteredDataset$get_filter_state()
Returns

NULL, invisibly.


Method set_filter_state()

Usage
DefaultFilteredDataset$set_filter_state(state)
Arguments
state

(teal_slices) for method consistency, ignored.

Returns

NULL, invisibly.


Method clear_filter_states()

Usage
DefaultFilteredDataset$clear_filter_states(force)
Arguments
force

(logical(1)) for method consistency, ignored.

Returns

NULL, invisibly.


Method get_filter_overview()

Creates row for filter overview in the form of
dataname - unsupported data class

Usage
DefaultFilteredDataset$get_filter_overview()
Returns

A data.frame.


Method ui_active()

Overwrites parent method.

Usage
DefaultFilteredDataset$ui_active(id, allow_add)
Arguments
id

(character(1)) shiny module instance id.

allow_add

(ignored)

Details

Blank UI module that would list active filter states for this dataset.

Returns

An empty div.


Method ui_add()

Overwrites parent method.

Usage
DefaultFilteredDataset$ui_add(id)
Arguments
id

(character(1)) shiny module instance id.

Details

Blank UI module that would list active filter states for this dataset.

Returns

An empty div.


Method clone()

The objects of this class are cloneable with this method.

Usage
DefaultFilteredDataset$clone(deep = FALSE)
Arguments
deep

Whether to make a deep clone.

Examples

# use non-exported function from teal.slice
DefaultFilteredDataset <- getFromNamespace("DefaultFilteredDataset", "teal.slice")

library(shiny)

ds <- DefaultFilteredDataset$new(letters, "letters")
isolate(ds$get_filter_state())
isolate(ds$get_call())


FilterState object for empty variables

Description

FilterState subclass representing an empty variable.

Super class

teal.slice::FilterState -> EmptyFilterState

Methods

Public methods

Inherited methods

Method new()

Initialize EmptyFilterState object.

Usage
EmptyFilterState$new(
  x,
  x_reactive = reactive(NULL),
  extract_type = character(0),
  slice
)
Arguments
x

(vector) variable to be filtered,

x_reactive

(reactive) returning vector of the same type as x. Is used to update counts following the change in values of the filtered dataset. If it is set to reactive(NULL) then counts based on filtered dataset are not shown.

extract_type

(character) specifying whether condition calls should be prefixed by dataname. Possible values:

  • character(0) (default) varname in the condition call will not be prefixed

  • "list" varname in the condition call will be returned as ⁠<dataname>$<varname>⁠

  • "matrix" varname in the condition call will be returned as ⁠<dataname>[, <varname>]⁠

slice

(teal_slice) specification of this filter state. teal_slice is stored in the object and set_state directly manipulates values within teal_slice. get_state returns teal_slice object which can be reused in other places. Note that teal_slice is a reactiveValues, which means it has reference semantics, i.e. changes made to an object are automatically reflected in all places that refer to the same teal_slice.

Returns

Object of class EmptyFilterState, invisibly.


Method get_call()

Returns reproducible condition call for current selection relevant for selected variable type. Uses internal reactive values, hence must be called in reactive or isolated context.

Usage
EmptyFilterState$get_call(dataname)
Arguments
dataname

name of data set; defaults to private$get_dataname()

Returns

logical(1)


Method clone()

The objects of this class are cloneable with this method.

Usage
EmptyFilterState$clone(deep = FALSE)
Arguments
deep

Whether to make a deep clone.

Examples

# use non-exported function from teal.slice
include_js_files <- getFromNamespace("include_js_files", "teal.slice")
EmptyFilterState <- getFromNamespace("EmptyFilterState", "teal.slice")

library(shiny)

filter_state <- EmptyFilterState$new(
  x = NA,
  slice = teal_slice(varname = "x", dataname = "data"),
  extract_type = character(0)
)
isolate(filter_state$get_call())
filter_state$set_state(teal_slice(dataname = "data", varname = "x", keep_na = TRUE))
isolate(filter_state$get_call())


Class to encapsulate the API of the filter panel of a teal app

Description

An API class for managing filter states in a teal application's filter panel.

Details

The purpose of this class is to encapsulate the API of the filter panel in a new class FilterPanelAPI so that it can be passed and used in the server call of any module instead of passing the whole FilteredData object.

This class is supported by methods to set, get, remove filter states in the filter panel API.

Methods

Public methods


Method new()

Initialize a FilterPanelAPI object.

Usage
FilterPanelAPI$new(datasets)
Arguments
datasets

(FilteredData)


Method get_filter_state()

Gets the reactive values from the active FilterState objects of the FilteredData object.

Gets all active filters in the form of a nested list. The output list is a compatible input to set_filter_state.

Usage
FilterPanelAPI$get_filter_state()
Returns

list with named elements corresponding to FilteredDataset objects with active filters.


Method set_filter_state()

Sets active filter states.

Usage
FilterPanelAPI$set_filter_state(filter)
Arguments
filter

(teal_slices)

Returns

NULL, invisibly.


Method remove_filter_state()

Remove one or more FilterState of a FilteredDataset in the FilteredData object.

Usage
FilterPanelAPI$remove_filter_state(filter)
Arguments
filter

(teal_slices) specifying FilterState objects to remove; teal_slices may contain only dataname and varname, other elements are ignored

Returns

NULL, invisibly.


Method clear_filter_states()

Remove all FilterStates of the FilteredData object.

Usage
FilterPanelAPI$clear_filter_states(datanames)
Arguments
datanames

(character) datanames to remove their FilterStates; omit to remove all FilterStates in the FilteredData object

Returns

NULL, invisibly.


Method clone()

The objects of this class are cloneable with this method.

Usage
FilterPanelAPI$clone(deep = FALSE)
Arguments
deep

Whether to make a deep clone.

Examples

library(shiny)

fd <- init_filtered_data(list(iris = iris))
fpa <- FilterPanelAPI$new(fd)

# get the actual filter state --> empty named list
isolate(fpa$get_filter_state())

# set a filter state
set_filter_state(
  fpa,
  teal_slices(
    teal_slice(dataname = "iris", varname = "Species", selected = "setosa", keep_na = TRUE)
  )
)

# get the actual filter state --> named list with filters
isolate(fpa$get_filter_state())

# remove all_filter_states
fpa$clear_filter_states()

# get the actual filter state --> empty named list
isolate(fpa$get_filter_state())


FilterState abstract class

Description

Abstract class to encapsulate single filter state.

Details

This class is responsible for managing a single filter item within a FilteredData object and outputs a condition call (logical predicate) for subsetting one variable. Filter states depend on the variable type: (logical, integer, numeric, character, factor, Date, POSIXct, POSIXlt) and FilterState subclasses exist that correspond to those types.

Each variable's filter state is an R6 object keeps the variable that is filtered, a teal_slice object that describes the filter state, as well as a shiny module (UI and server) that allows the user to alter the filter state. Changes to the filter state that cause some observations to be omitted trigger the get_call method and every R function call up in the reactive chain.

Modifying state

Modifying a FilterState object is possible in three scenarios:

Methods

Public methods


Method new()

Initialize a FilterState object.

Usage
FilterState$new(
  x,
  x_reactive = reactive(NULL),
  slice,
  extract_type = character(0)
)
Arguments
x

(vector) variable to be filtered.

x_reactive

(reactive) returning vector of the same type as x. Is used to update counts following the change in values of the filtered dataset. If it is set to reactive(NULL) then counts based on filtered dataset are not shown.

slice

(teal_slice) specification of this filter state. teal_slice is stored in the object and set_state directly manipulates values within teal_slice. get_state returns teal_slice object which can be reused in other places. Note that teal_slice is a reactiveValues, which means it has reference semantics, i.e. changes made to an object are automatically reflected in all places that refer to the same teal_slice.

extract_type

(character) specifying whether condition calls should be prefixed by dataname. Possible values:

  • character(0) (default) varname in the condition call will not be prefixed

  • "list" varname in the condition call will be returned as ⁠<dataname>$<varname>⁠

  • "matrix" varname in the condition call will be returned as ⁠<dataname>[, <varname>]⁠

Returns

Object of class FilterState, invisibly.


Method format()

Returns a formatted string representing this FilterState object.

Usage
FilterState$format(show_all = FALSE, trim_lines = TRUE)
Arguments
show_all

(logical(1)) passed to format.teal_slice

trim_lines

(logical(1)) passed to format.teal_slice

Returns

character(1) the formatted string


Method print()

Prints this FilterState object.

Usage
FilterState$print(...)
Arguments
...

additional arguments


Method set_state()

Sets mutable parameters of the filter state.

Usage
FilterState$set_state(state)
Arguments
state

(teal_slice)

Returns

self invisibly


Method get_state()

Returns a complete description of the filter state.

Usage
FilterState$get_state()
Returns

A teal_slice object.


Method get_call()

Returns reproducible condition call for current selection relevant for selected variable type. Method is using internal reactive values which makes it reactive and must be executed in reactive or isolated context.

Usage
FilterState$get_call()

Method server()

shiny module server.

Usage
FilterState$server(id, remove_callback)
Arguments
id

(character(1)) shiny module instance id.

remove_callback

(function) callback to handle removal of this FilterState object from state_list

Returns

Reactive expression signaling that remove button has been clicked.


Method ui()

shiny UI module. The UI for this class contains simple message stating that it is not supported.

Usage
FilterState$ui(id, parent_id = "cards")
Arguments
id

(character(1)) shiny module instance id.

parent_id

(character(1)) id of the FilterStates card container


Method finalize()

Destroy inputs and observers stored in private$session_bindings.

Usage
FilterState$finalize()
Returns

NULL, invisibly.


Method clone()

The objects of this class are cloneable with this method.

Usage
FilterState$clone(deep = FALSE)
Arguments
deep

Whether to make a deep clone.


FilterStateExpr R6 class

Description

Sister class to FilterState that handles arbitrary filter expressions.

Details

Creates a filter state around a predefined condition call (logical predicate). The condition call is independent of the data and the filter card allows no interaction (the filter is always fixed).

Methods

Public methods


Method new()

Initialize a FilterStateExpr object.

Usage
FilterStateExpr$new(slice)
Arguments
slice

(teal_slice_expr)

Returns

Object of class FilterStateExpr, invisibly.


Method format()

Returns a formatted string representing this FilterStateExpr object.

Usage
FilterStateExpr$format(show_all = FALSE, trim_lines = TRUE)
Arguments
show_all

(logical(1)) passed to format.teal_slice

trim_lines

(logical(1)) passed to format.teal_slice

Returns

character(1) the formatted string


Method print()

Prints this FilterStateExpr object.

Usage
FilterStateExpr$print(...)
Arguments
...

arguments passed to the format method

Returns

NULL, invisibly.


Method get_state()

Returns a complete description of this filter state.

Usage
FilterStateExpr$get_state()
Returns

A teal_slice object.


Method set_state()

Does nothing. Exists for compatibility.

Usage
FilterStateExpr$set_state(state)
Arguments
state

(teal_slice)

Returns

self, invisibly.


Method get_call()

Get reproducible call.

Usage
FilterStateExpr$get_call(dataname)
Arguments
dataname

(ignored) for a consistency with FilterState

Returns reproducible condition call for current selection relevant for selected variable type. Method is using internal reactive values which makes it reactive and must be executed in reactive or isolated context.

Returns

call or NULL


Method finalize()

Destroy inputs and observers stored in private$session_bindings.

Usage
FilterStateExpr$finalize()
Returns

NULL, invisibly.


Method server()

shiny module server.

Usage
FilterStateExpr$server(id, remove_callback)
Arguments
id

(character(1)) shiny module instance id.

remove_callback

(function) callback to handle removal of this FilterState object from state_list

Returns

Reactive expression signaling that the remove button has been clicked.


Method ui()

shiny module UI. The UI for this class contains simple message stating that it is not supported.

Usage
FilterStateExpr$ui(id, parent_id = "cards")
Arguments
id

(character(1)) shiny module instance id.

parent_id

(character(1)) id of the FilterStates card container.


Method clone()

The objects of this class are cloneable with this method.

Usage
FilterStateExpr$clone(deep = FALSE)
Arguments
deep

Whether to make a deep clone.

Examples

# use non-exported function from teal.slice
include_js_files <- getFromNamespace("include_js_files", "teal.slice")
include_css_files <- getFromNamespace("include_css_files", "teal.slice")
FilterStateExpr <- getFromNamespace("FilterStateExpr", "teal.slice")

filter_state <- FilterStateExpr$new(
  slice = teal_slice(
    dataname = "x",
    id = "FA",
    title = "Adult females",
    expr = "sex == 'F' & age >= 18"
  )
)
filter_state$get_call()

# working filter in an app
library(shiny)
library(shinyjs)

ui <- fluidPage(
  useShinyjs(),
  include_css_files(pattern = "filter-panel"),
  include_js_files(pattern = "count-bar-labels"),
  column(4, tags$div(
    tags$h4("ChoicesFilterState"),
    filter_state$ui("fs")
  )),
  column(8, tags$div(
    tags$h4("Condition (i.e. call)"), # display the condition call generated by this FilterState
    textOutput("condition_choices"), tags$br(),
    tags$h4("Unformatted state"), # display raw filter state
    textOutput("unformatted_choices"), tags$br(),
    tags$h4("Formatted state"), # display human readable filter state
    textOutput("formatted_choices"), tags$br()
  ))
)

server <- function(input, output, session) {
  filter_state$server("fs")
  output$condition_choices <- renderPrint(filter_state$get_call())
  output$formatted_choices <- renderText(filter_state$format())
  output$unformatted_choices <- renderPrint(filter_state$get_state())
}

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


FilterStates R6 class

Description

Abstract class that manages adding and removing FilterState objects and builds a subset expression.

A FilterStates object tracks all condition calls (logical predicates that limit observations) associated with a given dataset and composes them into a single reproducible R expression that will assign a subset of the original data to a new variable. This expression is hereafter referred to as subset expression.

The subset expression is constructed differently for different classes of the underlying data object and FilterStates sub-classes. Currently implemented for data.frame, matrix, SummarizedExperiment, and MultiAssayExperiment.

Methods

Public methods


Method new()

Initializes FilterStates object by setting dataname, and datalabel.

Usage
FilterStates$new(
  data,
  data_reactive = function(sid = "") NULL,
  dataname,
  datalabel = NULL
)
Arguments
data

(data.frame or MultiAssayExperiment or SummarizedExperiment or matrix) the R object which subset function is applied on.

data_reactive

(⁠function(sid)⁠) should return an object of the same type as data object or NULL. This object is needed for the FilterState counts being updated on a change in filters. If function returns NULL then filtered counts are not shown. Function has to have sid argument being a character.

dataname

(character(1)) name of the dataset, used in the subset expression. Passed to the function argument attached to this FilterStates.

datalabel

(character(1)) optional text label.

Returns

Object of class FilterStates, invisibly.


Method format()

Returns a formatted string representing this FilterStates object.

Usage
FilterStates$format(show_all = FALSE, trim_lines = TRUE)
Arguments
show_all

(logical(1)) passed to format.teal_slices

trim_lines

(logical(1)) passed to format.teal_slices

Returns

character(1) the formatted string


Method get_call()

Filter call

Builds subset expression from condition calls generated by FilterState. The lhs of the expression is a dataname_prefixed, where word prefixed refers to situation when call is evaluated on elements of the original data, for example dataname[[x]]. By default dataname_prefixed = dataname and it's not alterable through class methods. Customization of private$dataname_prefixed is done through inheriting classes.

The rhs is a call to private$fun with following arguments:

# default
dataname <- subset(dataname, col == "x")

# fun = dplyr::filter
dataname <- dplyr::filter(dataname, col == "x")

# fun = MultiAssayExperiment::subsetByColData; extract_type = "list"
dataname <- MultiAssayExperiment::subsetByColData(dataname, dataname$col == "x")

# teal_slice objects having `arg = "subset"` and `arg = "select"`
dataname <- subset(dataname, subset = row_col == "x", select = col_col == "x")

# dataname = dataname[[element]]
dataname[[element]] <- subset(dataname[[element]], subset = col == "x")

If no filters are applied, NULL is returned to avoid no-op calls such as dataname <- dataname.

Usage
FilterStates$get_call(sid = "")
Arguments
sid

(character) when specified then method returns code containing condition calls (logical predicates) of FilterState objects which "sid" attribute is different than this sid argument.

Returns

call or NULL


Method print()

Prints this FilterStates object.

Usage
FilterStates$print(...)
Arguments
...

additional arguments passed to format.


Method remove_filter_state()

Remove one or more FilterStates from the state_list along with their UI elements.

Usage
FilterStates$remove_filter_state(state)
Arguments
state

(teal_slices) specifying FilterState objects to remove; teal_slices may contain only dataname and varname, other elements are ignored

Returns

NULL, invisibly.


Method get_filter_state()

Gets reactive values from active FilterState objects.

Get active filter state from FilterState objects stored in state_list(s). The output is a list compatible with input to self$set_filter_state.

Usage
FilterStates$get_filter_state()
Returns

Object of class teal_slices.


Method set_filter_state()

Sets active FilterState objects.

Usage
FilterStates$set_filter_state(state)
Arguments
state

(teal_slices)

Returns

Function that raises an error.


Method clear_filter_states()

Remove all FilterState objects from this FilterStates object.

Usage
FilterStates$clear_filter_states(force = FALSE)
Arguments
force

(logical(1)) flag specifying whether to include anchored filter states.

Returns

NULL, invisibly.


Method ui_active()

shiny UI definition that stores FilterState UI elements. Populated with elements created with renderUI in the module server.

Usage
FilterStates$ui_active(id)
Arguments
id

(character(1)) shiny module instance id.

Returns

shiny.tag


Method srv_active()

shiny server module.

Usage
FilterStates$srv_active(id)
Arguments
id

(character(1)) shiny module instance id.

Returns

NULL.


Method ui_add()

shiny UI module to add filter variable.

Usage
FilterStates$ui_add(id)
Arguments
id

(character(1)) shiny module instance id.

Returns

shiny.tag


Method srv_add()

shiny server module to add filter variable.

This module controls available choices to select as a filter variable. Once selected, a variable is removed from available choices. Removing a filter variable adds it back to available choices.

Usage
FilterStates$srv_add(id)
Arguments
id

(character(1)) shiny module instance id.

Returns

NULL.


Method finalize()

Object cleanup.

Usage
FilterStates$finalize()
Returns

NULL, invisibly.


Method clone()

The objects of this class are cloneable with this method.

Usage
FilterStates$clone(deep = FALSE)
Arguments
deep

Whether to make a deep clone.


Class to encapsulate filtered datasets

Description

Manages filtering of all datasets in the application or module.

Details

The main purpose of this class is to provide a collection of reactive datasets, each dataset having a filter state that determines how it is filtered.

For each dataset, get_filter_expr returns the call to filter the dataset according to the filter state. The data itself can be obtained through get_data.

The datasets are filtered lazily, i.e. only when requested / needed in a shiny app.

By design, any dataname set through set_dataset cannot be removed because other code may already depend on it. As a workaround, the underlying data can be set to NULL.

The class currently supports variables of the following types within datasets:

Common arguments are:

  1. filtered: whether to return a filtered result or not

  2. dataname: the name of one of the datasets in this FilteredData object

  3. varname: one of the columns in a dataset

Methods

Public methods


Method new()

Initialize a FilteredData object.

Usage
FilteredData$new(data_objects, join_keys = teal.data::join_keys())
Arguments
data_objects

(⁠named list⁠) List of data objects. Names of the list will be used as dataname for respective datasets.

join_keys

(join_keys) optional joining keys, see teal.data::join_keys().


Method datanames()

Gets datanames.

Usage
FilteredData$datanames()
Details

The datanames are returned in the order in which they must be evaluated (in case of dependencies).

Returns

Character vector.


Method get_datalabel()

Gets data label for the dataset. Useful to display in ⁠Show R Code⁠.

Usage
FilteredData$get_datalabel(dataname)
Arguments
dataname

(character(1)) name of the dataset

Returns

Character string.


Method set_available_teal_slices()

Set list of external filter states available for activation.

Usage
FilteredData$set_available_teal_slices(x)
Arguments
x

(reactive) should return teal_slices

Details

Unlike adding new filter from the column, these filters can come with some prespecified settings. teal_slices are wrapped in a reactive so they can be updated from elsewhere in the app. Filters passed in x are limited to those that can be set for this FilteredData object, i.e. they have the correct dataname and varname (waived teal_slice_fixed as they do not have varname). List is accessible in ui/srv_active through ui/srv_available_filters.

Returns

NULL, invisibly.


Method get_available_teal_slices()

Get list of filter states available for this object.

Usage
FilteredData$get_available_teal_slices()
Details

All teal_slice objects that have been created since the beginning of the app session are stored in one teal_slices object. This returns a subset of that teal_slices, describing filter states that can be set for this object.

Returns

reactive that returns teal_slices.


Method get_call()

Gets a call to filter the dataset according to the filter state.

Usage
FilteredData$get_call(dataname)
Arguments
dataname

(character(1)) name of the dataset

Details

It returns a call to filter the dataset only, assuming the other (filtered) datasets it depends on are available.

Together with self$datanames() which returns the datasets in the correct evaluation order, this generates the whole filter code, see the function FilteredData$get_filter_code.

For the return type, note that rlang::is_expression returns TRUE on the return type, both for base R expressions and calls (single expression, capturing a function call).

The filtered dataset has the name given by self$filtered_dataname(dataname)

This can be used for the ⁠Show R Code⁠ generation.

Returns

A list of calls.


Method get_data()

Gets filtered or unfiltered dataset.

For filtered = FALSE, the original data set with set_data is returned including all attributes.

Usage
FilteredData$get_data(dataname, filtered = TRUE)
Arguments
dataname

(character(1)) name of the dataset.

filtered

(logical(1)) whether to return a filtered or unfiltered dataset.

Returns

A data object, a data.frame or a MultiAssayExperiment.


Method get_join_keys()

Get join keys between two datasets.

Usage
FilteredData$get_join_keys()
Returns

join_keys


Method get_filter_overview()

Creates filter overview table to be displayed in the application. One row is created per dataset, according to the get_filter_overview methods of the contained FilteredDataset objects.

Usage
FilteredData$get_filter_overview(datanames)
Arguments
datanames

(character) vector of dataset names.

Returns

A data.frame listing the numbers of observations in all datasets.


Method get_keys()

Get keys for the dataset.

Usage
FilteredData$get_keys(dataname)
Arguments
dataname

(character(1)) name of the dataset.

Returns

Character vector of key column names.


Method set_dataset()

Adds a dataset to this FilteredData.

Usage
FilteredData$set_dataset(data, dataname)
Arguments
data

(data.frame or MultiAssayExperiment) data to be filtered.

dataname

(character(1)) the name of the dataset to be added to this object.

Details

set_dataset creates a FilteredDataset object which keeps dataset for the filtering purpose. If this data has a parent specified in the join_keys object stored in private$join_keys then created FilteredDataset (child) gets linked with other FilteredDataset (parent). "Child" dataset return filtered data then dependent on the reactive filtered data of the "parent". See more in documentation of parent argument in DataframeFilteredDataset constructor.

Returns

self, invisibly.


Method set_join_keys()

Set the join_keys.

Usage
FilteredData$set_join_keys(join_keys)
Arguments
join_keys

(join_keys), see teal.data::join_keys().

Returns

self, invisibly.


Method get_filter_state()

Gets states of all contained FilterState objects.

Usage
FilteredData$get_filter_state()
Returns

A teal_slices object.


Method format()

Returns a formatted string representing this FilteredData object.

Usage
FilteredData$format(show_all = FALSE, trim_lines = TRUE)
Arguments
show_all

(logical(1)) passed to format.teal_slice.

trim_lines

(logical(1)) passed to format.teal_slice.

Returns

character(1) the formatted string.


Method print()

Prints this FilteredData object.

Usage
FilteredData$print(...)
Arguments
...

additional arguments passed to format.


Method set_filter_state()

Sets active filter states.

Usage
FilteredData$set_filter_state(state)
Arguments
state

(teal_slices)

Returns

NULL, invisibly.


Method remove_filter_state()

Removes one or more FilterState from a FilteredData object.

Usage
FilteredData$remove_filter_state(state)
Arguments
state

(teal_slices) specifying FilterState objects to remove; teal_slices may contain only dataname and varname, other elements are ignored.

Returns

NULL, invisibly.


Method clear_filter_states()

Remove all FilterStates of a FilteredDataset or all FilterStates of a FilteredData object.

Usage
FilteredData$clear_filter_states(datanames = self$datanames(), force = FALSE)
Arguments
datanames

(character) names of datasets for which to remove all filter states. Defaults to all datasets in this FilteredData object.

force

(logical(1)) flag specifying whether to include anchored filter states.

Returns

NULL, invisibly.


Method ui_filter_panel()

top-level shiny module for the filter panel in the teal app. Contains 1) filter overview panel, 2) filter active panel, and 3) add filters panel.

Usage
FilteredData$ui_filter_panel(id, active_datanames = self$datanames)
Arguments
id

(character(1)) shiny module instance id.

active_datanames

(reactive) defining subset of self$datanames() to be displayed.

Returns

shiny.tag


Method srv_filter_panel()

Server function for filter panel.

Usage
FilteredData$srv_filter_panel(id, active_datanames = self$datanames)
Arguments
id

(character(1)) shiny module instance id.

active_datanames

(function or reactive) returning datanames that should be shown on the filter panel. Must be a subset of the datanames in this FilteredData. If the function returns NULL (as opposed to character(0)), the filter panel will be hidden.

Returns

NULL.


Method ui_active()

Server module responsible for displaying active filters.

Usage
FilteredData$ui_active(id, active_datanames = self$datanames)
Arguments
id

(character(1)) shiny module instance id.

active_datanames

(reactive) defining subset of self$datanames() to be displayed.

Returns

shiny.tag


Method srv_active()

Server module responsible for displaying active filters.

Usage
FilteredData$srv_active(id, active_datanames = self$datanames)
Arguments
id

(character(1)) shiny module instance id.

active_datanames

(reactive) defining subset of self$datanames() to be displayed.

Returns

NULL.


Method ui_overview()

Creates the UI definition for the module showing counts for each dataset contrasting the filtered to the full unfiltered dataset.

Per dataset, it displays the number of rows/observations in each dataset, the number of unique subjects.

Usage
FilteredData$ui_overview(id)
Arguments
id

(character(1)) shiny module instance id.


Method srv_overview()

Server function to display the number of records in the filtered and unfiltered data.

Usage
FilteredData$srv_overview(id, active_datanames = self$datanames)
Arguments
id

(character(1)) shiny module instance id.

active_datanames

(reactive) returning datanames that should be shown on the filter panel, must be a subset of the datanames argument provided to ui_filter_panel; if the function returns NULL (as opposed to character(0)), the filter panel will be hidden.

Returns

NULL.


Method finalize()

Object and dependencies cleanup.

Usage
FilteredData$finalize()
Returns

NULL, invisibly.


Method clone()

The objects of this class are cloneable with this method.

Usage
FilteredData$clone(deep = FALSE)
Arguments
deep

Whether to make a deep clone.

Examples

# use non-exported function from teal.slice
FilteredData <- getFromNamespace("FilteredData", "teal.slice")

library(shiny)

datasets <- FilteredData$new(list(iris = iris, mtcars = mtcars))

# get datanames
datasets$datanames()

datasets$set_filter_state(
  teal_slices(teal_slice(dataname = "iris", varname = "Species", selected = "virginica"))
)

datasets$set_filter_state(
  teal_slices(teal_slice(dataname = "mtcars", varname = "mpg", selected = c(15, 20)))
)

isolate(datasets$get_filter_state())
isolate(datasets$get_call("iris"))
isolate(datasets$get_call("mtcars"))


### set_filter_state
library(shiny)

data(miniACC, package = "MultiAssayExperiment")
datasets <- FilteredData$new(list(iris = iris, mae = miniACC))
fs <- teal_slices(
  teal_slice(
    dataname = "iris", varname = "Sepal.Length", selected = c(5.1, 6.4),
    keep_na = TRUE, keep_inf = FALSE
  ),
  teal_slice(
    dataname = "iris", varname = "Species", selected = c("setosa", "versicolor"),
    keep_na = FALSE
  ),
  teal_slice(
    dataname = "mae", varname = "years_to_birth", selected = c(30, 50),
    keep_na = TRUE, keep_inf = FALSE
  ),
  teal_slice(dataname = "mae", varname = "vital_status", selected = "1", keep_na = FALSE),
  teal_slice(dataname = "mae", varname = "gender", selected = "female", keep_na = TRUE),
  teal_slice(
    dataname = "mae", varname = "ARRAY_TYPE",
    selected = "", keep_na = TRUE, experiment = "RPPAArray", arg = "subset"
  )
)
datasets$set_filter_state(state = fs)
isolate(datasets$get_filter_state())


FilteredDataset R6 class

Description

FilteredDataset is a class which renders/controls FilterStates(s) Each FilteredDataset contains filter_states field - a list which contains one (data.frame) or multiple (MultiAssayExperiment) FilterStates objects. Each FilterStates is responsible for one filter/subset expression applied for specific components of the dataset.

Methods

Public methods


Method new()

Initializes this FilteredDataset object.

Usage
FilteredDataset$new(
  dataset,
  dataname,
  keys = character(0),
  label = attr(dataset, "label", exact = TRUE)
)
Arguments
dataset

any object

dataname

(character(1)) syntactically valid name given to the dataset.

keys

(character) optional vector of primary key column names.

label

(character(1)) label to describe the dataset.

Returns

Object of class FilteredDataset, invisibly.


Method format()

Returns a formatted string representing this FilteredDataset object.

Usage
FilteredDataset$format(show_all = FALSE, trim_lines = TRUE)
Arguments
show_all

(logical(1)) passed to format.teal_slice.

trim_lines

(logical(1)) passed to format.teal_slice.

Returns

The formatted character string.


Method print()

Prints this FilteredDataset object.

Usage
FilteredDataset$print(...)
Arguments
...

additional arguments passed to format.


Method clear_filter_states()

Removes all filter items applied to this dataset.

Usage
FilteredDataset$clear_filter_states(force = FALSE)
Arguments
force

(logical(1)) flag specifying whether to include anchored filter states.

Returns

NULL.


Method get_call()

Gets a filter expression.

This function returns filter calls equivalent to selected items within each of filter_states. Configuration of the calls is constant and depends on filter_states type and order which are set during initialization.

Usage
FilteredDataset$get_call(sid = "")
Arguments
sid

(character) when specified, the method returns code containing conditions calls of FilterState objects with sid different to this sid argument.

Returns

Either a list of filter calls, or NULL.


Method get_filter_state()

Gets states of all contained FilterState objects.

Usage
FilteredDataset$get_filter_state()
Returns

A teal_slices object.


Method set_filter_state()

Set filter state.

Usage
FilteredDataset$set_filter_state(state)
Arguments
state

(teal_slices)

Returns

Virtual method, returns nothing and raises error.


Method get_dataname()

Gets the name of the dataset.

Usage
FilteredDataset$get_dataname()
Returns

A character string.


Method get_dataset()

Gets the dataset object in this FilteredDataset.

Usage
FilteredDataset$get_dataset(filtered = FALSE)
Arguments
filtered

(logical(1))

Returns

The stored dataset. If data.frame or MultiAssayExperiment, either raw or as a reactive with current filters applied (depending on filtered).


Method get_filter_overview()

Get filter overview of a dataset.

Usage
FilteredDataset$get_filter_overview()
Returns

Virtual method, returns nothing and raises an error.


Method get_keys()

Gets the key columns for this dataset.

Usage
FilteredDataset$get_keys()
Returns

Character vector of variable names


Method get_dataset_label()

Gets the dataset label.

Usage
FilteredDataset$get_dataset_label()
Returns

Character string.


Method ui_active()

shiny module containing active filters for a dataset, along with a title and a remove button.

Usage
FilteredDataset$ui_active(id, allow_add = TRUE)
Arguments
id

(character(1)) shiny module instance id.

allow_add

(logical(1)) logical flag specifying whether the user will be able to add new filters

Returns

shiny.tag


Method srv_active()

Server module for a dataset active filters.

Usage
FilteredDataset$srv_active(id)
Arguments
id

(character(1)) shiny module instance id.

Returns

NULL.


Method ui_add()

UI module to add filter variable for this dataset.

Usage
FilteredDataset$ui_add(id)
Arguments
id

(character(1)) shiny module instance id.

Returns

Virtual method, returns nothing and raises error.


Method srv_add()

Server module to add filter variable for this dataset. For this class srv_add calls multiple modules of the same name from FilterStates as MAEFilteredDataset contains one FilterStates object for colData and one for each experiment.

Usage
FilteredDataset$srv_add(id)
Arguments
id

(character(1)) shiny module instance id.

Returns

NULL.


Method finalize()

Object and dependencies cleanup.

Usage
FilteredDataset$finalize()
Returns

NULL, invisibly.


Method clone()

The objects of this class are cloneable with this method.

Usage
FilteredDataset$clone(deep = FALSE)
Arguments
deep

Whether to make a deep clone.


FilterState object for logical data

Description

Manages choosing a logical state.

Super class

teal.slice::FilterState -> LogicalFilterState

Methods

Public methods

Inherited methods

Method new()

Initialize a FilterState object.

Usage
LogicalFilterState$new(
  x,
  x_reactive = reactive(NULL),
  extract_type = character(0),
  slice
)
Arguments
x

(logical) variable to be filtered.

x_reactive

(reactive) returning vector of the same type as x. Is used to update counts following the change in values of the filtered dataset. If it is set to reactive(NULL) then counts based on filtered dataset are not shown.

extract_type

(character) specifying whether condition calls should be prefixed by dataname. Possible values:

  • character(0) (default) varname in the condition call will not be prefixed

  • "list" varname in the condition call will be returned as ⁠<dataname>$<varname>⁠

  • "matrix" varname in the condition call will be returned as ⁠<dataname>[, <varname>]⁠

slice

(teal_slice) specification of this filter state. teal_slice is stored in the object and set_state directly manipulates values within teal_slice. get_state returns teal_slice object which can be reused in other places. Note that teal_slice is a reactiveValues, which means it has reference semantics, i.e. changes made to an object are automatically reflected in all places that refer to the same teal_slice.

Returns

Object of class LogicalFilterState, invisibly.


Method get_call()

Returns reproducible condition call for current selection. For LogicalFilterState it's a ⁠!<varname>⁠ or ⁠<varname>⁠ and optionally ⁠is.na(<varname>)⁠

Usage
LogicalFilterState$get_call(dataname)
Arguments
dataname

name of data set; defaults to private$get_dataname()

Returns

call


Method clone()

The objects of this class are cloneable with this method.

Usage
LogicalFilterState$clone(deep = FALSE)
Arguments
deep

Whether to make a deep clone.

Examples

# use non-exported function from teal.slice
include_css_files <- getFromNamespace("include_css_files", "teal.slice")
include_js_files <- getFromNamespace("include_js_files", "teal.slice")
LogicalFilterState <- getFromNamespace("LogicalFilterState", "teal.slice")

library(shiny)

filter_state <- LogicalFilterState$new(
  x = sample(c(TRUE, FALSE, NA), 10, replace = TRUE),
  slice = teal_slice(varname = "x", dataname = "data")
)
isolate(filter_state$get_call())
filter_state$set_state(
  teal_slice(dataname = "data", varname = "x", selected = TRUE, keep_na = TRUE)
)
isolate(filter_state$get_call())

# working filter in an app
library(shinyjs)

data_logical <- c(sample(c(TRUE, FALSE), 10, replace = TRUE), NA)
fs <- LogicalFilterState$new(
  x = data_logical,
  slice = teal_slice(dataname = "data", varname = "x", selected = FALSE, keep_na = TRUE)
)

ui <- fluidPage(
  useShinyjs(),
  include_css_files(pattern = "filter-panel"),
  include_js_files(pattern = "count-bar-labels"),
  column(4, tags$div(
    tags$h4("LogicalFilterState"),
    fs$ui("fs")
  )),
  column(4, tags$div(
    id = "outputs", # div id is needed for toggling the element
    tags$h4("Condition (i.e. call)"), # display the condition call generated by this FilterState
    textOutput("condition_logical"), tags$br(),
    tags$h4("Unformatted state"), # display raw filter state
    textOutput("unformatted_logical"), tags$br(),
    tags$h4("Formatted state"), # display human readable filter state
    textOutput("formatted_logical"), tags$br()
  )),
  column(4, tags$div(
    tags$h4("Programmatic filter control"),
    actionButton("button1_logical", "set drop NA", width = "100%"), tags$br(),
    actionButton("button2_logical", "set keep NA", width = "100%"), tags$br(),
    actionButton("button3_logical", "set a selection", width = "100%"), tags$br(),
    actionButton("button0_logical", "set initial state", width = "100%"), tags$br()
  ))
)

server <- function(input, output, session) {
  fs$server("fs")
  output$condition_logical <- renderPrint(fs$get_call())
  output$formatted_logical <- renderText(fs$format())
  output$unformatted_logical <- renderPrint(fs$get_state())
  # modify filter state programmatically
  observeEvent(
    input$button1_logical,
    fs$set_state(teal_slice(dataname = "data", varname = "x", keep_na = FALSE))
  )
  observeEvent(
    input$button2_logical,
    fs$set_state(teal_slice(dataname = "data", varname = "x", keep_na = TRUE))
  )
  observeEvent(
    input$button3_logical,
    fs$set_state(teal_slice(dataname = "data", varname = "x", selected = TRUE))
  )
  observeEvent(
    input$button0_logical,
    fs$set_state(
      teal_slice(dataname = "data", varname = "x", selected = FALSE, keep_na = TRUE)
    )
  )
}

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


FilterStates subclass for MultiAssayExperiments

Description

Handles filter states in a MultiAssayExperiment.

Super class

teal.slice::FilterStates -> MAEFilterStates

Methods

Public methods

Inherited methods

Method new()

Initialize MAEFilterStates object.

Usage
MAEFilterStates$new(
  data,
  data_reactive = function(sid = "") NULL,
  dataname,
  datalabel = "subjects",
  keys = character(0)
)
Arguments
data

(MultiAssayExperiment) the R object which MultiAssayExperiment::subsetByColData function is applied on.

data_reactive

(⁠function(sid)⁠) should return a MultiAssayExperiment object or NULL. This object is needed for the FilterState counts being updated on a change in filters. If function returns NULL then filtered counts are not shown. Function has to have sid argument being a character.

dataname

(character(1)) name of the data used in the subset expression. Passed to the function argument attached to this FilterStates.

datalabel

(character(1)) optional text label.

keys

(character) key column names.

varlabels

(character) labels of the variables used in this object.


Method clone()

The objects of this class are cloneable with this method.

Usage
MAEFilterStates$clone(deep = FALSE)
Arguments
deep

Whether to make a deep clone.


MAEFilteredDataset R6 class

Description

MAEFilteredDataset R6 class

MAEFilteredDataset R6 class

Super class

teal.slice::FilteredDataset -> MAEFilteredDataset

Methods

Public methods

Inherited methods

Method new()

Initialize MAEFilteredDataset object.

Usage
MAEFilteredDataset$new(
  dataset,
  dataname,
  keys = character(0),
  label = character(0)
)
Arguments
dataset

(MulitiAssayExperiment) single MulitiAssayExperiment for which filters are rendered.

dataname

(character(1)) syntactically valid name given to the dataset.

keys

(character) optional vector of primary key column names.

label

(character(1)) label to describe the dataset.

Returns

Object of class MAEFilteredDataset, invisibly.


Method set_filter_state()

Set filter state.

Usage
MAEFilteredDataset$set_filter_state(state)
Arguments
state

(teal_slices)

Returns

NULL, invisibly.


Method remove_filter_state()

Remove one or more FilterState of a MAEFilteredDataset.

Usage
MAEFilteredDataset$remove_filter_state(state)
Arguments
state

(teal_slices) specifying FilterState objects to remove; teal_slices may contain only dataname and varname, other elements are ignored.

Returns

NULL, invisibly.


Method ui_add()

UI module to add filter variable for this dataset.

Usage
MAEFilteredDataset$ui_add(id)
Arguments
id

(character(1)) shiny module instance id.

Returns

shiny.tag


Method get_filter_overview()

Creates row for filter overview in the form of
dataname -- observations (remaining/total) -- subjects (remaining/total) - MAE

Usage
MAEFilteredDataset$get_filter_overview()
Returns

A data.frame.


Method clone()

The objects of this class are cloneable with this method.

Usage
MAEFilteredDataset$clone(deep = FALSE)
Arguments
deep

Whether to make a deep clone.

Examples


# use non-exported function from teal.slice
MAEFilteredDataset <- getFromNamespace("MAEFilteredDataset", "teal.slice")

data(miniACC, package = "MultiAssayExperiment")
dataset <- MAEFilteredDataset$new(miniACC, "MAE")
fs <- teal_slices(
  teal_slice(
    dataname = "MAE", varname = "years_to_birth", selected = c(30, 50), keep_na = TRUE
  ),
  teal_slice(
    dataname = "MAE", varname = "vital_status", selected = "1", keep_na = FALSE
  ),
  teal_slice(
    dataname = "MAE", varname = "gender", selected = "female", keep_na = TRUE
  ),
  teal_slice(
    dataname = "MAE", varname = "ARRAY_TYPE", selected = "", keep_na = TRUE
  )
)
dataset$set_filter_state(state = fs)

library(shiny)
isolate(dataset$get_filter_state())


FilterStates subclass for matrices

Description

Handles filter states in a matrix.

Super class

teal.slice::FilterStates -> MatrixFilterStates

Methods

Public methods

Inherited methods

Method new()

Initialize MatrixFilterStates object.

Usage
MatrixFilterStates$new(
  data,
  data_reactive = function(sid = "") NULL,
  dataname,
  datalabel = NULL
)
Arguments
data

(matrix) the R object which subset function is applied on.

data_reactive

(⁠function(sid)⁠) should return a matrix object or NULL. This object is needed for the FilterState counts being updated on a change in filters. If function returns NULL then filtered counts are not shown. Function has to have sid argument being a character.

dataname

(character(1)) name of the data used in the subset expression. Passed to the function argument attached to this FilterStates.

datalabel

(character(1)) optional text label. Should be a name of experiment.


Method clone()

The objects of this class are cloneable with this method.

Usage
MatrixFilterStates$clone(deep = FALSE)
Arguments
deep

Whether to make a deep clone.


FilterState object for numeric data

Description

Manages choosing a numeric range.

Super class

teal.slice::FilterState -> RangeFilterState

Methods

Public methods

Inherited methods

Method new()

Initialize a FilterState object for range selection.

Usage
RangeFilterState$new(
  x,
  x_reactive = reactive(NULL),
  extract_type = character(0),
  slice
)
Arguments
x

(numeric) variable to be filtered.

x_reactive

(reactive) returning vector of the same type as x. Is used to update counts following the change in values of the filtered dataset. If it is set to reactive(NULL) then counts based on filtered dataset are not shown.

extract_type

(character) specifying whether condition calls should be prefixed by dataname. Possible values:

  • character(0) (default) varname in the condition call will not be prefixed

  • "list" varname in the condition call will be returned as ⁠<dataname>$<varname>⁠

  • "matrix" varname in the condition call will be returned as ⁠<dataname>[, <varname>]⁠

slice

(teal_slice) specification of this filter state. teal_slice is stored in the object and set_state directly manipulates values within teal_slice. get_state returns teal_slice object which can be reused in other places. Note that teal_slice is a reactiveValues, which means it has reference semantics, i.e. changes made to an object are automatically reflected in all places that refer to the same teal_slice.

Returns

Object of class RangeFilterState, invisibly.


Method get_call()

Returns reproducible condition call for current selection. For this class returned call looks like ⁠<varname> >= <min value> & <varname> <= <max value>⁠ with optional ⁠is.na(<varname>)⁠ and ⁠is.finite(<varname>)⁠.

Usage
RangeFilterState$get_call(dataname)
Arguments
dataname

name of data set; defaults to private$get_dataname()

Returns

call


Method get_keep_inf()

Returns current keep_inf selection.

Usage
RangeFilterState$get_keep_inf()
Returns

logical(1)


Method clone()

The objects of this class are cloneable with this method.

Usage
RangeFilterState$clone(deep = FALSE)
Arguments
deep

Whether to make a deep clone.

Examples

# use non-exported function from teal.slice
include_css_files <- getFromNamespace("include_css_files", "teal.slice")
include_js_files <- getFromNamespace("include_js_files", "teal.slice")
RangeFilterState <- getFromNamespace("RangeFilterState", "teal.slice")

library(shiny)

filter_state <- RangeFilterState$new(
  x = c(NA, Inf, seq(1:10)),
  slice = teal_slice(varname = "x", dataname = "data")
)
isolate(filter_state$get_call())
filter_state$set_state(
  teal_slice(
    dataname = "data",
    varname = "x",
    selected = c(3L, 8L),
    keep_na = TRUE,
    keep_inf = TRUE
  )
)
isolate(filter_state$get_call())

# working filter in an app
library(shinyjs)

data_range <- c(runif(100, 0, 1), NA, Inf)
fs <- RangeFilterState$new(
  x = data_range,
  slice = teal_slice(
    dataname = "data",
    varname = "x",
    selected = c(0.15, 0.93),
    keep_na = TRUE,
    keep_inf = TRUE
  )
)

ui <- fluidPage(
  useShinyjs(),
  include_css_files(pattern = "filter-panel"),
  include_js_files(pattern = "count-bar-labels"),
  column(4, tags$div(
    tags$h4("RangeFilterState"),
    fs$ui("fs")
  )),
  column(4, tags$div(
    id = "outputs", # div id is needed for toggling the element
    tags$h4("Condition (i.e. call)"), # display the condition call generated by this FilterState
    textOutput("condition_range"), tags$br(),
    tags$h4("Unformatted state"), # display raw filter state
    textOutput("unformatted_range"), tags$br(),
    tags$h4("Formatted state"), # display human readable filter state
    textOutput("formatted_range"), tags$br()
  )),
  column(4, tags$div(
    tags$h4("Programmatic filter control"),
    actionButton("button1_range", "set drop NA", width = "100%"), tags$br(),
    actionButton("button2_range", "set keep NA", width = "100%"), tags$br(),
    actionButton("button3_range", "set drop Inf", width = "100%"), tags$br(),
    actionButton("button4_range", "set keep Inf", width = "100%"), tags$br(),
    actionButton("button5_range", "set a range", width = "100%"), tags$br(),
    actionButton("button6_range", "set full range", width = "100%"), tags$br(),
    actionButton("button0_range", "set initial state", width = "100%"), tags$br()
  ))
)

server <- function(input, output, session) {
  fs$server("fs")
  output$condition_range <- renderPrint(fs$get_call())
  output$formatted_range <- renderText(fs$format())
  output$unformatted_range <- renderPrint(fs$get_state())
  # modify filter state programmatically
  observeEvent(
    input$button1_range,
    fs$set_state(teal_slice(dataname = "data", varname = "x", keep_na = FALSE))
  )
  observeEvent(
    input$button2_range,
    fs$set_state(teal_slice(dataname = "data", varname = "x", keep_na = TRUE))
  )
  observeEvent(
    input$button3_range,
    fs$set_state(teal_slice(dataname = "data", varname = "x", keep_inf = FALSE))
  )
  observeEvent(
    input$button4_range,
    fs$set_state(teal_slice(dataname = "data", varname = "x", keep_inf = TRUE))
  )
  observeEvent(
    input$button5_range,
    fs$set_state(
      teal_slice(dataname = "data", varname = "x", selected = c(0.2, 0.74))
    )
  )
  observeEvent(
    input$button6_range,
    fs$set_state(teal_slice(dataname = "data", varname = "x", selected = c(0, 1)))
  )
  observeEvent(
    input$button0_range,
    fs$set_state(
      teal_slice("data", "variable", selected = c(0.15, 0.93), keep_na = TRUE, keep_inf = TRUE)
    )
  )
}

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

FilterStates subclass for SummarizedExperiments

Description

Handles filter states in a SummaryExperiment.

Super class

teal.slice::FilterStates -> SEFilterStates

Methods

Public methods

Inherited methods

Method new()

Initialize SEFilterStates object.

Usage
SEFilterStates$new(
  data,
  data_reactive = function(sid = "") NULL,
  dataname,
  datalabel = NULL
)
Arguments
data

(SummarizedExperiment) the R object which subset function is applied on.

data_reactive

(⁠function(sid)⁠) should return a SummarizedExperiment object or NULL. This object is needed for the FilterState counts being updated on a change in filters. If function returns NULL then filtered counts are not shown. Function has to have sid argument being a character.

dataname

(character(1)) name of the data used in the expression specified to the function argument attached to this FilterStates.

datalabel

(character(1)) optional text label. Should be the name of experiment.


Method set_filter_state()

Set filter state.

Usage
SEFilterStates$set_filter_state(state)
Arguments
state

(teal_slices) teal_slice objects should contain the field arg %in% c("subset", "select")

Returns

NULL, invisibly.


Method ui_add()

shiny UI module to add filter variable.

Usage
SEFilterStates$ui_add(id)
Arguments
id

(character(1)) shiny module instance id.

Returns

shiny.tag


Method srv_add()

shiny server module to add filter variable.

Module controls available choices to select as a filter variable. Selected filter variable is being removed from available choices. Removed filter variable gets back to available choices. This module unlike other FilterStates classes manages two sets of filter variables - one for colData and another for rowData.

Usage
SEFilterStates$srv_add(id)
Arguments
id

(character(1)) shiny module instance id.

Returns

NULL


Method clone()

The objects of this class are cloneable with this method.

Usage
SEFilterStates$clone(deep = FALSE)
Arguments
deep

Whether to make a deep clone.


Compose predicates

Description

Combines calls with a logical operator.

Usage

calls_combine_by(calls, operator)

Arguments

calls

(list) containing calls (or symbols) to be combined by operator

operator

(character(1)) infix operator to use in predicate composition, e.g. "&"

Details

This function is used to combine logical predicates produced by FilterState objects to build a complete subset expression.

Value

A call where elements of calls are composed with operator or NULL if calls is an empty list.

Examples

# use non-exported function from teal.slice
calls_combine_by <- getFromNamespace("calls_combine_by", "teal.slice")

calls <- list(
  quote(SEX == "F"), # subsetting on factor
  quote(AGE >= 20 & AGE <= 50), # subsetting on range
  quote(!SURV) # subsetting on logical
)
calls_combine_by(calls, "&")


Set "⁠<choice>:<label>⁠" type of names

Description

[Stable]

This is often useful for as it marks up the drop-down boxes for shiny::selectInput().

Usage

choices_labeled(choices, labels, subset = NULL, types = NULL)

Arguments

choices

(character or numeric or logical) vector

labels

(character) vector containing labels to be applied to choices. If NA then "Label Missing" will be used.

subset

a vector that is a subset of choices. This is useful if only a few variables need to be named. If this argument is used, the returned vector will match its order.

types

vector containing the types of the columns.

Details

If either choices or labels are factors, they are coerced to character. Duplicated elements from choices get removed.

Value

A named character vector.


Recursively coalesce list elements.

Description

Returns first element of list that it not NULL, recursively.

Usage

coalesce_r(x)

Arguments

x

(list), either of atomic vectors or of named lists

Details

Given a list of atomic vectors, the first non-null element is returned. Given a list of lists, for all names found in all elements of the list the first non-null element of a given name is returned.

This function is used internally in c.teal_slices to manage teal_slices attributes.

Value

Either an atomic vector of length 1 or a (potentially nested) list.


Progress bar with label

Description

shiny element displaying a progress bar and observation count.

Usage

countBar(inputId, label, countmax, countnow = NULL, counttotal = countmax)

updateCountBar(
  session = getDefaultReactiveDomain(),
  inputId,
  label,
  countmax,
  countnow = NULL,
  counttotal
)

updateCountText(
  session = getDefaultReactiveDomain(),
  inputId,
  label,
  countmax,
  countnow
)

Arguments

inputId

(character(1)) shiny id of the parent element (e.g. a check-box group input).

label

(character(1)) Text to display followed by counts.

countmax

(numeric(1)) Maximum count for a single element.

countnow

(numeric(1)) Current count for a single element.

counttotal

(numeric(1)) Sum total of maximum counts of all elements, see Details.

session

(session) shiny session object passed to function given to shinyServer.

Details

A progress bar is created to visualize the number of counts in a variable, with filling and a text label.

Value

shiny.tag object with a progress bar and a label.


Progress bars with labels

Description

shiny element displaying a series of progress bars and observation counts.

Usage

countBars(inputId, choices, countsmax, countsnow = NULL)

updateCountBars(
  session = getDefaultReactiveDomain(),
  inputId,
  choices,
  countsmax,
  countsnow = NULL
)

Arguments

inputId

(character(1)) shiny id of the parent element (e.g. a check-box group input).

choices

(vector) Available values. Used to determine label text.

countsmax

(numeric) Maximum counts of each element. Must be the same length choices.

countsnow

(numeric) Current counts of each element. Must be the same length choices.

session

(session) shiny session object passed to function given to shinyServer.

Value

List of shiny.tags.

Creates a number of progress bar elements, one for each value of choices. The widths of all progress bars add up to the full width of the container. Each progress bar has a text label that contains the name of the value and the number of counts.

If the filter panel is used with count_type = "all", the progress bars will be filled according to the number of counts remaining in the current selection and the label will show both the current and the total number of counts.

Each child element can have a unique id attribute to be used independently.

Examples

# use non-exported function from teal.slice
include_js_files <- getFromNamespace("include_js_files", "teal.slice")
include_css_files <- getFromNamespace("include_css_files", "teal.slice")
countBars <- getFromNamespace("countBars", "teal.slice")
updateCountBars <- getFromNamespace("updateCountBars", "teal.slice")

library(shiny)

choices <- sample(as.factor(c("a", "b", "c")), size = 20, replace = TRUE)
counts <- table(choices)
labels <- countBars(
  inputId = "counts",
  choices = c("a", "b", "c"),
  countsmax = counts,
  countsnow = unname(counts)
)

ui <- fluidPage(
  tags$div(
    class = "choices_state",
    include_js_files("count-bar-labels.js"),
    include_css_files(pattern = "filter-panel"),
    checkboxGroupInput(
      inputId = "choices",
      selected = levels(choices),
      choiceNames = labels,
      choiceValues = levels(choices),
      label = NULL
    )
  )
)
server <- function(input, output, session) {
  observeEvent(input$choices, {
    new_counts <- counts
    new_counts[!names(new_counts) %in% input$choices] <- 0
    updateCountBars(
      inputId = "counts",
      choices = levels(choices),
      countsmax = counts,
      countsnow = unname(new_counts)
    )
  })
}

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


Returns a choices_labeled object

Description

Returns a choices_labeled object

Usage

data_choices_labeled(
  data,
  choices,
  varlabels = teal.data::col_labels(data, fill = TRUE),
  keys = character(0)
)

Arguments

data

(data.frame or DFrame or list) where labels can be taken from in case when varlabels is not specified. data must be specified if varlabels is not specified.

choices

(character) the vector of chosen variables

varlabels

(character) the labels of variables in data

keys

(character) the names of the key columns in data

Value

character(0) if choices are empty; a choices_labeled object otherwise


Evaluate expression with meaningful message

Description

Method created for the FilteredData object to execute filter call with meaningful message. After evaluation used environment should contain all necessary bindings.

Usage

eval_expr_with_msg(expr, env)

Arguments

expr

(language)

env

(environment) where expression is evaluated.

Value

NULL, invisibly.


Get hex code of the current Bootstrap theme color.

Description

Determines the color specification for the currently active Bootstrap color theme and returns one queried color.

Usage

fetch_bs_color(color, alpha = NULL)

Arguments

color

(character(1)) naming one of the available theme colors

alpha

either a numeric(1) or character(1) specifying transparency in the range of 0-1 or a hexadecimal value 00-ff, respectively; set to NULL to omit adding the alpha channel

Value

Named character(1) containing a hexadecimal color representation.

Examples

fetch_bs_color <- getFromNamespace("fetch_bs_color", "teal.slice")
fetch_bs_color("primary")
fetch_bs_color("danger", 0.35)
fetch_bs_color("danger", "80")


Managing FilteredData states

Description

[Experimental]

Set, get and remove filter states of FilteredData object.

Usage

set_filter_state(datasets, filter)

get_filter_state(datasets)

remove_filter_state(datasets, filter)

clear_filter_states(datasets, force = FALSE)

Arguments

datasets

(FilteredData) object to store filter state and filtered datasets, shared across modules

see FilteredData for details

filter

(teal_slices) specify filters in place on app start-up

force

(logical(1)) flag specifying whether to include anchored filter states.

Value

See Also

teal_slice

Examples

datasets <- init_filtered_data(list(iris = iris, mtcars = mtcars))
fs <- teal_slices(
  teal_slice(dataname = "iris", varname = "Species", selected = c("setosa", "versicolor")),
  teal_slice(dataname = "iris", varname = "Sepal.Length", selected = c(5.1, 6.4)),
  teal_slice(dataname = "mtcars", varname = "gear", selected = c(4, 5)),
  teal_slice(dataname = "mtcars", varname = "carb", selected = c(4, 10))
)

# set initial filter state
set_filter_state(datasets, filter = fs)

# get filter state
get_filter_state(datasets)

# modify filter state
set_filter_state(
  datasets,
  teal_slices(
    teal_slice(dataname = "iris", varname = "Species", selected = "setosa", keep_na = TRUE)
  )
)

# remove specific filters
remove_filter_state(
  datasets,
  teal_slices(
    teal_slice(dataname = "iris", varname = "Species"),
    teal_slice(dataname = "mtcars", varname = "gear"),
    teal_slice(dataname = "mtcars", varname = "carb")
  )
)

# remove all states
clear_filter_states(datasets)


if (requireNamespace("MultiAssayExperiment", quietly = TRUE)) {
  # Requires MultiAssayExperiment from Bioconductor
  data(miniACC, package = "MultiAssayExperiment")

  datasets <- init_filtered_data(list(mae = miniACC))
  fs <- teal_slices(
    teal_slice(
      dataname = "mae", varname = "years_to_birth", selected = c(30, 50),
      keep_na = TRUE, keep_inf = FALSE
    ),
    teal_slice(
      dataname = "mae", varname = "vital_status", selected = "1",
      keep_na = FALSE
    ),
    teal_slice(
      dataname = "mae", varname = "gender", selected = "female",
      keep_na = TRUE
    ),
    teal_slice(
      dataname = "mae", varname = "ARRAY_TYPE", selected = "",
      keep_na = TRUE, experiment = "RPPAArray", arg = "subset"
    )
  )

  # set initial filter state
  set_filter_state(datasets, filter = fs)

  # get filter state
  get_filter_state(datasets)

  # modify filter state
  set_filter_state(
    datasets,
    teal_slices(
      teal_slice(dataname = "mae", varname = "years_to_birth", selected = c(40, 60))
    )
  )

  # remove specific filters
  remove_filter_state(
    datasets,
    teal_slices(
      teal_slice(dataname = "mae", varname = "years_to_birth"),
      teal_slice(dataname = "mae", varname = "vital_status")
    )
  )

  # remove all states
  clear_filter_states(datasets)
}


Format POSIXt for storage

Description

Convert POSIXt date time object to character representation in UTC time zone.

Usage

format_time(x)

Arguments

x

(POSIXt) vector of date time values or anything else

Details

Date times are stored as string representations expressed in the UTC time zone. The storage format is ⁠YYYY-MM-DD HH:MM:SS⁠.

Value

If x is of class POSIXt, a character vector, otherwise x itself.


Default teal_slice id

Description

Create a slice id if none provided.

Usage

get_default_slice_id(x)

Arguments

x

(teal_slice or list)

Details

Function returns a default id for a teal_slice object which needs to be distinct from other teal_slice objects created for any FilterStates object. Returned id can be treated as a location of a vector on which FilterState is built:

Value

(character(1)) id for a teal_slice object.


Gets filter expression for multiple datanames taking into account its order.

Description

[Stable]

To be used in ⁠Show R Code⁠ button.

Usage

get_filter_expr(datasets, datanames = datasets$datanames())

Arguments

datasets

(FilteredData)

datanames

(character) vector of dataset names

Value

A character string containing all subset expressions.


Gets supported filterable variable names

Description

Gets filterable variable names from a given object. The names match variables of classes in an vector teal.slice:::.filterable_class.

Usage

get_supported_filter_varnames(data)

Arguments

data

the R object containing elements which class can be checked through vapply or apply.

Value

character vector of variable names.

Examples

# use non-exported function from teal.slice
get_supported_filter_varnames <- getFromNamespace("get_supported_filter_varnames", "teal.slice")

df <- data.frame(
  a = letters[1:3],
  b = 1:3,
  c = Sys.Date() + 1:3,
  d = Sys.time() + 1:3,
  z = complex(3)
)
get_supported_filter_varnames(df)

Include CSS files from ⁠/inst/css/⁠ package directory to application header

Description

system.file should not be used to access files in other packages, it does not work with devtools. Therefore, we redefine this method in each package as needed. Thus, we do not export this method.

Usage

include_css_files(pattern = "*")

Arguments

pattern

(character) pattern of files to be included

Value

HTML code that includes CSS files


Include JS files from ⁠/inst/js/⁠ package directory to application header

Description

system.file should not be used to access files in other packages, it does not work with devtools. Therefore, we redefine this method in each package as needed. Thus, we do not export this method.

Usage

include_js_files(pattern)

Arguments

pattern

(character) pattern of files to be included, passed to system.file

Value

HTML code that includes JS files


Initialize FilterState

Description

Initializes a FilterState object corresponding to the class of the filtered variable.

Usage

init_filter_state(
  x,
  x_reactive = reactive(NULL),
  slice,
  extract_type = character(0)
)

Arguments

x

(vector) variable to be filtered.

x_reactive

(reactive) returning vector of the same type as x. Is used to update counts following the change in values of the filtered dataset. If it is set to reactive(NULL) then counts based on filtered dataset are not shown.

slice

(teal_slice) specification of this filter state. teal_slice is stored in the object and set_state directly manipulates values within teal_slice. get_state returns teal_slice object which can be reused in other places. Note that teal_slice is a reactiveValues, which means it has reference semantics, i.e. changes made to an object are automatically reflected in all places that refer to the same teal_slice.

extract_type

(character) specifying whether condition calls should be prefixed by dataname. Possible values:

  • character(0) (default) varname in the condition call will not be prefixed

  • "list" varname in the condition call will be returned as ⁠<dataname>$<varname>⁠

  • "matrix" varname in the condition call will be returned as ⁠<dataname>[, <varname>]⁠

Value

FilterState object

Examples

# use non-exported function from teal.slice
init_filter_state <- getFromNamespace("init_filter_state", "teal.slice")

library(shiny)

filter_state <- init_filter_state(
  x = c(1:10, NA, Inf),
  x_reactive = reactive(c(1:10, NA, Inf)),
  slice = teal_slice(
    varname = "varname",
    dataname = "dataname"
  ),
  extract_type = "matrix"
)

isolate(filter_state$get_call())

# working filter in an app

ui <- fluidPage(
  filter_state$ui(id = "app"),
  verbatimTextOutput("call")
)
server <- function(input, output, session) {
  filter_state$server("app")

  output$call <- renderText(
    deparse1(filter_state$get_call(), collapse = "\n")
  )
}

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


Initialize a FilterStateExpr object

Description

Initialize a FilterStateExpr object

Usage

init_filter_state_expr(slice)

Arguments

slice

(teal_slice_expr) specifying this filter state.

Value

FilterStateExpr object


Initialize FilterStates object

Description

Initialize FilterStates object

Usage

init_filter_states(
  data,
  data_reactive = reactive(NULL),
  dataname,
  datalabel = NULL,
  ...
)

Arguments

data

(data.frame or MultiAssayExperiment or SummarizedExperiment or matrix) object to subset.

data_reactive

(⁠function(sid)⁠) should return an object of the same type as data or NULL. This function is needed for the FilterState shiny module to update counts if filtered data changes. If function returns NULL then filtered counts are not shown. Function has to have sid argument being a character which is related to sid argument in the get_call method.

dataname

(character(1)) name of the data used in the subset expression, passed to the function argument attached to this FilterStates.

datalabel

(character(1)) optional text label.

...

optional, additional arguments for specific classes: keys.

Value

Object of class FilterStates.

Examples

# use non-exported function from teal.slice
init_filter_states <- getFromNamespace("init_filter_states", "teal.slice")

df <- data.frame(
  character = letters,
  numeric = seq_along(letters),
  date = seq(Sys.Date(), length.out = length(letters), by = "1 day"),
  datetime = seq(Sys.time(), length.out = length(letters), by = "33.33 hours")
)
rf <- init_filter_states(
  data = df,
  dataname = "DF"
)

library(shiny)
ui <- fluidPage(
  actionButton("clear", tags$span(icon("xmark"), "Remove all filters")),
  rf$ui_add(id = "add"),
  rf$ui_active("states"),
  verbatimTextOutput("expr"),
)

server <- function(input, output, session) {
  rf$srv_add(id = "add")
  rf$srv_active(id = "states")
  output$expr <- renderText({
    deparse1(rf$get_call(), collapse = "\n")
  })
  observeEvent(input$clear, rf$clear_filter_states())
}

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


Initialize FilteredData

Description

Function creates a FilteredData object.

Usage

init_filtered_data(x, join_keys = teal.data::join_keys())

Arguments

x

(⁠named list⁠) of datasets.

join_keys

(join_keys) see teal.data::join_keys().

Value

Object of class FilteredData.

Examples

datasets <- init_filtered_data(list(iris = iris, mtcars = mtcars))
datasets


Initialize FilteredDataset

Description

Initializes a FilteredDataset object corresponding to the class of the filtered dataset.

Usage

init_filtered_dataset(
  dataset,
  dataname,
  keys = character(0),
  parent_name = character(0),
  parent = reactive(dataset),
  join_keys = character(0),
  label = attr(dataset, "label", exact = TRUE)
)

Arguments

dataset

any object

dataname

(character(1)) syntactically valid name given to the dataset.

keys

(character) optional vector of primary key column names.

parent_name

(character(1)) name of the parent dataset.

parent

(reactive) that returns a filtered data.frame from other FilteredDataset named parent_name. Passing parent results in a reactive link that causes re-filtering of this dataset based on the changes in parent.

join_keys

(character) vector of names of columns in this dataset to join with parent dataset. If column names in the parent do not match these, they should be given as the names of this vector.

label

(character(1)) label to describe the dataset.

Value

Object of class FilteredDataset.

Warning

This function is exported to allow other packages to extend teal.slice but it is treated as internal. Breaking changes may occur without warning. We recommend consulting the package maintainer before using it.

Examples

# DataframeFilteredDataset example
library(shiny)

iris_fd <- init_filtered_dataset(iris, dataname = "iris")
ui <- fluidPage(
  iris_fd$ui_add(id = "add"),
  iris_fd$ui_active("dataset"),
  verbatimTextOutput("call")
)
server <- function(input, output, session) {
  iris_fd$srv_add(id = "add")
  iris_fd$srv_active(id = "dataset")

  output$call <- renderText({
    paste(
      vapply(iris_fd$get_call(), deparse1, character(1), collapse = "\n"),
      collapse = "\n"
    )
  })
}
if (interactive()) {
  shinyApp(ui, server)
}


if (requireNamespace("MultiAssayExperiment", quietly = TRUE)) {
  # MAEFilteredDataset example
  library(shiny)

  data(miniACC, package = "MultiAssayExperiment")

  MAE_fd <- init_filtered_dataset(miniACC, "MAE")
  ui <- fluidPage(
    MAE_fd$ui_add(id = "add"),
    MAE_fd$ui_active("dataset"),
    verbatimTextOutput("call")
  )
  server <- function(input, output, session) {
    MAE_fd$srv_add(id = "add")
    MAE_fd$srv_active(id = "dataset")
    output$call <- renderText({
      paste(
        vapply(MAE_fd$get_call(), deparse1, character(1), collapse = "\n"),
        collapse = "\n"
      )
    })
  }
  if (interactive()) {
    shinyApp(ui, server)
  }
}


Convert a list to a justified JSON string

Description

This function takes a list and converts it to a JSON string. The resulting JSON string is then optionally justified to improve readability and trimmed to easier fit in the console when printing.

Usage

jsonify(x, trim_lines)

Arguments

x

(list), possibly recursive, obtained from teal_slice or teal_slices.

trim_lines

(logical(1)) flag specifying whether to trim lines of the JSON string.

Value

A JSON string representation of the input list.


Justify colons in JSON string

Description

This function takes a JSON string as input, splits it into lines, and pads element names with spaces so that colons are justified between lines.

Usage

justify_json(json)

Arguments

json

(character(1)) a JSON string.

Value

A list of character strings, which can be collapsed into a JSON string.


Build concatenating call

Description

This function takes a vector of values and returns a c call. If the vector has only one element, the element is returned directly.

Usage

make_c_call(choices)

Arguments

choices

A vector of values.

Value

A c call.

Examples

# use non-exported function from teal.slice
make_c_call <- getFromNamespace("make_c_call", "teal.slice")
make_c_call(1:3)
make_c_call(1)


Build count text

Description

Returns a text label describing filtered counts. The text is composed in the following way:

Usage

make_count_text(label, countmax, countnow = NULL)

Arguments

label

(character(1)) Text displayed before counts.

countmax

(numeric(1)) Number of unfiltered counts.

countnow

(numeric(1)) Number of filtered counts.

Value

A character string.


Adjust counts to match choices

Description

Adjust counts to match choices

Usage

pair_counts(choices, counts)

Arguments

choices

(character) Choices to match.

counts

(⁠named numeric⁠) Counts to adjust.


Encodes ids to be used in JavaScript and Shiny

Description

Replaces non-ASCII characters into a format that can be used in HTML, JavaScript and Shiny.

When the id has a character that is not allowed, it is replaced with "_" and a 4 character hash of the original id is added to the start of the resulting id.

Usage

sanitize_id(id)

Arguments

id

(character(1)) The id string.

Value

Sanitized string that removes special characters and spaces.


setdiff method for teal_slices

Description

Compare two teal slices objects and return teal_slices containing slices present in x but not in y.

Usage

setdiff_teal_slices(x, y)

Arguments

x, y

(teal_slices)

Value

teal_slices


Specify single filter

Description

Create a teal_slice object that holds complete information on filtering one variable. Check out teal_slice-utilities functions for working with teal_slice object.

Usage

teal_slice(
  dataname,
  varname,
  id,
  expr,
  choices = NULL,
  selected = NULL,
  keep_na = NULL,
  keep_inf = NULL,
  fixed = FALSE,
  anchored = FALSE,
  multiple = TRUE,
  title = NULL,
  ...
)

Arguments

dataname

(character(1)) name of data set

varname

(character(1)) name of variable

id

(character(1)) identifier of the filter. Must be specified when expr is set. When varname is specified then id is set to "{dataname} {varname}" by default.

expr

(character(1)) string providing a logical expression. Must be a valid R expression which can be evaluated in the context of the data set. For a data.frame var == "x" is sufficient, but MultiAssayExperiment::subsetByColData requires dataname prefix, e.g. data$var == "x".

choices

(vector) optional, specifies allowed choices; When specified it should be a subset of values in variable denoted by varname; Type and size depends on variable type. Factors are coerced to character.

selected

(vector) optional, specifies selected values from choices; Type and size depends on variable type. Factors are coerced to character.

keep_na

(logical(1)) optional flag specifying whether to keep missing values

keep_inf

(logical(1)) optional flag specifying whether to keep infinite values

fixed

(logical(1)) flag specifying whether to fix this filter state (forbid setting state)

anchored

(logical(1)) flag specifying whether to lock this filter state (forbid removing and inactivating)

multiple

(logical(1)) optional flag specifying whether more than one value can be selected; only applicable to ChoicesFilterState and LogicalFilterState

title

(character(1)) optional title of the filter. Ignored when varname is set.

...

additional arguments which can be handled by extensions of teal.slice classes.

Details

teal_slice object fully describes filter state and can be used to create, modify, and delete a filter state. A teal_slice contains a number of common fields (all named arguments of teal_slice), some of which are mandatory, but only dataname and either varname or expr must be specified, while the others have default values.

Setting any of the other values to NULL means that those properties will not be modified (when setting an existing state) or that they will be determined by data (when creating new a new one). Entire object is FilterState class member and can be accessed with FilterState$get_state().

A teal_slice can come in two flavors:

  1. teal_slice_var - this describes a typical interactive filter that refers to a single variable, managed by the FilterState class. This class is created when varname is specified. The object retains all fields specified in the call. id can be created by default and need not be specified.

  2. teal_slice_expr - this describes a filter state that refers to an expression, which can potentially include multiple variables, managed by the FilterStateExpr class. This class is created when expr is specified. dataname and anchored are retained, fixed is set to TRUE, id becomes mandatory, title remains optional, while other arguments are disregarded.

A teal_slice can be passed FilterState/FilterStateExpr constructors to instantiate an object. It can also be passed to FilterState$set_state to modify the state. However, once a FilterState is created, only the mutable features can be set with a teal_slice: selected, keep_na and keep_inf.

Special consideration is given to two fields: fixed and anchored. These are always immutable logical flags that default to FALSE. In a FilterState instantiated with fixed = TRUE the features selected, keep_na, keep_inf cannot be changed. Note that a FilterStateExpr is always considered to have fixed = TRUE. A FilterState instantiated with anchored = TRUE cannot be removed.

Value

A teal.slice object. Depending on whether varname or expr was specified, the resulting teal_slice also receives class teal_slice_var or teal_slice_expr, respectively.

Filters in SumarizedExperiment and MultiAssayExperiment objects

To establish a filter on a column in a data.frame, dataname and varname are sufficient. MultiAssayExperiment objects can be filtered either on their colData slot (which contains subject information) or on their experiments, which are stored in the experimentList slot. For filters referring to colData no extra arguments are needed. If a filter state is created for an experiment, that experiment name must be specified in the experiment argument. Furthermore, to specify filter for an SummarizedExperiment one must also set arg ("subset" or "select", arguments in the subset() function for SummarizedExperiment) in order to determine whether the filter refers to the SE's rowData or colData.

Note

Date time objects of POSIX*t classes are printed as strings after converting to UTC timezone.

See Also

teal_slices, is.teal_slice, as.teal_slice, as.list.teal_slice, print.teal_slice, format.teal_slice

Examples

x1 <- teal_slice(
  dataname = "data",
  id = "Female adults",
  expr = "SEX == 'F' & AGE >= 18",
  title = "Female adults"
)
x2 <- teal_slice(
  dataname = "data",
  varname = "var",
  choices = c("F", "M", "U"),
  selected = "F",
  keep_na = TRUE,
  keep_inf = TRUE,
  fixed = FALSE,
  anchored = FALSE,
  multiple = TRUE,
  id = "Gender",
  extra_arg = "extra"
)

is.teal_slice(x1)
as.list(x1)
as.teal_slice(list(dataname = "a", varname = "var"))
format(x1)
format(x1, show_all = TRUE, trim_lines = FALSE)
print(x1)
print(x1, show_all = TRUE, trim_lines = FALSE)


teal_slice utility functions

Description

Helper functions for working with teal_slice object.

Usage

is.teal_slice(x)

as.teal_slice(x)

## S3 method for class 'teal_slice'
as.list(x, ...)

## S3 method for class 'teal_slice'
format(x, show_all = FALSE, trim_lines = TRUE, ...)

## S3 method for class 'teal_slice'
print(x, ...)

Arguments

x

(teal.slice)

...

additional arguments passed to other functions.

show_all

(logical(1)) indicating whether to show all fields. If set to FALSE, only non-NULL elements will be printed.

trim_lines

(logical(1)) indicating whether to trim lines when printing.

Examples

x1 <- teal_slice(
  dataname = "data",
  id = "Female adults",
  expr = "SEX == 'F' & AGE >= 18",
  title = "Female adults"
)
x2 <- teal_slice(
  dataname = "data",
  varname = "var",
  choices = c("F", "M", "U"),
  selected = "F",
  keep_na = TRUE,
  keep_inf = TRUE,
  fixed = FALSE,
  anchored = FALSE,
  multiple = TRUE,
  id = "Gender",
  extra_arg = "extra"
)

is.teal_slice(x1)
as.list(x1)
as.teal_slice(list(dataname = "a", varname = "var"))
format(x1)
format(x1, show_all = TRUE, trim_lines = FALSE)
print(x1)
print(x1, show_all = TRUE, trim_lines = FALSE)


Complete filter specification

Description

Create teal_slices object to package multiple filters and additional settings. Check out teal_slices-utilities functions for working with teal_slices object.

Usage

teal_slices(
  ...,
  exclude_varnames = NULL,
  include_varnames = NULL,
  count_type = NULL,
  allow_add = TRUE
)

Arguments

...

any number of teal_slice objects.

include_varnames, exclude_varnames

(⁠named list⁠s of character) where list names match names of data sets and vector elements match variable names in respective data sets; specify which variables are allowed to be filtered; see Details.

count_type

[Experimental] This is a new feature. Do kindly share your opinions on teal.slice's GitHub repository.

(character(1)) string specifying how observations are tallied by these filter states. Possible options:

  • "none" (default) to have counts of single FilterState to show unfiltered number only.

  • "all" to have counts of single FilterState to show number of observation in filtered and unfiltered dataset. Note, that issues were reported when using this option with MultiAssayExperiment. Please make sure that adding new filters doesn't fail on target platform before deploying for production.

allow_add

(logical(1)) logical flag specifying whether the user will be able to add new filters

Details

teal_slices() collates multiple teal_slice objects into a teal_slices object, a complete filter specification. This is used by all classes above FilterState as well as filter_panel_api wrapper functions. teal_slices has attributes that modify the behavior of the filter panel, which are resolved by different classes.

include_varnames and exclude_varnames determine which variables can have filters assigned. The former enumerates allowed variables, the latter enumerates forbidden values. Since these could be mutually exclusive, it is impossible to set both allowed and forbidden variables for one data set in one teal_slices.

Value

teal_slices, which is an unnamed list of teal_slice objects.

See Also

Examples

filter_1 <- teal_slice(
  dataname = "dataname1",
  varname = "varname1",
  choices = letters,
  selected = "b",
  keep_na = TRUE,
  fixed = FALSE,
  extra1 = "extraone"
)
filter_2 <- teal_slice(
  dataname = "dataname1",
  varname = "varname2",
  choices = 1:10,
  keep_na = TRUE,
  selected = 2,
  fixed = TRUE,
  anchored = FALSE,
  extra2 = "extratwo"
)
filter_3 <- teal_slice(
  dataname = "dataname2",
  varname = "varname3",
  choices = 1:10 / 10,
  keep_na = TRUE,
  selected = 0.2,
  fixed = TRUE,
  anchored = FALSE,
  extra1 = "extraone",
  extra2 = "extratwo"
)

all_filters <- teal_slices(
  filter_1,
  filter_2,
  filter_3,
  exclude_varnames = list(
    "dataname1" = "varname2"
  )
)

is.teal_slices(all_filters)
all_filters[1:2]
c(all_filters[1], all_filters[2])
print(all_filters)
print(all_filters, trim_lines = FALSE)


teal_slices utility functions

Description

Helper functions for working with teal_slices object.

Usage

is.teal_slices(x)

as.teal_slices(x)

## S3 method for class 'teal_slices'
as.list(x, recursive = FALSE, ...)

## S3 method for class 'teal_slices'
x[i]

## S3 method for class 'teal_slices'
c(...)

## S3 method for class 'teal_slices'
format(x, show_all = FALSE, trim_lines = TRUE, ...)

## S3 method for class 'teal_slices'
print(x, ...)

Arguments

x

object to test for teal_slices, object to convert to teal_slices or a teal_slices object

recursive

(logical(1)) flag specifying whether to also convert to list the elements of this teal_slices

...

additional arguments passed to other functions.

i

(character or numeric or logical) indicating which elements to extract

show_all

(logical(1)) whether to display non-null elements of constituent teal_slice objects

trim_lines

(logical(1)) whether to trim lines

Examples

filter_1 <- teal_slice(
  dataname = "dataname1",
  varname = "varname1",
  choices = letters,
  selected = "b",
  keep_na = TRUE,
  fixed = FALSE,
  extra1 = "extraone"
)
filter_2 <- teal_slice(
  dataname = "dataname1",
  varname = "varname2",
  choices = 1:10,
  keep_na = TRUE,
  selected = 2,
  fixed = TRUE,
  anchored = FALSE,
  extra2 = "extratwo"
)
filter_3 <- teal_slice(
  dataname = "dataname2",
  varname = "varname3",
  choices = 1:10 / 10,
  keep_na = TRUE,
  selected = 0.2,
  fixed = TRUE,
  anchored = FALSE,
  extra1 = "extraone",
  extra2 = "extratwo"
)

all_filters <- teal_slices(
  filter_1,
  filter_2,
  filter_3,
  exclude_varnames = list(
    "dataname1" = "varname2"
  )
)

is.teal_slices(all_filters)
all_filters[1:2]
c(all_filters[1], all_filters[2])
print(all_filters)
print(all_filters, trim_lines = FALSE)


Converts a list to a JSON string

Description

Converts a list representation of teal_slice or teal_slices into a JSON string. Ensures proper unboxing of list elements. This function is used by the format methods for teal_slice and teal_slices.

Usage

to_json(x)

Arguments

x

(list) representation of teal_slices object.

Value

A JSON string.


Toggle button properties.

Description

Switch between different icons or titles on a button.

Usage

toggle_icon(input_id, icons, one_way = FALSE)

toggle_title(input_id, titles, one_way = FALSE)

Arguments

input_id

(character(1)) (name-spaced) id of the button

icons, titles

(character(2)) vector specifying values between which to toggle

one_way

(logical(1)) flag specifying whether to keep toggling; if TRUE, the target will be changed from the first element of icons/titles to the second

Details

Wrapper functions that use shinyjs::runjs to change button properties in response to events, typically clicking those very buttons. shiny's actionButton and actionLink create ⁠<a>⁠ tags, which may contain a child ⁠<i>⁠ tag that specifies an icon to be displayed. toggle_icon calls the toggleClass (when one_way = FALSE) or removeClass and addClass methods (when one_way = TRUE) to change icons. toggle_title calls the attr method to modify the Title attribute of the button.

Value

NULL, invisibly.

Examples

# use non-exported function from teal.slice
toggle_icon <- getFromNamespace("toggle_icon", "teal.slice")

library(shiny)
library(shinyjs)

ui <- fluidPage(
  useShinyjs(),
  actionButton("hide_content", label = "hide", icon = icon("xmark")),
  actionButton("show_content", label = "show", icon = icon("check")),
  actionButton("toggle_content", label = "toggle", icon = icon("angle-down")),
  tags$br(),
  tags$div(
    id = "content",
    verbatimTextOutput("printout")
  )
)

server <- function(input, output, session) {
  observeEvent(input$hide_content,
    {
      hide("content")
      toggle_icon("toggle_content", c("fa-angle-down", "fa-angle-right"), one_way = TRUE)
    },
    ignoreInit = TRUE
  )

  observeEvent(input$show_content,
    {
      show("content")
      toggle_icon("toggle_content", c("fa-angle-right", "fa-angle-down"), one_way = TRUE)
    },
    ignoreInit = TRUE
  )

  observeEvent(input$toggle_content,
    {
      toggle("content")
      toggle_icon("toggle_content", c("fa-angle-right", "fa-angle-down"))
    },
    ignoreInit = TRUE
  )

  output$printout <- renderPrint({
    head(faithful, 10)
  })
}
if (interactive()) {
  shinyApp(ui, server)
}


Topological graph sort

Description

Graph is a list which for each node contains a vector of child nodes in the returned list, parents appear before their children.

Usage

topological_sort(graph)

Arguments

graph

(⁠named list⁠) with node vector elements

Details

Implementation of Kahn algorithm with a modification to maintain the order of input elements.

Examples

# use non-exported function from teal.slice
topological_sort <- getFromNamespace("topological_sort", "teal.slice")

topological_sort(list(A = c(), B = c("A"), C = c("B"), D = c("A")))
topological_sort(list(D = c("A"), A = c(), B = c("A"), C = c("B")))
topological_sort(list(D = c("A"), B = c("A"), C = c("B"), A = c()))

Trim lines in JSON string

Description

This function takes a JSON string as input and returns a modified version of the input where the values portion of each line is trimmed for a less messy console output.

Usage

trim_lines_json(x)

Arguments

x

(character)

Value

A character string trimmed after a certain hard-coded number of characters in the value portion.


Get classes of selected columns from dataset

Description

Get classes of selected columns from dataset

Usage

variable_types(data, columns = NULL)

Arguments

data

(data.frame or DataFrame or matrix) Object in which to determine variable types.

columns

(character) Vector of columns in data for which to get types. Set to NULL to get types of all columns.

Value

Character vector of classes of columns from provided data.

Examples

# use non-exported function from teal.slice
variable_types <- getFromNamespace("variable_types", "teal.slice")

variable_types(
  data.frame(
    x = 1:3, y = factor(c("a", "b", "a")), z = c("h1", "h2", "h3"),
    stringsAsFactors = FALSE
  ),
  "x"
)

variable_types(
  data.frame(
    x = 1:3, y = factor(c("a", "b", "a")), z = c("h1", "h2", "h3"),
    stringsAsFactors = FALSE
  ),
  c("x", "z")
)

variable_types(
  data.frame(
    x = 1:3, y = factor(c("a", "b", "a")), z = c("h1", "h2", "h3"),
    stringsAsFactors = FALSE
  )
)