diff --git a/.Rbuildignore b/.Rbuildignore index e3f52930cd..ce47f17cd6 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -1,3 +1,4 @@ +LICENSE ^renv$ ^renv\.lock$ CODE_OF_CONDUCT.md diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index a340b7b543..7ea29efc00 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -130,7 +130,7 @@ The package maintainer also reserves the right to adjust the criteria to recogni If you have further questions regarding the contribution guidelines, please contact the package/repository maintainer. -[docs]: https://insightsengineering.github.io/teal/index.html -[articles]: https://insightsengineering.github.io/teal/main/articles/index.html -[license]: https://insightsengineering.github.io/teal/main/LICENSE-text.html +[docs]: https://insightsengineering.github.io/teal/latest-tag/index.html +[articles]: https://insightsengineering.github.io/teal/latest-tag/articles/index.html +[license]: https://insightsengineering.github.io/teal/latest-tag/LICENSE-text.html [insights]: https://github.com/insightsengineering/teal/pulse diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index 63616961e1..4f45bd5170 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -33,7 +33,7 @@ body: id: code-of-conduct attributes: label: Code of Conduct - description: By submitting this issue, you agree to follow our [Code of Conduct.](https://insightsengineering.github.io/teal/CODE_OF_CONDUCT.html) + description: By submitting this issue, you agree to follow our [Code of Conduct.](https://insightsengineering.github.io/teal/latest-tag/CODE_OF_CONDUCT.html) options: - label: I agree to follow this project's Code of Conduct. required: true @@ -41,7 +41,7 @@ body: id: contributor-guidelines attributes: label: Contribution Guidelines - description: By submitting this issue, you agree to follow our [Contribution Guidelines.](https://insightsengineering.github.io/teal/CONTRIBUTING.html) + description: By submitting this issue, you agree to follow our [Contribution Guidelines.](https://insightsengineering.github.io/teal/latest-tag/CONTRIBUTING.html) options: - label: I agree to follow this project's Contribution Guidelines. required: true diff --git a/.github/ISSUE_TEMPLATE/feature.yml b/.github/ISSUE_TEMPLATE/feature.yml index 0ea9f295b5..a794c6247a 100644 --- a/.github/ISSUE_TEMPLATE/feature.yml +++ b/.github/ISSUE_TEMPLATE/feature.yml @@ -13,7 +13,7 @@ body: id: code-of-conduct attributes: label: Code of Conduct - description: By submitting this issue, you agree to follow our [Code of Conduct.](https://insightsengineering.github.io/teal/CODE_OF_CONDUCT.html) + description: By submitting this issue, you agree to follow our [Code of Conduct.](https://insightsengineering.github.io/teal/latest-tag/CODE_OF_CONDUCT.html) options: - label: I agree to follow this project's Code of Conduct. required: true @@ -21,7 +21,7 @@ body: id: contributor-guidelines attributes: label: Contribution Guidelines - description: By submitting this issue, you agree to follow our [Contribution Guidelines.](https://insightsengineering.github.io/teal/CONTRIBUTING.html) + description: By submitting this issue, you agree to follow our [Contribution Guidelines.](https://insightsengineering.github.io/teal/latest-tag/CONTRIBUTING.html) options: - label: I agree to follow this project's Contribution Guidelines. required: true diff --git a/.github/ISSUE_TEMPLATE/question.yml b/.github/ISSUE_TEMPLATE/question.yml index 947a756563..a88675284c 100644 --- a/.github/ISSUE_TEMPLATE/question.yml +++ b/.github/ISSUE_TEMPLATE/question.yml @@ -13,7 +13,7 @@ body: id: code-of-conduct attributes: label: Code of Conduct - description: By submitting this issue, you agree to follow our [Code of Conduct.](https://insightsengineering.github.io/teal/CODE_OF_CONDUCT.html) + description: By submitting this issue, you agree to follow our [Code of Conduct.](https://insightsengineering.github.io/teal/latest-tag/CODE_OF_CONDUCT.html) options: - label: I agree to follow this project's Code of Conduct. required: true @@ -21,7 +21,7 @@ body: id: contributor-guidelines attributes: label: Contribution Guidelines - description: By submitting this issue, you agree to follow our [Contribution Guidelines.](https://insightsengineering.github.io/teal/CONTRIBUTING.html) + description: By submitting this issue, you agree to follow our [Contribution Guidelines.](https://insightsengineering.github.io/teal/latest-tag/CONTRIBUTING.html) options: - label: I agree to follow this project's Contribution Guidelines. required: true diff --git a/DESCRIPTION b/DESCRIPTION index c747092a9a..b17332b971 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Type: Package Package: teal Title: Exploratory Web Apps for Analyzing Clinical Trials Data -Version: 0.14.0.9004 -Date: 2023-08-24 +Version: 0.14.0.9007 +Date: 2023-09-13 Authors@R: c( person("Dawid", "Kaledkowski", , "dawid.kaledkowski@roche.com", role = c("aut", "cre")), person("Pawel", "Rucki", , "pawel.rucki@roche.com", role = "aut"), @@ -20,11 +20,14 @@ Authors@R: c( person("F. Hoffmann-La Roche AG", role = c("cph", "fnd")), person("Maximilian", "Mordig", role = "ctb") ) -Description: A shiny based interactive exploration framework for analyzing - clinical trials data. teal currently provides a dynamic filtering - facility and different data viewers. teal shiny applications are built - using standard shiny modules. -License: Apache License 2.0 | file LICENSE +Description: A 'shiny' based interactive exploration framework for + analyzing clinical trials data. 'teal' currently provides a dynamic + filtering facility and different data viewers. 'teal' 'shiny' + applications are built using standard 'shiny' modules. +License: Apache License 2.0 +URL: https://insightsengineering.github.io/teal/, + https://github.com/insightsengineering/teal/ +BugReports: https://github.com/insightsengineering/teal/issues Depends: R (>= 4.0), shiny (>= 1.7.0), diff --git a/NAMESPACE b/NAMESPACE index abcab1ba5a..4711ead7a4 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,5 +1,6 @@ # Generated by roxygen2: do not edit by hand +S3method(c,teal_slices) S3method(get_code,tdata) S3method(get_join_keys,default) S3method(get_join_keys,tdata) diff --git a/NEWS.md b/NEWS.md index e1e7ee24c7..3e259a17d3 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,4 +1,4 @@ -# teal 0.14.0.9004 +# teal 0.14.0.9007 ### Miscellaneous diff --git a/R/teal_slices.R b/R/teal_slices.R index 66e6669faa..2562b0976f 100644 --- a/R/teal_slices.R +++ b/R/teal_slices.R @@ -110,6 +110,28 @@ as.teal_slices <- function(x) { # nolint } +#' @rdname teal_slices +#' @export +#' @keywords internal +#' +c.teal_slices <- function(...) { + x <- list(...) + checkmate::assert_true(all(vapply(x, is.teal_slices, logical(1L))), .var.name = "all arguments are teal_slices") + + all_attributes <- lapply(x, attributes) + all_attributes <- coalesce_r(all_attributes) + all_attributes <- all_attributes[names(all_attributes) != "class"] + + do.call( + teal_slices, + c( + unique(unlist(x, recursive = FALSE)), + all_attributes + ) + ) +} + + #' Deep copy `teal_slices` #' #' it's important to create a new copy of `teal_slices` when diff --git a/R/zzz.R b/R/zzz.R index 3cee41004a..fbc9c756d9 100644 --- a/R/zzz.R +++ b/R/zzz.R @@ -25,8 +25,10 @@ # Use non-exported function(s) from teal.slice. # This is a temporary measure and will be removed two release cycles from now (now meaning 0.13.0). -list_to_teal_slices <- getFromNamespace("list_to_teal_slices", "teal.slice") # nolint +list_to_teal_slices <- getFromNamespace("list_to_teal_slices", "teal.slice") # This one is here because setdiff_teal_slice should not be exported from teal.slice. setdiff_teal_slices <- getFromNamespace("setdiff_teal_slices", "teal.slice") +# This one is here because it is needed by c.teal_slices but we don't want it exported from teal.slice. +coalesce_r <- getFromNamespace("coalesce_r", "teal.slice") # all *Block objects are private in teal.reporter RcodeBlock <- getFromNamespace("RcodeBlock", "teal.reporter") # nolint diff --git a/README.md b/README.md index a1bc7768b2..9c43676eaa 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ - Related datasets, for example a set of `data.frames` with key columns to enable data joins - `MultiAssayExperiment` objects which are R data structures for representing and analyzing multi-omics experiments - `teal` modules: - - `teal modules` are shiny modules built within the `teal` framework that specify analysis to be performed. For example, it can be a module for exploring outliers in the data, or a module for visualizing the data in line plots. Although these can be created from scratch, lost of `teal` modules have been released and we recommend starting with modules found in the following packages: + - `teal modules` are shiny modules built within the `teal` framework that specify analysis to be performed. For example, it can be a module for exploring outliers in the data, or a module for visualizing the data in line plots. Although these can be created from scratch, many `teal` modules have been released and we recommend starting with modules found in the following packages: - [`teal.modules.general`](https://insightsengineering.github.io/teal.modules.general/): general modules for exploring relational/independent/`CDISC` data - [`teal.modules.clinical`](https://insightsengineering.github.io/teal.modules.clinical/): modules specific to `CDISC` data and clinical trial reporting - [`teal.modules.hermes`](https://insightsengineering.github.io/teal.modules.hermes/): modules for analyzing `MultiAssayExperiment` objects @@ -103,9 +103,9 @@ shinyApp(app$ui, app$server) ![App recording](man/figures/readme_app.gif) -Please see [`teal` gallery](https://insightsengineering.github.io/teal.gallery) and [TLG Catalog](https://insightsengineering.github.io/tlg-catalog) to see examples of `teal` apps. +Please see [`teal.gallery`](https://insightsengineering.github.io/teal.gallery) and [TLG Catalog](https://insightsengineering.github.io/tlg-catalog) to see examples of `teal` apps. -Please start with the ["Getting Started" article](https://insightsengineering.github.io/teal/articles/teal.html) and then other [package vignettes](https://insightsengineering.github.io/teal/articles/index.html) for more detailed guide. +Please start with the ["Getting Started" article](https://insightsengineering.github.io/teal/latest-tag/articles/teal.html) and then other [package vignettes](https://insightsengineering.github.io/teal/articles/index.html) for more detailed guide. ## Getting help diff --git a/_pkgdown.yml b/_pkgdown.yml index 5e9ef259ee..f7afd6b568 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -21,23 +21,32 @@ navbar: href: https://github.com/insightsengineering/teal articles: - - title: Articles + - title: Get Started navbar: ~ contents: - teal + - title: Articles + navbar: Using teal + contents: - filter-panel - - including-general-data-in-teal + - teal-options + - teal-bs-themes + - title: Articles + navbar: Data in teal Apps + contents: - including-adam-data-in-teal + - including-general-data-in-teal - including-mae-data-in-teal - preprocessing-data + - title: Articles + navbar: Extending teal + contents: - creating-custom-modules - adding-support-for-reporting - - teal-options - - teal-bs-themes reference: - - title: teal Core Functions - desc: These are the main functions needed to build a teal app. + - title: Core `teal` Functions + desc: Main functions needed to build a `teal` app contents: - init - module @@ -45,15 +54,15 @@ reference: - srv_teal_with_splash - ui_teal_with_splash - teal_slices - - title: Example module - desc: A simple example teal module + - title: Example Module + desc: A simple `teal` module contents: - example_module - - title: Creating reports + - title: Creating Reports contents: - reporter_previewer_module - TealReportCard - - title: Functions for module developers + - title: Functions for Module Developers contents: - tdata - get_code_tdata @@ -61,9 +70,9 @@ reference: - get_metadata - tdata2env - show_rcode_modal - # - title: Functions moved to other packages - # desc: These functions have been moved from teal and will be deprecated. + # - title: Functions Moved to Other Packages + # desc: These functions have been moved from teal and will be deprecated # contents: - - title: Validation functions + - title: Validation Functions contents: - starts_with("validate_") diff --git a/inst/WORDLIST b/inst/WORDLIST index fc9934a03d..02f29a34d2 100644 --- a/inst/WORDLIST +++ b/inst/WORDLIST @@ -1,6 +1,9 @@ +ADaM Forkers Hoffmann +MultiAssayExperiment TLG +Theming UI UIs UX @@ -8,11 +11,10 @@ cloneable funder omics pharmaverse -preselected +preprocessed programmatically repo reproducibility tabsetted themer -theming uncheck diff --git a/man/teal-package.Rd b/man/teal-package.Rd index b9371475a7..ad4f6bd6b8 100644 --- a/man/teal-package.Rd +++ b/man/teal-package.Rd @@ -12,6 +12,15 @@ interactive data analysis environment. \details{ To learn mode about the package either read the project website at \url{Project Website} or read the \code{\link{init}} manual pages. +} +\seealso{ +Useful links: +\itemize{ + \item \url{https://insightsengineering.github.io/teal/} + \item \url{https://github.com/insightsengineering/teal/} + \item Report bugs at \url{https://github.com/insightsengineering/teal/issues} +} + } \author{ \strong{Maintainer}: Dawid Kaledkowski \email{dawid.kaledkowski@roche.com} diff --git a/man/teal_slices.Rd b/man/teal_slices.Rd index c0416af41f..6d5117b058 100644 --- a/man/teal_slices.Rd +++ b/man/teal_slices.Rd @@ -3,6 +3,7 @@ \name{teal_slices} \alias{teal_slices} \alias{as.teal_slices} +\alias{c.teal_slices} \title{Filter settings for teal applications} \usage{ teal_slices( @@ -16,6 +17,8 @@ teal_slices( ) as.teal_slices(x) + +\method{c}{teal_slices}(...) } \arguments{ \item{...}{any number of \code{teal_slice} objects. For \code{print} and \code{format}, diff --git a/vignettes/adding-support-for-reporting.Rmd b/vignettes/adding-support-for-reporting.Rmd index f8b11369b4..70a9c69579 100644 --- a/vignettes/adding-support-for-reporting.Rmd +++ b/vignettes/adding-support-for-reporting.Rmd @@ -1,12 +1,11 @@ --- -title: "Adding support for Reporting to custom modules" +title: "Adding Support for Reporting to Custom Modules" author: "NEST CoreDev" -date: "2022-05-23" output: rmarkdown::html_vignette: toc: true vignette: > - %\VignetteIndexEntry{Adding support for Reporting to custom modules} + %\VignetteIndexEntry{Adding Support for Reporting to Custom Modules} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- @@ -15,7 +14,7 @@ vignette: > The `teal` package offers an integrated reporting feature utilizing the `teal.reporter` package. For a comprehensive explanation of the reporting functionality itself, please refer to the documentation therein. -This article is intended for module developers and aims to provide guidance on enriching a custom `teal` module with an automatic reporting feature. This enhancement enables users to incorporate snapshots of the module outputs into a report which can then be reviewed in another module automatically provided by `teal`. Thus the app user can interact with the report. +This article is intended for module developers and aims to provide guidance on enhancing a custom `teal` module with an automatic reporting feature. This enhancement enables users to incorporate snapshots of the module outputs into a report which can then be reviewed in another module automatically provided by `teal`. Thus the app user can interact with the report. The responsibilities of a module developer include: diff --git a/vignettes/creating-custom-modules.Rmd b/vignettes/creating-custom-modules.Rmd index 6d5e9fea93..5a51551080 100644 --- a/vignettes/creating-custom-modules.Rmd +++ b/vignettes/creating-custom-modules.Rmd @@ -1,7 +1,6 @@ --- title: "Creating Custom Modules" author: "Nikolas Burkoff" -date: "2022-03-24" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Creating Custom Modules} @@ -11,8 +10,7 @@ vignette: > ## Introduction -The `teal` framework provides a large number of analysis modules to be incorporated into `teal` applications. -However, it is also possible to create your own modules using the `module()` function. +The `teal` framework provides a large number of analysis modules to be incorporated into `teal` applications. However, it is also possible to create your own modules using the `module` function. Here is an implementation of a simple module: @@ -46,11 +44,9 @@ which can be added into `teal` apps using `example_module(label = "Label for tab ### UI function -This function contains the UI required for the module. It should be a function with at least the arguments `id`. -It can also contain the argument `data` for access to the application data. See the server section below for more details. +This function contains the UI required for the module. It should be a function with at least the arguments `id`. It can also contain the argument `data` for access to the application data. See the server section below for more details. -The UI function can contain standard UI components alongside additional widgets provided by the `teal.widgets` package. -In the example above we are using the `standard_layout` function of `teal.widgets` which generates a layout +The UI function can contain standard UI components alongside additional widgets provided by the `teal.widgets` package. In the example above we are using the `standard_layout` function of `teal.widgets` which generates a layout including an encoding panel on the left and main output covering the rest of the module's UI. ### Server function @@ -70,18 +66,14 @@ function(id, ``` -When used inside a teal application called with `teal::init`, the `data` argument is a named list of reactive data.frames -containing the data after having been filtered through the filter panel. It is of the `tdata` type and can be created using -the `new_tdata` function. +When used inside a `teal` application called with `init`, the `data` argument is a named list of reactive `data.frame`s containing the data after having been filtered through the filter panel. It is of the `tdata` type and can be created using the `new_tdata` function. ## A More Complicated Example The `teal` framework also provides: -- A way to create modules which then generate the R code needed to reproduce their outputs; -these modules use the [`teal.code`](https://insightsengineering.github.io/teal.code/) package. -- A way extract from and merge related datasets using the -[`teal.transform`](https://insightsengineering.github.io/teal.transform/) package. +- A way to create modules which then generate the R code needed to reproduce their outputs; these modules use the [`teal.code`](https://insightsengineering.github.io/teal.code/) package. +- A way extract from and merge related datasets using the [`teal.transform`](https://insightsengineering.github.io/teal.transform/) package. - A way to allow app creators to customize your modules also using `teal.transform`. The annotated example below demonstrates these features within a simple histogram module, allowing app developers to choose the data and columns that their app users can select for display in a histogram. @@ -207,9 +199,7 @@ if (interactive()) { ## `shiny` input cycle -When teal modules are run inside the `teal::init` the initial shiny input cycle is empty for each of them. -In practice, this means that some inputs might be initialized with `NULL` value, unnecessary triggering some -observers. A developer has to be aware of this situation as often It will require `shiny::req` or `ignoreInit` argument in observers or `reactive` expressions. This side effect is caused by the `shiny::insertUI` function. We are aware of this inconvenience and have already started to look for a solution. +When `teal` modules are run inside the `init` the initial shiny input cycle is empty for each of them. In practice, this means that some inputs might be initialized with `NULL` value, unnecessary triggering some observers. A developer has to be aware of this situation as often it will require `shiny::req` or `ignoreInit` argument in observers or `reactive` expressions. This side effect is caused by the `shiny::insertUI` function. We are aware of this inconvenience and have already started to look for a solution. ## Adding reporting to a module Refer to `vignette("adding_support_for_reporting")` to read about adding support for reporting in your `teal` module. diff --git a/vignettes/filter-panel.Rmd b/vignettes/filter-panel.Rmd index 6c20beba5f..544e67546e 100644 --- a/vignettes/filter-panel.Rmd +++ b/vignettes/filter-panel.Rmd @@ -1,7 +1,6 @@ --- title: "Filter Panel" author: "NEST CoreDev" -date: "2023-07-12" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Filter Panel} @@ -9,14 +8,11 @@ vignette: > %\VignetteEncoding{UTF-8} --- -## `teal` apps with the filter panel +## `teal` Apps With the Filter Panel -The filter panel is an integral part of all `teal` applications and is included on the right side. Based on the selections made in the filter panel, filter expressions are executed before passing data to `teal` modules. -The technical details of the filter panel are extensively described in [`teal.slice` documentation](https://insightsengineering.github.io/teal.slice/latest-tag/). +The filter panel is an integral part of all `teal` applications and is included on the right side. Based on the selections made in the filter panel, filter expressions are executed before passing data to `teal` modules. The technical details of the filter panel are extensively described in [`teal.slice` documentation](https://insightsengineering.github.io/teal.slice/latest-tag/). -By default, `teal::init` initializes the filter panel without any active filters but allows the user to add filters on any column. -To start a `teal` application with predefined filters, one must to specify the `filter` argument. -In the following example four filters are specified using the `teal_slice` function and wrapped together with `teal_slices`. +By default, `init` initializes the filter panel without any active filters but allows the user to add filters on any column. To start a `teal` application with predefined filters, one must to specify the `filter` argument. In the following example four filters are specified using the `teal_slice` function and wrapped together with `teal_slices`. ```r library(teal) @@ -44,8 +40,7 @@ if (interactive()) { ### Filter panel respective to `teal_module` -Each `teal_module` (see `?module`) object contains the `filters` attribute that determines which data sets are to be sent to that module. -The filter panel will display only those data sets and hide the rest when this module is active. +Each `teal_module` (see `?module`) object contains the `datanames` attribute that determines which data sets are to be sent to that module. The filter panel will display only those data sets and hide the rest when this module is active. ```r library(teal) @@ -69,10 +64,7 @@ if (interactive()) { ### Global and module specific filter panel -`teal` contains the `teal_slices` function that extends the original `teal_slices` found in `teal.slice` by adding two arguments: `module_specific` and `mapping`. -By default `teal::init` initializes app with a "global" filter panel, where all modules use the same filters. -Setting `module_specific = TRUE` switches to a "module-specific" filter panel, where each module can have a different set of filters active. -It is still possible to set global filters that will be shared among modules. +`teal` contains the `teal_slices` function that extends the original `teal_slices` found in `teal.slice` by adding two arguments: `module_specific` and `mapping`. By default `init` initializes app with a "global" filter panel, where all modules use the same filters. Setting `module_specific = TRUE` switches to a "module-specific" filter panel, where each module can have a different set of filters active at any time. It is still possible to set global filters that will be shared among modules. One possible scenario is depicted in the figure below: @@ -84,9 +76,7 @@ One possible scenario is depicted in the figure below: ![](./images/filters_mapping.jpg) -To achieve the described setup, one must use the `mapping` argument to appropriately match each `teal_module` with its respective `teal_slice`. `mapping` takes a named list where each element is named with a module's `label` and contains a vector of `teal_slice` `id`s. -These elements will active in that module at startup. -In addition, `teal_slice`s whose `id`s are enumerated in the `global_filters` element of `mapping` will be applied to all modules in the app. +To achieve the described setup, one must use the `mapping` argument to appropriately match each `teal_module` with its respective `teal_slice`. `mapping` takes a named list where each element is named with a module's `label` and contains a vector of `teal_slice` `id`s. These elements will active in that module at startup. In addition, `teal_slice`s whose `id`s are enumerated in the `global_filters` element of `mapping` will be applied to all modules in the app. ```r library(teal) diff --git a/vignettes/including-adam-data-in-teal.Rmd b/vignettes/including-adam-data-in-teal.Rmd index 40a9c86927..0197e923c9 100644 --- a/vignettes/including-adam-data-in-teal.Rmd +++ b/vignettes/including-adam-data-in-teal.Rmd @@ -1,33 +1,26 @@ --- -title: "Input `ADaM` data in a teal application" +title: "Using ADaM Data in teal Applications" author: "NEST CoreDev" -date: "2022-04-20" output: rmarkdown::html_vignette vignette: > - %\VignetteIndexEntry{Input `ADaM` data in a teal application} + %\VignetteIndexEntry{Using ADaM Data in teal Applications} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ## Introduction -To include `ADaM` data in a teal app, the `teal.data::cdisc_data` function is used. +To include `ADaM` data in a `teal` app, the `teal.data::cdisc_data` function is used. -The `cdisc_data` function allows `teal` applications to include multiple datasets, identifying merge keys -and providing information to produce R code for reproducibility. +`cdisc_data` allows `teal` applications to include multiple datasets, identifying merge keys and providing information to produce R code for reproducibility. -There is an advantage to passing `CDISC` datasets that adhere to `ADaM` standards to these functions in that the code is -minimized. However, the dataset-related functions also include the flexibility to work with non-standard datasets -provided that merge keys and the relationship between the datasets are specified. +There is an advantage to passing `CDISC` datasets that adhere to `ADaM` standards to these functions in that the code is minimized. However, the dataset-related functions also include the flexibility to work with non-standard datasets provided that merge keys and the relationship between the datasets are specified. -The examples below illustrate the usage of these different dataset functions for example `cdisc_dataset` and `dataset`. For more information, -see documentation in `teal.data`. +The examples below illustrate the usage of these different dataset functions for example `cdisc_dataset` and `dataset`. For more information, see documentation in `teal.data`. ## Keys -Primary keys serve as unique row identifiers in individual datasets and thus need to be specified for each dataset -and dataset connector. These can be specified on the most general dataset constructor `dataset` as -shown below. +Primary keys serve as unique row identifiers in individual datasets and thus need to be specified for each dataset and dataset connector. These can be specified on the most general dataset constructor, `dataset`, as shown below. ```{r, message=FALSE} library(teal) @@ -44,14 +37,9 @@ dataset_adsl <- cdisc_dataset("ADSL", adsl) class(dataset_adsl) ``` -When passing multiple datasets to the `cdisc_data` function, dataset relationship are set using -`join_keys` and `join_key` and these are used to merge datasets together within teal apps. +When passing multiple datasets to the `cdisc_data` function, dataset relationship are set using `join_keys` and `join_key` and these are used to merge datasets together within `teal` apps. -In the example below, two standard `CDISC` datasets (`ADSL` and `ADTTE`) are passed to the aforementioned -function. In the case of `CDISC` datasets that adhere to `ADaM` standards, the merge keys do not need to be manually -specified. Keys are automatically added if `dataname` matches one of the implemented standards as documented in the -`cdisc_dataset` function. This minimizes the code needed to allow data merges as seen in this -example: +In the example below, two standard `CDISC` datasets (`ADSL` and `ADTTE`) are passed to `cdisc_data`. In the case of `CDISC` datasets that adhere to `ADaM` standards, the merge keys do not need to be manually specified. Keys are automatically added if `dataname` matches one of the implemented standards as documented in the `cdisc_dataset` function. This minimizes the code needed to allow data merges as seen in this example: ```{r, message=FALSE} adsl <- data.frame( @@ -94,8 +82,10 @@ cdisc_data_obj <- cdisc_data( ) ) class(cdisc_data_obj) +``` -# which is equivalent to: +which is equivalent to: +```{r, message=FALSE} example_data <- cdisc_data( cdisc_dataset( dataname = "ADSL", @@ -128,25 +118,19 @@ example_data <- cdisc_data( join_key("ADSL", "ADTTE", c("STUDYID", "USUBJID")) ) ) - -app <- init( - data = example_data, - modules = example_module() -) - -if (interactive()) { - shinyApp(app$ui, app$server) -} +class(cdisc_data_obj) ``` -The [teal.data::join_keys()] function is used to specify keys: +The `teal.data::join_keys` function is used to specify keys: -- [teal.data::join_keys()] is a collection of multiple [teal.data::join_key()] entries -- [teal.data::join_key()] specifies the relation between two datasets: +- [`teal.data::join_keys`](https://insightsengineering.github.io/teal.data/latest-tag/reference/join_keys.html) is a collection of multiple `teal.data::join_key` entries +- [`teal.data::join_key`](https://insightsengineering.github.io/teal.data/latest-tag/reference/join_key.html) specifies the relation between two datasets: - `dataset_1`, `dataset_2` - name of two datasets - - `key` - (optionally) named vector of column names + - `key` - optionally named vector of column names + +Note that it is assumed that join keys are symmetric, i.e. `join_key("x", "y", "x_col" = "y_col")` will enable merge from "x" to "y" and vice-versa. + -Note that it is assumed that join keys are symmetric, i.e. `join_key("x", "y", "x_col" = "y_col")` will enable merge -from "x" to "y" and vice-versa. +## Further Reading For more information about preprocessing, reproducibility, relationships between datasets and `DDL`, please refer to the [`teal.data` package](https://insightsengineering.github.io/teal.data/). diff --git a/vignettes/including-general-data-in-teal.Rmd b/vignettes/including-general-data-in-teal.Rmd index 1d0e2c5e0b..30251d6aaa 100644 --- a/vignettes/including-general-data-in-teal.Rmd +++ b/vignettes/including-general-data-in-teal.Rmd @@ -1,19 +1,18 @@ --- -title: "Input general data in a teal application" +title: "Using General Data in teal Applications" author: "NEST CoreDev" -date: "2022-04-20" output: rmarkdown::html_vignette vignette: > - %\VignetteIndexEntry{Input general data in a teal application} + %\VignetteIndexEntry{Using General Data in teal Applications} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ## Introduction -`teal` applications are not restricted to `CDISC`-standard data. Although many teal modules included with `NEST` are designed for `CDISC` data, those in the library `teal.modules.general` have been designed to work with non-relational data. +`teal` applications are not restricted to `CDISC`-standard data. Although many `teal` modules included with `NEST` are designed for `CDISC` data, those in the library `teal.modules.general` have been designed to work with non-relational data. -For example this application uses the standard `iris` and `mtcars` datasets: +This example application uses the standard `iris` and `mtcars` datasets: ```{r, message=FALSE} library(teal) @@ -35,46 +34,11 @@ For more information, see documentation in `teal.data`. ## Delayed Data Loading (`DDL`) -To learn more about `DDL`, visit `vignette("delayed-data-loading", package = "teal.data")`. All the features of `DDL` -are available for general datasets: +`teal` provides the ability to pull remote data and use it in the app. Additional user authentication may be necessary. -```{r eval=FALSE} -library(teal) - -person_generator <- function() { - return( - data.frame( - ID = factor(1:8), - AGE = c(40, 23, 56, 11, 17, 71, 23, 56) - ) - ) -} +To learn more about `DDL`, visit the appropriate vignette in `teal.data`. -pet_generator <- function() { - return( - data.frame( - ID = factor(1:10), - TYPE = rep(c("CAT", "DOG"), 5), - COLOR = c("GINGER", rep("BROWN", 5), rep("BLACK", 4)), - PERSON_ID = factor(c(5, 4, 3, 3, 3, 1, 8, 1, 2, 2)) - ) - ) -} - - -app <- init( - data = teal_data( - fun_dataset_connector("PERSON", fun = person_generator, keys = "ID") %>% - mutate_dataset("PERSON$SEX <- rep(c('M', 'F'), 4)"), - fun_dataset_connector("PETS", fun = pet_generator, keys = "ID") - ) %>% - mutate_join_keys("PERSON", "PETS", c("ID" = "PERSON_ID")), - modules = example_module() -) -if (interactive()) { - shinyApp(app$ui, app$server) -} -``` +## Further Reading For more information about preprocessing, reproducibility, relationships between datasets and `DDL`, please refer to the [`teal.data` package](https://insightsengineering.github.io/teal.data/). diff --git a/vignettes/including-mae-data-in-teal.Rmd b/vignettes/including-mae-data-in-teal.Rmd index 621bb8a3d7..bb4f5501ef 100644 --- a/vignettes/including-mae-data-in-teal.Rmd +++ b/vignettes/including-mae-data-in-teal.Rmd @@ -1,10 +1,9 @@ --- -title: "Input `MultiAssayExperiment` data in a teal application" +title: "Using MultiAssayExperiment data in teal Applications" author: "NEST CoreDev" -date: "2022-04-20" output: rmarkdown::html_vignette vignette: > - %\VignetteIndexEntry{Input `MultiAssayExperiment` data in a teal application} + %\VignetteIndexEntry{Using MultiAssayExperiment data in teal Applications} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- @@ -12,10 +11,10 @@ vignette: > ## `MultiAssayExperiment` data `MultiAssayExperiment` offers a data structure for representing and analyzing multi-omics experiments: a biological analysis approach utilizing multiple types of observations, such as DNA mutations and abundance of RNA and proteins, in the same biological specimens. -You can read more about `MultiAssayExperiment` data [here](https://www.bioconductor.org/packages/release/bioc/vignettes/MultiAssayExperiment/inst/doc/MultiAssayExperiment.html). +`MultiAssayExperiment` data is described in detail [here](https://www.bioconductor.org/packages/release/bioc/vignettes/MultiAssayExperiment/inst/doc/MultiAssayExperiment.html). -## Example application +## Example Application The example below represents an application including `MultiAssayExperiment` data. ```{r, eval = FALSE} @@ -34,8 +33,9 @@ if (interactive()) { } ``` -The filter panel supports `MAE` data out of the box, but `teal` itself does not guarantee that any module will work with `MAE` data the same way it works with other types of data (e.g. `ADaM`) because `MAE` has a unique structure that needs to be considered when developing a module. -The package [`teal.modules.hermes`](https://insightsengineering.github.io/teal.modules.hermes/) has been specifically developed for the -analysis of `MAE` data. +The filter panel supports `MAE` data out of the box, but `teal` itself does not guarantee that any module will work with `MAE` data the same way it works with other types of data (e.g. `ADaM`) because `MAE` has a unique structure that requires special consideration when developing a module. The package [`teal.modules.hermes`](https://insightsengineering.github.io/teal.modules.hermes/) has been specifically developed for the analysis of `MAE` data. + + +## Further Reading For more information about preprocessing, reproducibility, relationships between datasets and `DDL`, please refer to the [`teal.data` package](https://insightsengineering.github.io/teal.data/). diff --git a/vignettes/preprocessing-data.Rmd b/vignettes/preprocessing-data.Rmd index f2e6368b72..3da46d6e21 100644 --- a/vignettes/preprocessing-data.Rmd +++ b/vignettes/preprocessing-data.Rmd @@ -1,18 +1,17 @@ --- -title: "Preprocessing data" +title: "Preprocessing Data" author: "NEST CoreDev" -date: "2022-07-28" output: rmarkdown::html_vignette vignette: > - %\VignetteIndexEntry{Preprocessing data} + %\VignetteIndexEntry{Preprocessing Data} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- -## Usage in teal apps -In this vignette, we will show how to use preprocessing in a `teal` app. The basics of preprocessing data have been discussed in `teal.data` [here](https://insightsengineering.github.io/teal.data/main/articles/preprocessing-data.html). +## Usage in `teal` apps +In this vignette, we will show how to use preprocessed data in `teal` apps. The basics of data preprocessing have been discussed in `teal.data` [here](https://insightsengineering.github.io/teal.data/latest-tag/articles/preprocessing-data.html). -In a `teal` app, providing the code in a copy-paste style is cumbersome and can lead to an out-of-sync situation where the code does not represent the preprocessing code anymore. We therefore use the `get_code` function to extract the preprocessing code from the `app.R` file. The `get_code` function requires `#` tags to indicate which lines of code in `app.R` need be included in the preprocessing code. `get_code` understands the following tags: +In a `teal` app providing the code in a copy-paste style is cumbersome and can lead to an out-of-sync situation where the code does not represent the preprocessing code anymore. We therefore use the `teal.data::get_code` function to extract the preprocessing code from the `app.R` file. The `get_code` function requires `#` tags to indicate which lines of code in `app.R` need be included in the preprocessing code. `get_code` understands the following tags: - Enclosing preprocessing code between `#code>` `# - %\VignetteIndexEntry{teal and Bootstrap Themes} + %\VignetteIndexEntry{Bootstrap Themes in teal} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ## Introduction -We offer an easy application of a custom bootstrap theme to a `teal::init` app. -`teal` is a consumer of the `bslib` R package which provides tools for customizing Bootstrap themes e.g. of Shiny apps. +We offer an easy application of a custom Bootstrap theme in a `teal` app. `teal` uses the `bslib` R package which provides tools for customizing Bootstrap themes, including those of `shiny` apps. ## Usage -`teal` users have the benefit of custom bootstrap themes by specifying the `teal.bs_theme` R option, which has to be set to `bslib::bs_theme` object. -The `bslib::bs_theme(...)` function creates a Bootstrap theme object, where you should specify the (major) Bootstrap version (default or one of 3, 4 or 5). -Optionally you could choose a **`bootswatch` theme** and **customize the app CSS** with functions like `bslib::bs_add_rules`. -Please read more about custom themes in [the `bslib` getting started vignette](https://rstudio.github.io/bslib/articles/bslib.html). -The `teal.bs_theme` R option has to be specified at the top of the code script. +`teal` app developers can specify custom Bootstrap themes by setting the `teal.bs_theme` R option, which has to be set to `bslib::bs_theme` object. The `bslib::bs_theme(...)` function creates a Bootstrap theme object, where one specifies the (major) Bootstrap version (default or one of 3, 4 or 5). Optionally one can choose a **`bootswatch` theme** and **customize the app CSS** with functions like `bslib::bs_add_rules`. Please read more about custom themes in [the `bslib` getting started vignette](https://rstudio.github.io/bslib/articles/bslib.html). The `teal.bs_theme` R option has to be specified at the top of the code script. Please install `bslib` package before you run the code below. @@ -34,15 +28,11 @@ options("teal.bs_theme" = bslib::bs_theme("Custom Options")) ####################### ``` -### bootstrap version and themes +### Bootstrap Version and Themes -The best and recommended ways to **explore** the bootstrap themes are to use `bslib::run_with_themer(shinyApp(app$ui, app$server))` or `bslib::bs_theme_preview()`, -both functions offer an interactive explore mode. -Note that the interactive theming for Bootstrap 3 is not supported. -The `bslib::bs_theme_preview()` is recommended when the end user does not have any shiny app yet. -When you already have a shiny app and you want to test different bootstrap themes (and `CSS` styling) then `bslib::run_with_themer(shinyApp(app$ui, app$server))` is recommended. +The best and recommended ways to **explore** the Bootstrap themes are to use `bslib::run_with_themer(shinyApp(app$ui, app$server))` or `bslib::bs_theme_preview()`, both of which offer an interactive explore mode (not supported for Bootstrap 3). The `bslib::bs_theme_preview()` is recommended when the end user does not have any `shiny` app yet. When you already have a `shiny` app and you want to test different Bootstrap themes (and `CSS` styling) then `bslib::run_with_themer(shinyApp(app$ui, app$server))` is recommended. -Available bootstrap versions could be checked with `bslib::versions()` and bootstrap themes (`bootswatch`) with `bslib::bootswatch_themes(version = "5")`. +Available Bootstrap versions could be checked with `bslib::versions()` and Bootstrap themes (`bootswatch`) with `bslib::bootswatch_themes(version = "5")`. ``` # bslib::versions() @@ -52,12 +42,9 @@ options("teal.bs_theme" = bslib::bs_theme(version = "5", bootswatch = "lux") options("teal.bs_theme" = bslib::bs_theme_update(bslib::bs_theme(version = "5"), bootswatch = "lux")) ``` -Specifying only the bootstrap theme in many scenarios is not enough, please read the next section "Default bootstrap theme". +### Default Bootstrap theme -### Default bootstrap theme - -When using the default `bslib` theme for any version (3, 4 or 5) its styling might not be as expected. -Please run the interactive `themer` (recommended) or apply a custom theme to explore all the theme options. **In many scenarios updating only the theme might not be enough and e.g. font color and other specifications should be updated too.** +When using the default `bslib` theme for any version (3, 4 or 5), its styling might not be as expected. Please run the interactive `themer` (recommended) or apply a custom theme to explore all the theme options. **In many scenarios updating only the theme might not be enough and e.g. font color and other specifications should be updated too.** ``` # instead of @@ -67,33 +54,28 @@ options("teal.bs_theme" = bslib::bs_theme(version = "5", bootswatch = "THEME NAM # or run the app inside bslib::run_with_themer ``` -### Reset the bootstrap theme +### Reset the Bootstrap Theme -Please use the `options("teal.bs_theme" = NULL)` call to return to the default shiny bootstrap for teal apps. +Please use the `options("teal.bs_theme" = NULL)` call to return to the default `shiny` Bootstrap for `teal` apps. -### Theme not updated +### Theme Not Updated -One reason the theme is not updated could be the problem that a browser caches the previous one, especially when we run different themes one after another. -Please, use the `Cmd+Shift+R` (Mac) or `Ctrl+F5` (Windows) to hard refresh the webpage. +One reason the theme is not updated could be that the web browser caches the previous one, especially different themes are run one after another. Please, use the `Cmd+Shift+R` (Mac) or `Ctrl+F5` (Windows) to hard refresh the webpage. -### Custom teal `CSS` +### Custom `teal` `CSS` -The most important `teal` html tags have a proper id/class, so they could be directly styled. -The `bslib::bs_add_rules` function could be used around the `bslib::bs_theme` object to apply custom `CSS` rules. +The most important HTML tags in `teal` have a specific id or class, so they can be directly styled. The `bslib::bs_add_rules` function could be used around the `bslib::bs_theme` object to apply custom `CSS` rules. ``` library(magrittr) options("teal.bs_theme" = bslib::bs_theme(version = "5") %>% bslib::bs_add_rules("Anything understood by sass::as_sass()")) ``` -Other `bslib::bs_add_*` family functions could be used to specify low-level bootstrap elements. +Other `bslib::bs_add_*` family functions could be used to specify low-level Bootstrap elements. -### Bootstrap NULL vs 3 +### Bootstrap NULL vs Bootstrap 3 -It is important to note the difference between `options("teal.bs_theme" = NULL)` and `options("teal.bs_theme" = bslib::bs_theme(version = "3")`. -The small differences could comes from the `bslib` approximation of the default shiny bootstrap for version 3. -An important difference is that when using `bslib::bs_theme(version = "3", bootswatch = "THEME NAME")` we could apply the custom bootstrap theme. -Another difference is that the usage of `bslib::bs_theme(version = "3")` requires the installation of the newest `shinyWidgets` package from the main branch, see below. +It is important to note that the statements `options("teal.bs_theme" = NULL)` and `options("teal.bs_theme" = bslib::bs_theme(version = "3")` are not equivalent as the `bslib` approximation of the default `shiny` theme for Bootstrap version 3 can introduce some discrepancies. One important difference is that when using `bslib::bs_theme(version = "3", bootswatch = "THEME NAME")` one can apply the custom Bootstrap theme. Another one is that the usage of `bslib::bs_theme(version = "3")` requires the installation of the latest `shinyWidgets` package from the main branch, see below. ``` # Downloading the newest shinyWidgets @@ -103,15 +85,11 @@ remotes::install_github("https://github.com/dreamRs/shinyWidgets@main") ### Regular `shiny::fluidPage` -If you want to update the theme in the regular `shiny::fluidPage` like app, you do not need the `teal.bs_theme` option. Then simply provide the `bslib::bs_theme` directly to the `shiny::fluidPage(theme = bslib::bs_theme(...), ...)`. +If you want to update the theme in a regular `shiny::fluidPage`-like app, you do not need the `teal.bs_theme` option. Simply provide the `bslib::bs_theme` directly: `shiny::fluidPage(theme = bslib::bs_theme(...), ...)`. -### Interactive theming guide +### Interactive Theming Guide -In this section we provide a step-by-step guide to customizing a `teal` application theme interactively with `bslib::run_with_themer()`. -We recommend starting with a simple case and when you are satisfied, verify with your full application. -To that end we will use the following `teal` application. -For this example we assume that we want to use Bootstrap 5. -To start, we launch the app with `bslib::run_with_themer(app$ui, app$server)` instead of `shiny::runApp`. +In this section we provide a step-by-step guide to customizing a `teal` application theme interactively with `bslib::run_with_themer()`. We recommend starting with a simple case and once you are satisfied, verifying with your full application. To that end we will use the `teal` application below. For this example we assume that we want to use Bootstrap 5. To start, we launch the app with `bslib::run_with_themer(app$ui, app$server)` instead of `shiny::runApp`. ```{r, eval = FALSE} options("teal.bs_theme" = bslib::bs_theme(version = "5")) @@ -136,59 +114,45 @@ This gives us the following. knitr::include_graphics("images/bs-launch.png") ``` -Note the `Theme Customizer` section on the right hand side. -This was added by `bslib` and is how we customize our theme. +Note the `Theme Customizer` section on the right hand side. This was added by `bslib` and is how we customize our theme. #### Set overall app theme -Instead of starting from scratch, we want to start with a [`Bootswatch`](https://bootswatch.com/) theme. -We like the Minty theme so we select this in the "Overall theme" drop-down. +Instead of starting from scratch, we want to start with a [`Bootswatch`](https://bootswatch.com/) theme. Let us select the Minty theme in the "Overall theme" drop-down. ```{r echo = FALSE} knitr::include_graphics("images/bs-theme-set.png") ``` -`bslib` has updated our `CSS` styles to use our new theme, including the `customizer` theme. -Additionally if we look at our R console, we will see +`bslib` has updated our `CSS` styles to use our new theme, including the `customizer` theme. Additionally if we look at our R console, we will see ```{r eval = FALSE} #### Update your bs_theme() R code with: ##### bs_theme_update(theme, bootswatch = "minty") ``` -This is a helpful guide that provides code to update our theme. -For `teal` applications we don't actually use `bs_theme_update` and opt for `bs_theme` instead. -However, the printed code will still be helpful. +This is a helpful guide that provides code to update our theme. For `teal` applications we don't actually use `bs_theme_update` and opt for `bs_theme` instead. However, the printed code will still be helpful. -#### Customizing `bootswatch` theme +#### Customize a `bootswatch` theme -Our base theme of Minty is close to what we want but let's make a few modifications. -To start, we will increase the base font size. -To do this, we choose the "Fonts" section of the `customizer` theme and then set a value in the "Base font size" input. -We use 1.25 here which means all our fonts with be 1.25 times the default font size. -If we check the R console, we will see `bslib` has printed `bs_theme_update(theme, font_scale = 1.25, bootswatch = "minty")`, which now includes our font adjustment. +Our base theme (Minty) is close to what we want but let's make a few modifications. To start, we will increase the base font size. To do this, we choose the "Fonts" section of the `customizer` theme and then set a value in the "Base font size" input. We use 1.25 here, which means all our fonts will be increased by a factor of 1.25. If we check the R console, we will see `bslib` has printed `bs_theme_update(theme, font_scale = 1.25, bootswatch = "minty")`, which now includes our font size adjustment. ```{r echo = FALSE} knitr::include_graphics("images/bs-font-size.png") ``` -Finally, suppose we do not want borders to be rounded. -In our `customizer` theme, we can go to "Options" and then uncheck the "Rounded corners" box. +Finally, suppose we do not want borders to be rounded. In our `customizer` theme, we can go to "Options" and then uncheck the "Rounded corners" box. ```{r echo = FALSE} knitr::include_graphics("images/bs-corners.png") ``` -As expected, our corners are no longer rounded. -If we look at our R console, we will now see ``bs_theme_update(theme, font_scale = 1.25, `enable-rounded` = FALSE, bootswatch = "minty")``. +As expected, our corners are no longer rounded. If we look at our R console, we will now see `bs_theme_update(theme, font_scale = 1.25, `enable-rounded` = FALSE, bootswatch = "minty")`. -#### Applying a custom theme +#### Apply the customized theme -Assuming our customization is now complete, it's time to apply the changes to our application. -To do this, we use the option `teal.bs_theme` like before. -But this time we will expand on our `bslib::bs_theme` call to include our changes. -Helpfully, the arguments that were printed to the R console when running our app in the themer can be plugged right in. +Once our customization is complete, we will apply the changes to our application. To do this, we use the option `teal.bs_theme` like before but this time we will expand on our `bslib::bs_theme` call to include our changes. Luckily, the arguments that were printed to the R console when running our app in the themer can be plugged right in. ```{r eval = FALSE} options( diff --git a/vignettes/teal-options.Rmd b/vignettes/teal-options.Rmd index 284604d84a..c8be0eaf05 100644 --- a/vignettes/teal-options.Rmd +++ b/vignettes/teal-options.Rmd @@ -1,10 +1,9 @@ --- -title: "Modifying a teal application with R options" +title: "Modifying a teal Application With R Options" author: "Paweł Rucki" -date: " 2021-12-23" output: rmarkdown::html_vignette vignette: > - %\VignetteIndexEntry{Modifying a teal application with R options} + %\VignetteIndexEntry{Modifying a teal Application With R Options} %\VignetteEncoding{UTF-8} %\VignetteEngine{knitr::rmarkdown} editor_options: @@ -12,7 +11,7 @@ editor_options: --- # Motivation -Some `R` packages use `options` to modify their runtime behavior. These usually specify default values for internal functions or determine responses to users actions. For example, `testthat` uses an option `testthat.progress.max_fails` to define a default number of failed expectations before the testing functions terminate execution. While some of these adjustable values can be exposed as function parameters, some are destined to remain an option. This vignette details the options available to users of `teal`, `teal.logger`, `teal.widgets`, `teal.modules.general`, `teal.modules.clinical`. +Some `R` packages use `options` to modify their runtime behavior. These usually specify default values for internal functions or determine responses to users actions. For example, `testthat` uses an option `testthat.progress.max_fails` to define a default number of failed expectations before the testing functions terminate execution. While some of these adjustable values can be exposed as function parameters, some are confined to an option. This vignette details the options available to users of `teal`, `teal.logger`, `teal.widgets`, `teal.modules.general`, `teal.modules.clinical`. # Setting an option At any time during an interactive session, you can change an option using: @@ -39,7 +38,7 @@ This defines the layout of a log message used in a `teal` application. `teal` us Default: `"[{level}] {format(time, \"%Y-%m-%d %H:%M:%OS4\")} pid:{pid} token:[{token}] {ans} {msg}"`. -Note that this layout is formatted by the package `glue::glue`. +Note that this layout is formatted by the `glue` package. ### `teal.log_level` (`character`) This is the logging level threshold used in a `teal` application. A `teal` application will not emit logs below this level. Read the documentation of `teal.logger::register_logger` for more information. Possible values: `"TRACE"`, `"INFO"`, `"WARNING"`, `"ERROR"`. See the documentation of `logger::TRACE` for all possible values of logging threshold and more information on what it does. @@ -60,7 +59,7 @@ This indicates whether to print the `JavaScript` console logs to the `R` console Default: `FALSE`. ### `teal.threshold_slider_vs_checkboxgroup` (`numeric`) -It is the threshold that determines if a numeric variable is treated as a factor in the filter panel. If the number of unique values of a numeric variable is less than this threshold this variable will be treated as a factor instead of a numeric one. As an example, imagine `teal.threshold_slider_vs_checkboxgroup` equals to 2. Then a numeric variable `c(1, 1, 1)`, which has only one unique value (a digit `1`), is treated as a factor in the filter panel (and in the filter panel only!). The filter panel creates a checkbox widget to filter values from this variable, as it would for a factor variable, instead of a usual slider widget for numeric variables. +This is the threshold that determines if a variable is treated as a factor in the filter panel. If the number of unique values of a variable is less than this threshold the variable will be treated as a factor instead of its original class. As an example, imagine `teal.threshold_slider_vs_checkboxgroup` equals to 2. Then a numeric variable `c(1, 1, 1)`, which has only one unique value, is treated as a factor in the filter panel (and in the filter panel only!). The filter panel creates a checkbox widget to filter values from this variable, as it would for a factor variable, instead of the usual numeric range selector. Default: 5. @@ -86,7 +85,7 @@ This option controls the dots per inch of the graphs rendered and downloaded whe Default: 72 ### `teal.bs_theme` (`bslib::bs_theme` object) -This option controls the bootstrap theme and version used in the teal apps. Achieve better UX with the customized UI of an app. -Please visit the `vignette("teal-bs-themes", package = "teal")` to read more about the functionality. +This option controls the bootstrap theme and version used in `teal` apps. Achieve better UX with the customized UI of an app. +Please visit the vignette on Bootstrap themes to read more about the functionality. Default: `NULL` diff --git a/vignettes/teal.Rmd b/vignettes/teal.Rmd index 192c9dd9ee..40a40f313b 100644 --- a/vignettes/teal.Rmd +++ b/vignettes/teal.Rmd @@ -1,7 +1,6 @@ --- title: "Getting Started with teal" author: "NEST CoreDev" -date: "2022-11-03" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Getting Started with teal} @@ -11,25 +10,25 @@ vignette: > ## Introduction -*teal* is a shiny-based interactive exploration framework for analyzing data, with particular emphasis on -`CDISC` clinical trial data. `teal` applications provide their users with: +`teal` is a shiny-based interactive exploration framework for analyzing data, with particular emphasis on `CDISC` clinical trial data. +`teal` applications allow their users to: -* Ability to "pull" in data from external data sources -* Dynamic filtering of data to be used in the analyses -* Ability to generate reproducible code to regenerate the on-screen analyses -* Ability to create and download reports containing results of analyses (for analysis modules which support reporting) +* "Pull" in data from external data sources +* Dynamically filter of data to be used in the analyses +* Generate reproducible code to regenerate the on-screen analyses +* Create and download reports containing results of analyses (for analysis modules which support reporting) -In addition, the `teal` framework also provides application developers with: +In addition, the `teal` framework provides application developers with: * A large suite of custom-made standard analysis modules to be included in applications * A logging framework to facilitate debugging of applications -More advanced users of the framework can also create new analysis modules which can be added into any teal applications. -See the Creating Custom Modules vignette for a brief introduction to creating modules. +More advanced users of the framework can also create new analysis modules which can be added into any `teal` applications. +See the _Creating Custom Modules_ vignette for a brief introduction to creating modules. ## Your first `teal` application: -This simple application takes the `iris` and `mtcars` datasets and displays their contents in a `teal` application: +This simple `teal` application takes the `iris` and `mtcars` datasets and displays their contents: ```{r, message=FALSE} library(teal) @@ -51,60 +50,54 @@ if (interactive()) { As shown in the image above, this application consists of several distinct areas: -* Application header: The title of the application shown at the top. -* A filter panel (panels on the right hand side): for filtering the data to be passed into all `teal` modules. -* `teal` modules (accessible via a set of tabs): in this case a simple module named "example teal module". -* An encoding panel (panel on the left hand side): Module specific UI components, in this case a drop-down to select a dataset name. +* Application header: the title of the application shown at the top. +* `teal` modules (bar at the top): in this case a simple module named "example teal module". +* Encoding panel (panel on the left hand side): Module specific UI components, in this case a drop-down to select a dataset name. * Main output panel (panel on the middle): The outputs of the module, for this example module the chosen dataset is displayed. +* Filter panel (panels on the right hand side): for filtering the data to be passed into all `teal` modules. + +### Encoding panel + +The left hand side of the application is (usually) dedicated to module specific controls. +In modules which include reproducibility functionality it often contains a _Show R Code_ button that, when clicked, will display the code required to re-generate the output, including any filtering added by the filter panel and `library` calls to attach required packages. ### Filter panel -The filter panel allows users to select parts of the datasets they wish to use in the modules. The top panel shows the number of records which remain after filtering. +The filter panel allows app developers to select the datasets they wish to make available in the modules and define filters for those datasets. +The top section shows the number of records remaining in each dataset after filtering. +The middle section lists all currently defined filters. Typically these can be modified by the user. +The bottom section allows the user to add new filters. In the example below: -* For the `IRIS` dataset, only rows satisfying the conditions `Petal.Length >= 3.4` and `Species %in% c("setosa", "virginica")` are included thereby keeping 50 rows. +* For the `IRIS` dataset, only rows satisfying the conditions `Petal.Length >= 3.4` and `Species %in% c("setosa", "virginica")` are included, thereby keeping 50 rows. * For the `MTCARS` dataset, only rows satisfying the condition `cyl %in% c(4, 6)` are included, thereby keeping 18 rows. Example filter panel -### Encoding panel - -The left hand side of the application is (usually) dedicated to module specific controls. -For modules which include reproducibility functionality, it often contains a "Show R Code" button which when clicked will show the code required to re-generate the output (including any filters added on the filter panel and library calls to load required packages). - ## Creating your own applications -`init` is the key function to use to create your `teal` application and it requires two key arguments: `data` and `modules`. +The key function to use to create your `teal` application is `init`, which requires two arguments: `data` and `modules`. ### Application Data -The `data` argument to the `init` function specifies the data used by your application. This can contain data currently in your R session, -as in the example above, but also can contain `connectors` which describe where to "pull" data from when the application is run. This can be -used to allow data to be pulled into `teal` applications from external sources which require your application users to enter credentials. +The `data` argument to the `init` function specifies the data used by your application. This can be data currently in your R session, as in the example above, but also `connectors`, which describe how to "pull" remote data when the application is run. Connectors can pull data from external sources, which may require authentication. -In the example above we call `teal_data` to convert the raw datasets into `teal` specific datasets and to bind them in one `R` object. -This function can also be used to specify relationships between different datasets. -In order to use `CDISC` clinical trial data in a `teal` application the `cdisc_data` function is used instead. +In the example above we call `teal_data` to convert raw datasets into `teal` specific datasets and to bind them in one `R` object. This function can also be used to specify relationships between different datasets. In order to use `CDISC` clinical trial data in a `teal` application the `cdisc_data` function is used instead. For further details we recommend exploring the [`teal.data`](https://insightsengineering.github.io/teal.data/) package documentation. ### Modules -The `modules` argument to `init` consists of a list of `teal` modules (which can be wrapped together using the function `modules`). -We recommend creating applications using predefined `teal` modules. See the references below for links to these modules. +The `modules` argument to `init` consists of a list of `teal` modules (which can be wrapped together using the function `modules`). We recommend creating applications using predefined `teal` modules. See the references below for links to these modules. -### Defining filters +### Defining Filters -The `init` function has an additional argument `filters` which allows you to initialize the application with certain filters preselected. -See the documentation for `init` for further details. +The optional `filter` argument in `init` allows you to initialize the application with predefined filters. See the documentation for `init` for further details. ### Reporting -If any of the `modules` in your `teal` application support reporting -(see [`teal.reporter`](https://insightsengineering.github.io/teal.reporter/) for more details) then users of your application -can add these outputs to a report. This report can be downloaded and a special "Report Previewer" module will be added to your application as an additional tab -so your users can view and configure their reports before downloading them. +If any of the `modules` in your `teal` application support reporting (see [`teal.reporter`](https://insightsengineering.github.io/teal.reporter/) for more details), users of your application can add the outputs of the modules to a report. This report can then be downloaded and a special _Report Previewer_ module will be added to your application as an additional tab, where users can view and configure their reports before downloading them. ## Where to go next