Title: Shared Utilities to Extend the 'teal' Modules
Language: en-US
Version: 0.0.2
Date: 2026-02-12
URL: https://github.com/phuse-org/uteals
Description: Provides decorators, transformators, and utility functions to extend the 'teal' framework for interactive data analysis applications. Implements methods for data visualization enhancement, statistical data transformations, and workflow integration tools. Designed to support clinical and pharmaceutical research workflows within the 'teal' ecosystem through modular and reusable components.
License: MIT + file LICENSE
Encoding: UTF-8
RoxygenNote: 7.3.3
Depends: R (≥ 4.1.0)
Imports: R6, checkmate, cowplot, dplyr, formatters, ggplot2, ggplotify, junco, methods, openxlsx, patchwork, rlang, rtables, shiny, shinyBS, shinyWidgets, shinyjs, teal, teal.code, tern, yaml, teal.modules.clinical
Suggests: forcats, knitr, rAccess, rmarkdown, teal.data, teal.modules.general, teal.transform
VignetteBuilder: knitr
NeedsCompilation: no
Packaged: 2026-02-12 12:47:03 UTC; kpagacz
Author: Nadia Abraham [aut], Chanchal Bhalla [aut], Peyman Eshghi [aut, cre], Pranith Gourisetty [aut], Sohan Lal [aut], Przemyslaw Posiadala [aut], Alina Tselinina [aut], Konrad Pagacz [aut], PHUSE [cph]
Maintainer: Peyman Eshghi <peymaan.es@gmail.com>
Repository: CRAN
Date/Publication: 2026-02-17 15:40:02 UTC

Decorators and transformators for teal modules.

Description

Provides decorator and transformator modules for teal modules.

Author(s)

Maintainer: Konrad Pagacz konrad.pagacz@gmail.com

Authors:

Other contributors:

See Also

Useful links:


Class BlockConditions

Description

This class represents a collection of conditions used for filtering datasets.

Slots

conditions

A list of conditions, where each condition is a list containing variable, operator, and value.


Add a condition to a BlockConditions object

Description

Add a condition to a BlockConditions object

Usage

add_condition(object, variable, operator, value)

Arguments

object

A BlockConditions object.

variable

A character string specifying the variable/column name.

operator

A character string specifying the operator (e.g., "==", "!=", "<", ">", "<=", ">=").

value

The value to compare against.

Value

An updated BlockConditions object with the new condition added.


Add conditions

Description

Add conditions

Usage

## S4 method for signature 'BlockConditions'
add_condition(object, variable, operator, value)

Create Relative risk column

Description

[Experimental]

Usage

create_rel_risk_transformator(dataname, column_name, control_group, label_name)

Arguments

dataname

(character(1)) the name of the dataset which columns will be used for possible transformation. dataname should be passed in quotes ex: "ADSL".

column_name

(character(1)) field or variable from the dataset.

control_group

(character(1)) one of the existing level from the selected column_name.

label_name

(character(1)) label for the new field or variable.

Details

This transformator allows the user to select a column and control group from the dataset and create a relative risk column.

Value

teal::teal_transform_module

Examples


app <- teal::init(
  data = teal.data::teal_data(IRIS = iris, code = "IRIS <- iris"),
  modules = teal::modules(
    teal::example_module(
      transformators = list(create_rel_risk_transformator("IRIS"))
    )
  )
)
if (interactive()) {
  shiny::shinyApp(app$ui, app$server)
}


Extract Non-Parent Module Labels to YAML

Description

[Experimental] Extracts module labels from a teal modules object, filters out parent modules (grouping containers), and generates a YAML file with the functional modules.

Usage

extract_modules_to_yaml(mods, filepath, verbose = FALSE)

Arguments

mods

(teal_module or teal_modules) a teal modules object containing the module structure.

filepath

(character(1)) character string specifying the output YAML file path.

verbose

(logical(1)) whether to print informational messages. Default is FALSE.

Value

Character vector of non-parent module labels

Examples

# Extract modules from mods object to YAML file
mods <- teal::modules(
  teal::example_module("mod1"),
  teal::example_module("mod2")
)
labels <- extract_modules_to_yaml(mods, "panel_str_modules.yml")
unlink("panel_str_modules.yml")


View model for or_filtering_transformator().

Description

View model for or_filtering_transformator().

View model for or_filtering_transformator().

Public fields

block_objects

Block objects.

r_vals

Reactive values.

alt_id

The id of the last alternative.

block_conditions

Conditions as strings.

choices_for_columns

Choices for the columns.

final_filter_expr

Final filtering expression.

final_exp

Final expression for teal.data. Initializes the object

Methods

Public methods


Method new()

Usage
filtering_transformator_model$new(data, dataname)
Arguments
data

the reactive data object from teal.

dataname

character(1) the name of the dataset.


Method add_alternative()

Usage
filtering_transformator_model$add_alternative()
Returns

invisibly self.


Method is_duplicate_condition()

Usage
filtering_transformator_model$is_duplicate_condition(cond_str, block_cond_list)
Arguments
cond_str

character(1) added condition.

block_cond_list

character(1) list of all conditions.

Returns

logical(1) whether the added condition is a duplicate.


Method clone()

The objects of this class are cloneable with this method.

Usage
filtering_transformator_model$clone(deep = FALSE)
Arguments
deep

Whether to make a deep clone.


Change X-axis scaling decorator for teal.modules.clinical::tm_g_forest_rsp.

Description

[Experimental] A function to create a UI component for selecting a transform function for the forest plot x axis.

Usage

forestplot_x_decorator()

Details

The module creates a UI with a radio control for selecting the transform function. The selected transformation function is applied to the forest plot to update the plot's axis and annotations accordingly.

Value

teal::teal_transform_module Returns a modified plot object with the transformation applied.

Examples

library(teal.modules.clinical)
data <- teal.data::teal_data()
data <- within(data, {
  ADSL <- teal.modules.clinical::tmc_ex_adsl
  ADRS <- teal.modules.clinical::tmc_ex_adrs |>
    dplyr::mutate(AVALC = tern::d_onco_rsp_label(AVALC) |>
      formatters::with_label("Character Result/Finding")) |>
    dplyr::filter(PARAMCD != "OVRINV" | AVISIT == "FOLLOW UP")
})
teal.data::join_keys(data) <- teal.data::default_cdisc_join_keys[names(data)]

ADSL <- data[["ADSL"]]
ADRS <- data[["ADRS"]]

arm_ref_comp <- list(
  ARM = list(
    ref = "B: Placebo",
    comp = c("A: Drug X", "C: Combination")
  ),
  ARMCD = list(
    ref = "ARM B",
    comp = c("ARM A", "ARM C")
  )
)

app <- teal::init(
  data = data,
  modules = teal::modules(
    teal.modules.clinical::tm_g_forest_rsp(
      label = "Forest Response",
      dataname = "ADRS",
      arm_var = choices_selected(
        variable_choices(ADSL, c("ARM", "ARMCD")),
        "ARMCD"
      ),
      arm_ref_comp = arm_ref_comp,
      paramcd = choices_selected(
        value_choices(ADRS, "PARAMCD", "PARAM"),
        "INVET"
      ),
      subgroup_var = choices_selected(
        variable_choices(ADSL, names(ADSL)),
        c("BMRKR2", "SEX")
      ),
      strata_var = choices_selected(
        variable_choices(ADSL, c("STRATA1", "STRATA2")),
        "STRATA2"
      ),
      plot_height = c(600L, 200L, 2000L),
      decorators = list(
        plot = forestplot_x_decorator()
      ),
      default_responses = list(
        BESRSPI = list(
          rsp = c("Stable Disease (SD)", "Not Evaluable (NE)"),
          levels = c(
            "Complete Response (CR)", "Partial Response (PR)", "Stable Disease (SD)",
            "Progressive Disease (PD)", "Not Evaluable (NE)"
          )
        ),
        INVET = list(
          rsp = c("Complete Response (CR)", "Partial Response (PR)"),
          levels = c(
            "Complete Response (CR)", "Not Evaluable (NE)", "Partial Response (PR)",
            "Progressive Disease (PD)", "Stable Disease (SD)"
          )
        ),
        OVRINV = list(
          rsp = c("Progressive Disease (PD)", "Stable Disease (SD)"),
          levels = c("Progressive Disease (PD)", "Stable Disease (SD)", "Not Evaluable (NE)")
        )
      )
    )
  )
)
if (interactive()) {
  shinyApp(app$ui, app$server)
}


Create a forest plot from an rtable with x transform settings

Description

[Experimental] Given a rtables::rtable() object with at least one column with a single value and one column with 2 values, converts table to a ggplot2::ggplot() object and generates an accompanying forest plot. The table and forest plot are printed side-by-side.

Usage

g_forest_with_transform(
  tbl,
  col_x = attr(tbl, "col_x"),
  col_ci = attr(tbl, "col_ci"),
  vline = 1,
  forest_header = attr(tbl, "forest_header"),
  xlim = c(0.1, 10),
  transform_x = NA,
  x_at = c(0.1, 1, 10),
  width_columns = NULL,
  lbl_col_padding = 0,
  rel_width_forest = 0.25,
  font_size = 12,
  col_symbol_size = attr(tbl, "col_symbol_size"),
  col = getOption("ggplot2.discrete.colour")[1],
  ggtheme = NULL,
  as_list = FALSE
)

Arguments

tbl

(VTableTree)
rtables table with at least one column with a single value and one column with 2 values.

col_x

(integer(1) or NULL)
column index with estimator. By default tries to get this from tbl attribute col_x, otherwise needs to be manually specified. If NULL, points will be excluded from forest plot.

col_ci

(integer(1) or NULL)
column index with confidence intervals. By default tries to get this from tbl attribute col_ci, otherwise needs to be manually specified. If NULL, lines will be excluded from forest plot.

vline

(numeric)
position of the vertical reference line on the plot. like 0 and 1 in forest plot.

forest_header

(character(2))
text displayed to the left and right of vline, respectively. If vline = NULL then forest_header is not printed. By default tries to get this from tbl attribute forest_header. If NULL, defaults will be extracted from the table if possible, and set to "Comparison\nBetter" and "Treatment\nBetter" if not.

xlim

(numeric)
range of x-axis limits. Example: c(0.1, 10)

transform_x

(character)
function for x-values transformation

x_at

(numeric)
specifies the tick marks on the axis. The value of union(xlim, vline) or Example: c(0.1,1,10).

width_columns

(numeric)
a vector of column widths. Each element's position in colwidths corresponds to the column of tbl in the same position. If NULL, column widths are calculated according to maximum number of characters per column.

lbl_col_padding

(numeric)
padding between label and columns value. Default is 0.

rel_width_forest

(proportion)
proportion of total width to allocate to the forest plot. Relative width of table is then 1 - rel_width_forest. If as_list = TRUE, this parameter is ignored.

font_size

(numeric(1))
font size.

col_symbol_size

(numeric or NULL)
column index from tbl containing data to be used to determine relative size for estimator plot symbol. Typically, the symbol size is proportional to the sample size used to calculate the estimator. If NULL, the same symbol size is used for all subgroups. By default tries to get this from tbl attribute col_symbol_size, otherwise needs to be manually specified.

col

(character)
color(s).

ggtheme

(theme)
a graphical theme as provided by ggplot2 to control styling of the plot.

as_list

(flag)
whether the two ggplot objects should be returned as a list. If TRUE, a named list with two elements, table and plot, will be returned. If FALSE (default) the table and forest plot are printed side-by-side via cowplot::plot_grid().

Value

ggplot forest plot and table.


Get condition expression

Description

Get condition expression

Usage

get_str_expression(object, dataname, data)

Arguments

object

A BlockConditions object.

dataname

character(1) The name of the dataset to filter.

data

The reactive data object from teal.

Value

character(1) The condition expression.


Get condition expression

Description

Get condition expression

Usage

## S4 method for signature 'BlockConditions'
get_str_expression(object, dataname, data)

ggplot decorator

Description

[Experimental] Decorator function to update various settings for ggplot plot objects

Usage

ggplot_decorator(
  output_name,
  label_text = "decorator",
  render_ui = c(),
  plot_options = list(title = "", footnote = "", y_breaks = "", y_limits_max = "",
    y_limits_min = "", x_breaks = "", x_labels_discrete = "", x_labels_cont = "",
    y_labels_discrete = "", y_labels_cont = "", font_size_geom_text = "",
    font_size_plot_title = "", font_size_axis_title = "", font_size_axis_text = "")
)

Arguments

output_name

a name for the output plot object.

label_text

customized label text for the decorator

render_ui

vector of ggplot_options from the following list: "title" - Title of the plot, "footnote" - Footnote of the plot, "y_breaks" - Value of breaks(numeric) for y-axis. Note: y_limits_max and y_limits_min should also be provided, "y_limits_max" - Value of y-axis maximum limit(numeric). Note: y_limits_max and y_breaks should also be provided, "y_limits_min" - Value of y-axis minimum limit(numeric). Note: y_breaks and y_limits_min should also be provided, "x_breaks"- Value of breaks for continuous x-axis(numeric). Note: should be comma separated, "x_labels_discrete" - Values of labels for discrete x-axis. Note: should be comma separated, "x_labels_cont" - Values of labels for continuous x-axis. Note: should be comma separated, "y_labels_discrete" - Values of labels for discrete y-axis. Note: should be comma separated, "y_labels_cont" - Values of labels for continuous y-axis. Note: should be comma separated, "font_size_geom_text" - Font size of geom_text. Note: numeric value should be provided, "font_size_plot_title"- Font size of plot title text. Note: numeric value should be provided, "font_size_axis_title"- Font size of axis title text. Note: numeric value should be provided, "font_size_axis_text"- Font size of axis labels text. Note: numeric value should be provided

plot_options

named list with the list of values for the ggplot options. The app developer can specify the required list of options while calling the decorator.

Details

The module creates a UI with text controls for specifying the list of ggplot options given in the plot_options parameter value. The entered ggplot options are applied to ggplot plot object.

Value

teal::teal_transform_module Returns a modified plot object with the transformation applied.

Examples

app <- teal::init(
  data = teal.data::teal_data(IRIS = iris, code = "IRIS <- iris"),
  modules = teal::modules(
    teal.modules.general::tm_g_scatterplot(
      x = teal.transform::data_extract_spec(
        dataname = "IRIS",
        select = teal.transform::select_spec(choices = teal.transform::variable_choices(iris))
      ),
      y = teal.transform::data_extract_spec(
        dataname = "IRIS",
        select = teal.transform::select_spec(choices = teal.transform::variable_choices(iris))
      ),
      decorators = list(
        plot = ggplot_decorator(
          output_name = "plot", render_ui = c("title", "footnote", "font_size_axis_title")
        )
      )
    )
  )
)
if (interactive()) {
  shinyApp(app$ui, app$server)
}


Filter Teal Modules by Label

Description

[Experimental] Recursively filters a teal modules object to keep only modules whose labels match the specified labels. Removes modules that don't match and empty parent containers.

Usage

keep_by_label(x, label)

Arguments

x

(teal_module or teal_modules) the object to filter.

label

(character(1)) character vector of module labels to keep.

Value

Filtered teal_modules or teal_module object, or NULL if none matches.

Examples

# Keep only specific modules by label
mods <- teal::modules(
  teal::example_module("mod1"),
  teal::example_module("mod2")
)
filtered_mods <- keep_by_label(mods, c("Data Table", "Disposition"))


Combine levels of a variable into one level

Description

[Experimental]

Usage

merge_levels_transformator(dataname)

Arguments

dataname

(character(1)) the name of the dataset which columns will be used for possible transformation.

Details

This transformator allows the user to select a column from the dataset and combine values of this column into a single level. Only selected levels are affected.

The new combined level is called "Combined".

Merging works only for character or factor columns.

Value

teal::teal_transform_module

Examples


app <- teal::init(
  data = teal.data::teal_data(IRIS = iris, code = "IRIS <- iris"),
  modules = teal::modules(
    teal::example_module(
      transformators = list(uteals::merge_levels_transformator("IRIS"))
    )
  )
)
if (interactive()) {
  shiny::shinyApp(app$ui, app$server)
}


Apply Logical AND/OR filter transformations

Description

[Experimental] This transformator provides users with flexible, dynamic filtering capabilities for datasets.

Each instance of the transformator operates on a single dataset. Users can define multiple filter blocks, where:

This allows creating complex filter expressions like:

(Condition1 AND Condition2) OR (Condition3 AND Condition4)

To apply filtering across multiple datasets, users can instantiate multiple instances of this module, each configured for a different dataset. Each module call is independent and manages filters for its specific dataset.

Usage

or_filtering_transformator(dataname)

Arguments

dataname

(character(1)) Name of the dataset to filter. Pass a single dataset name as a string.

Value

teal::teal_transform_module

Examples


app <- teal::init(
  data = teal.data::teal_data(IRIS = iris),
  modules = teal::modules(teal::example_module(
    transformators = list(or_filtering_transformator("IRIS"))
  ))
)
if (interactive()) {
  shinyApp(app$ui, app$server)
}

Patchwork Decorator

Description

[Experimental] Decorator function to add plot title and footnote to patchwork plots

Usage

patchwork_plot_decorator(output_name, label_text = "decorator")

Arguments

output_name

(character(1)) A name for the output plot object.

label_text

(character(1)) A customized label text for the decorator.

Details

The module creates a UI with text controls for plot title and footnote. The entered title and footnote text are applied to the patchwork plots.

Value

(teal.data::qenv) Returns a modified plot object with the transformation applied.


Remove Teal Modules by Label

Description

[Experimental] Recursively removes modules from a teal modules structure that match the specified labels.

Usage

remove_by_label(x, label)

Arguments

x

(teal_module or teal_modules) The object to filter.

label

(character(1)) character vector of module labels to remove.

Value

The filtered teal modules object with matching modules removed, or NULL if all modules are removed.

Examples

mods <- teal::modules(
  teal::example_module("mod1"),
  teal::example_module("mod2")
)
# Remove a single module
filtered_mods <- remove_by_label(mods, "Deaths")

# Remove multiple modules
filtered_mods <- remove_by_label(mods, c("Deaths", "Lab Summary Table"))


Description

[Experimental] A function to create a UI component for selecting a title and footer for tables or plots. It reads title information from a specified Excel file and allows users to choose a title from the provided options. It also provides user with flexibility to customize the title and footer according to their specific needs.

Usage

title_footer_decorator(
  output_name,
  titles_file,
  choices = NULL,
  selected = NULL
)

Arguments

output_name

(character(1)) a name for the output object (e.g., a plot or table).

titles_file

(character(1)) the path to an Excel file containing title and footer information. The function expects the titles to be in the first sheet named Sheet1.

choices

(character) an array of titles and footers, which are available for selection. Default NULL, indicates all titles and footers are available.

selected

(character(1)) the selected title or footer. Default NULL, indicates no title or footer is selected.

Details

The module creates a UI with a dropdown for selecting a title. Once a title is selected, it updates the output by either adding titles to a table or modifying a plot's title and caption accordingly. Additionally, it includes a checkbox that user can check to enable customization, allowing them to enter their own values for the title and footer in the designated input fields.

Value

teal::teal_transform_module()

See Also

For the exact Excel workbook layout expected by this function, see the package vignette: vignette("title-footer-decorator-excel-structure", package = "uteals")

Examples

library(openxlsx)
library(teal.modules.general)

example_excel <- data.frame(
  `TABLE ID` = c(
    "DO_NOT_DELETE",
    "TSFAE01A", "TSFAE01A", "TSFAE01A",
    "TSFAE01B", "TSFAE01B"
  ),
  IDENTIFIER = c(
    "DO_NOT_DELETE",
    "TITLE", "FOOTNOTE1", "FOOTNOTE2",
    "TITLE", "FOOTNOTE1"
  ),
  TEXT = c(
    "DO_NOT_DELETE",
    "Adverse Events Summary A", "Source: Clinical Study Report", "Confidential",
    "Adverse Events Summary B", "Draft Version"
  ),
  stringsAsFactors = FALSE,
  check.names = FALSE
)

temp_titles <- tempfile(fileext = ".xlsx")
write.xlsx(example_excel, temp_titles, sheetName = "Sheet1", asTable = TRUE)
plot_module <- tm_g_scatterplot(
  label = "Scatter Plot",
  x = data_extract_spec(
    dataname = "IRIS",
    select = select_spec(
      choices = variable_choices(
        "IRIS", c("Sepal.Length", "Sepal.Width")
      ), selected = "Sepal.Length"
    )
  ),
  y = data_extract_spec(
    dataname = "IRIS",
    select = select_spec(
      choices = variable_choices(
        "IRIS", c("Petal.Length", "Petal.Width")
      ), selected = "Petal.Length"
    )
  ),
  decorators = list(
    plot = title_footer_decorator(
      "plot", temp_titles,
      choices = c("TSFAE01A", "TSFAE01B"), selected = NULL
    )
  )
)

# Initialize the teal app
app <- init(
  data = teal_data(IRIS = iris),
  modules = list(plot_module)
)

# Run the app
if (interactive()) {
  shinyApp(app$ui, app$server)
}

mirror server hosted at Truenetwork, Russian Federation.