--- title: "Standard Column Structures" date: "2026-05-04" output: rmarkdown::html_document: theme: "spacelab" highlight: "kate" toc: true toc_float: true vignette: > %\VignetteIndexEntry{Standard Column Structures} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} editor_options: markdown: wrap: 72 --- ```{r setup, include = FALSE} knitr::opts_chunk$set( echo = TRUE, collapse = TRUE, comment = "#>" ) ``` # Structures With Difference Columns Many standard tables call for a set of difference columns to be added alongside the main tabulation; this, combined with the spanning column labels favored by Johnson&Johnson shells, results in a complex final column structure. To ease the creation of these structures, particularly in the presence of virtual *combination* arms, we provide the `grouped_cols_w_diffs` function. It provides the flexibility to be used in standard template scripts, as we will see below. ## Basic Usage At it's most basic, `grouped_cols_w_diffs` takes a column-span treatment map, as created by `create_colspan_map`. This creates a column structure with spanning labels over active and non-active treatment groups, as well as difference columns comparing each active treatments individually against each non-active treatment: ```{r} library(junco) adsl <- create_colspan_var(pharmaverseadamjnj::adsl) adae <- create_colspan_var(pharmaverseadamjnj::adae) trt_map <- create_colspan_map(adsl) print(trt_map) ``` ```{r} lyt <- basic_table() |> grouped_cols_w_diffs(trt_map) build_table(lyt, adsl) ``` ### A Note About Types Of Differences `grouped_cols_w_diffs` creates only the *column* structure; the contents of the difference columns are calculated by the analysis function used in the layout. The *structure* for the various types of difference columns (risk, mean, eair, etc) differs only in the spanning label for the difference columns. `grouped_cols_w_diffs` accepts `diffs_label` for this purpose: ```{r} lyt2 <- basic_table() |> grouped_cols_w_diffs(trt_map, diffs_label = "Mean Differences") build_table(lyt2, adsl) ``` Care should be taken to choose the correct analysis function to create the types of differences required by your shell. ### Turning Off The Difference Columns Despite the function's name, we can turn off difference columns when using `grouped_cols_w_diffs` via the `diff_cols` argument. This allows us to use the function unconditionally in our layouts while retaining the ability to turn off difference columns , e.g., in shells where they are optional. ```{r} lyt_nodiff <- basic_table() |> grouped_cols_w_diffs(trt_map, diff_cols = FALSE) build_table(lyt_nodiff, adsl) ``` ## Advanced Usage Beyond the basic usage, `grouped_cols_w_diffs` offers fine-grained control over both the arms (notably the addition of combination arms) and comparisons between arms displayed in your table. ### Including Virtual Combination Arms Combination levels are declared via a "combo data.frame" similar to those accepted by `rtables::add_combo_levels`. In particular, we use a data.frame with the following columns: - **`valname`** - (`character`) Name of the combination level (as it will appear in paths) - **`label`** - (`character`) Label for the combination level (as it will appear in the table) - **`levelcombo`** - (`list` of `character`s) The levels which should be combined into the combination level - **`exargs`** - (`list`) Extra arguments to be passed to a/cfuns associated with the combination level - **`is_control`** *Optional* (`logical`) When `TRUE`, the combination level will be added to the second (non-active) group of treatments. Assumed `FALSE` if not specified. - **`compare_against`** *Optional* (`list` of `character`s) The levels the combination level should be compared against (as the first/active element). Assumed to be `select_all_levels` if not specified. Thus at its most basic, we use this argument like so: ```{r} library(tibble) combodf1 <- tribble( ~valname, ~label, ~levelcombo, ~exargs, "all_active", "All Xanomeline", c("Xanomeline High Dose", "Xanomeline Low Dose"), list() ) lyt3 <- basic_table() |> grouped_cols_w_diffs(trt_map, combo_map_df = combodf1) build_table(lyt3, adsl) ``` We can instead add a second virtual control or referene group by including the `is_control` column and setting it to `TRUE` for some or all of our combination levels: ```{r} combodf2 <- tribble( ~valname, ~label, ~levelcombo, ~exargs, ~is_control, "all_active", "All Xanomeline", c("Xanomeline High Dose", "Xanomeline Low Dose"), list(), FALSE, "placebo_redux", "Double Placebo!!", c("Placebo"), list(), TRUE ) lyt4 <- basic_table() |> grouped_cols_w_diffs(trt_map, combo_map_df = combodf2) build_table(lyt4, adsl) ``` As we can see, this allows us full flexibility to include combination levels as both active and non-active virtual arms, including using them in both sides of comparisons (even simultaneously). ### Direct Control Of Comparisons Finally, we have complete control over which comparisons appear in our table via the `comp_map` argument. When non-null, the exact set of comparisons specified in `comp_map` will appear in our table. `comp_map` accepts a data.frame with the columns `active`, and `comparator`, as well optional `active_is_combo` and `comparator_is_combo` columns. The values in `active` and `comparator` should be the *names* (as opposed to labels) of the respective arms: ```{r} comp_map1 <- tribble( ~active, ~comparator, "Xanomeline High Dose", "Placebo", "Xanomeline Low Dose", "placebo_redux", "all_active", "placebo_redux" ) lyt5 <- basic_table() |> grouped_cols_w_diffs(trt_map, combo_map_df = combodf2, comp_map = comp_map1) build_table(lyt5, adsl) ``` We can also use `comp_map` to compare one active treatment to another: ```{r} comp_map2 <- tribble( ~active, ~comparator, "Xanomeline High Dose", "Xanomeline Low Dose", "Xanomeline High Dose", "Placebo", "Xanomeline Low Dose", "Placebo" ) lyt6 <- basic_table() |> grouped_cols_w_diffs(trt_map, comp_map = comp_map2) build_table(lyt6, adsl) ```