Topic 3: Launching a simple teal application (7 minutes)

Launching a simple teal application

When you launch this minimal application, you’ll observe:

  1. The teal header - displaying the application title
  2. A main panel that shows our one empty module.
  3. The filter panel on the left - ready to filter data (though no data is loaded yet)
  4. The navigation structure - showing how teal organizes content

Basic structure

Every teal application follows this fundamental pattern:

  • Initialization using teal::init()
  • Data specification (must be specified)
  • Modules definition
  • Application launch using the usual Shiny API

Code example: Simplest teal application

library(teal)

# Create the simplest possible teal application
app <- teal::init(
  data = teal.data::teal_data(iris = iris),
  modules = teal::example_module(
    label = "example teal module",
    datanames = "all",
    transformators = list(),
    decorators = list()
  )
)

# Launch the application
shiny::shinyApp(app$ui, app$server)

What this demonstrates

This minimal example shows you:

  • The teal framework structure
  • The filter panel
  • The modular architecture - the list in the top left shows the module list (with just one module for now)
  • The initialization pattern - teal::init() is the entry point for all teal applications

The data argument - your application’s foundation

The data argument is where you specify all the datasets your application will use. There are several ways to provide data to teal:

  • using teal_data()
  • using cdisc_data() for clinical data

Option 1: Using teal_data()

# Create data using teal_data()
my_data <- teal_data(
  ADSL = adsl_data,
  ADAE = adae_data,
  IRIS = iris
)

app <- init(
  data = my_data,
  modules = modules(...)
)

Option 2: Using cdisc_data() for clinical data

# For CDISC/ADaM data with relationships
my_data <- cdisc_data(
  ADSL = adsl_data,
  ADAE = adae_data,
  code = c(
    "ADSL <- adsl_data",
    "ADAE <- adae_data"
  )
)

app <- init(
  data = my_data,
  modules = modules(...)
)

What the data argument controls:

  • Available datasets - Which datasets appear in the filter panel
  • Data relationships - How datasets connect to each other (via join_keys)
  • Reproducibility - Code tracking for generating the data

The modules argument - your application’s functionality

The modules argument defines what your application can do. It accepts a modules() object containing one or more teal modules.

Single module example

library(teal.modules.general)
library(teal.data)

app <- teal::init(
  data = teal.data::teal_data(IRIS = iris),
  modules = teal::modules(
    teal.modules.general::tm_data_table(
      label = "Data Explorer",
      datanames = "IRIS"
    )
  )
)

# Launch the application
shiny::shinyApp(app$ui, app$server)

Multiple modules example

library(teal.modules.general)

app <- teal::init(
  data = teal.data::teal_data(IRIS = iris, MTCARS = mtcars, code = "IRIS <- iris; MTCARS <- mtcars"),
  modules = teal::modules(
    teal.modules.general::tm_data_table(
      label = "Data Tables",
      dataname = "IRIS"
    ),
    teal.modules.general::tm_variable_browser(
      label = "Variable Browser",
      dataname = "IRIS"
    ),
    teal.modules.general::tm_g_scatterplot(
      label = "Scatter Plot",
      x = teal.transform::data_extract_spec(
        dataname = "IRIS",
        select = teal.transform::select_spec(
          choices = teal.transform::variable_choices("IRIS", c("Sepal.Length", "Sepal.Width")),
          selected = "Sepal.Length"
        )
      ),
      y = teal.transform::data_extract_spec(
        dataname = "IRIS",
        select = teal.transform::select_spec(
          choices = teal.transform::variable_choices("IRIS", c("Petal.Length", "Petal.Width")),
          selected = "Petal.Length"
        )
      )
    )
  )
)

# Launch the application
shiny::shinyApp(app$ui, app$server)

🛠️ Exercise (a warm up really)

  • Try launching this application in your environment.
library(teal)

app <- teal::init(
  data = teal.data::teal_data(iris = iris),
  modules = teal::example_module(
    label = "example teal module",
    datanames = "all",
    transformators = list(),
    decorators = list()
  )
)

# Launch the application
if (interactive()) {
  shiny::shinyApp(app$ui, app$server)
}

🛠️ Exercise

  1. Add another dataset to the application - mtcars
  2. Launch the application and check if the dataset is available in the application
library(teal)

app <- teal::init(
  data = teal.data::teal_data(iris = iris, mtcars = mtcars),
  modules = teal::example_module(
    label = "example teal module",
    datanames = "all",
    transformators = list(),
    decorators = list()
  )
)

# Launch the application
if (interactive()) {
  shiny::shinyApp(app$ui, app$server)
}

🛠️ Exercise

  1. Add a new module to the application - teal.modules.general::tm_data_table().
  2. Launch the application and check if the module is available in the application

Hint: you will need to load the teal.modules.general package to use the module. via library(teal.modules.general). If you feel lost, please check out the manual at: https://insightsengineering.github.io/teal.modules.general/latest-tag/reference/tm_data_table.html

library(teal)
library(teal.modules.general) # <- new library call

app <- teal::init(
  data = teal.data::teal_data(iris = iris, mtcars = mtcars),
  modules = teal::modules(
    teal::example_module(
      label = "example teal module",
      datanames = "all",
      transformators = list(),
      decorators = list()
    ),
    teal.modules.general::tm_data_table()
  )
)

# Launch the application
if (interactive()) {
  shiny::shinyApp(app$ui, app$server)
}

🌐 References