layouts.Rmd
The chevron
R package has a collection of functions that
create standard tables, listings, and graphs (TLGs). These functions are
referred in chevron
as tlg-functions. A subset of
these tlg-functions create tables. Tables are created using the
rtables
package. rtables
has the context of
table layouts, i.e. pre-data table cell-derivation instructions. For
example:
library(rtables)
#> Loading required package: magrittr
#> Loading required package: formatters
lyt <- basic_table() %>%
split_cols_by("ARM") %>%
analyze("AGE", mean)
lyt
#> A Pre-data Table Layout
#>
#> Column-Split Structure:
#> ARM (lvls)
#>
#> Row-Split Structure:
#> AGE (** analysis **)
These layout contain all the cell-value derivation information and can be used and reused for different data
adsl <- data.frame(
ARM = factor(sample(c("ARM A", "ARM B"), 100, TRUE)),
AGE = runif(100, 20, 90),
COUNTRY = factor(sample(c("CHN", "USA", "BRA", "RUS"), 100, TRUE))
)
build_table(lyt, adsl)
#> ARM A ARM B
#> —————————————————————————————————————————
#> mean 53.8902372463296 54.329995988443
build_table(lyt, adsl[adsl$COUNTRY == "RUS", ])
#> ARM A ARM B
#> ——————————————————————————————————————————
#> mean 52.2339463816024 55.9801052469993
Hence these layouts define a table pre-data. That is, the layout
functions in chevron
do never take any data as an argument.
Note that pruning and sorting are currently not performed in the layout
space in rtables
but rather on the actual table
objects.
Also, layouts allow for certain queries such as which variables are required to build the table using the given layout:
rtables::vars_in_layout(lyt)
#> [1] "ARM" "AGE"
So in chevron
when creating tables we always do the
explicit layout creation in the *_lyt
functions. For
example for aet02_1
we have the layout function:
library(chevron)
#> Registered S3 method overwritten by 'tern':
#> method from
#> tidy.glm broom
aet02_1_lyt
#> function (armvar = .study$actualarm, lbl_overall = .study$lbl_overall,
#> lbl_aebodsys = "Body System or Organ Class", lbl_aedecod = "Dictionary-Derived Term",
#> deco = std_deco("AET02"), .study = list(actualarm = "ACTARM",
#> lbl_overall = NULL))
#> {
#> basic_table_deco(deco) %>% split_cols_by(var = armvar) %>%
#> add_colcounts() %>% ifneeded_add_overall_col(lbl_overall) %>%
#> summarize_num_patients(var = "USUBJID", .stats = c("unique",
#> "nonunique"), .labels = c(unique = "Total number of patients with at least one adverse event",
#> nonunique = "Overall total number of events")) %>%
#> split_rows_by("AEBODSYS", child_labels = "visible", labels_var = "AEBODSYS",
#> nested = FALSE, indent_mod = -1L, split_fun = drop_split_levels,
#> label_pos = "topleft", split_label = lbl_aebodsys) %>%
#> summarize_num_patients(var = "USUBJID", .stats = c("unique",
#> "nonunique"), .labels = c(unique = "Total number of patients with at least one adverse event",
#> nonunique = "Total number of events")) %>% count_occurrences(vars = "AEDECOD",
#> .indent_mods = -1L) %>% append_topleft(paste0(" ", lbl_aedecod))
#> }
#> <bytecode: 0x55a9cae690b8>
#> <environment: namespace:chevron>
Note that the aet02_1_lyt
function returns a concise
description on how tern
and rtables
can be
used to create the cell values of the tables. The table creation
function then does then use the *_lyt
function and builds
the table using build_table
and the data given in
adam_db
as shown next:
aet02_1
#> function (adam_db, armvar = .study$actualarm, lbl_overall = .study$lbl_overall,
#> prune_0 = TRUE, deco = std_deco("AET02"), .study = list(actualarm = "ACTARM",
#> lbl_overall = NULL))
#> {
#> dbsel <- get_db_data(adam_db, "adsl", "adae")
#> lyt <- aet02_1_lyt(armvar = armvar, lbl_overall = lbl_overall,
#> lbl_aebodsys = var_labels_for(dbsel$adae, "AEBODSYS"),
#> lbl_aedecod = var_labels_for(dbsel$adae, "AEDECOD"),
#> deco = deco)
#> tbl <- build_table(lyt, dbsel$adae, alt_counts_df = dbsel$adsl)
#> if (prune_0) {
#> tbl <- prune_table(tbl)
#> }
#> tbl_sorted <- tbl %>% sort_at_path(path = c("AEBODSYS"),
#> scorefun = cont_n_onecol(ncol(tbl))) %>% sort_at_path(path = c("AEBODSYS",
#> "*", "AEDECOD"), scorefun = score_occurrences)
#> tbl_sorted
#> }
#> <bytecode: 0x55a9bdad82a8>
#> <environment: namespace:chevron>
chevron
exports the layout functions for each table
creating tlg-function
deco
argument. Note that we
currently do not have all of the data base for standard headers and
footers imported in chevron
.