Introduction to Chevron
Adrian Waddell
2022-10-21
chevron.Rmd
Introduction
The chevron
R package provides functions to produce
standard tables, listings and graphs (TLGs) used to analyze and report
clinical trials data. The ensemble of function used to produce a
particular output are stored in an S4
object of virtual
class chevron_tlg
. Each type of output are associated with
a specific class: chevron_t
for tables,
chevron_l
for listings and chevron_g
for
graphs.
Each standard output is associated with one
chevron_tlg
object. They contain the following
objects in separate slots:
- A
main
function also refereed to as TLG-function. - A
preprocess
function. - A
postprocess
function - A
adam_datasets
character vector of the name of theAdAM
datasets required to create the output.
TLG-functions
The TLG-functions in chevron
use other packages
to produce the final outputs, for example rtables
and
tern
are used to create tables, ggplot2
,
lattice
, and grid
are used to create graphs,
rlistings
to create listings.
TLG-functions in chevron
such as
dmt01_1_main
, aet02_1_main
,
aet02_2_main
have the following properties:
- they produce a narrow defined output (currently standards in Roche
GDS
). Note, that the naming convention<gds template id>_<i>_main
indicates that a RocheGDS
defined standard may have different implementations. Or, alternatively, aGDS
template id can be regarded as a guideline and the function name inchevron
as a standard. - have, if possible, few arguments to modify the standard. Generally, arguments may change the structure of the table (arm variable, which variables are summarized) but not parameterize the cell content (i.e. alpha-level for p-value).
- have always the first argument
adam_db
which is the collection ofADaM
datasets (ADSL
,ADAE
,ADRS
, etc.). Please read the Theadam_db
Argument vignette in this package for more details.
preprocessing
The preprocess functions in chevron
use
dm
and dunlin
packages to process
dm
object and turn them into a suitable input for
TLG-functions. The preprocessing step typically includes checks
that will ensure that the dm
input can be later processed
by the TLG-functions.
preprocess in chevron such as dmt01_1_pre
,
aet02_1_pre
, aet02_2_pre
have the following
properties:
- they return a
dm
object amenable to processing by a TLG-functions or return rapidly an understandable error message. - have very few arguments to modify the standard.
- have always the first argument
adam_db
which is the collection ofADaM
datasets (ADSL
,ADAE
,ADRS
, etc.). Please read the Theadam_db
Argument vignette in this package for more details.
Example AET02
For example, the GDS
template aet02
is
implemented in chevron
with the chevropn_tlg
objects that have the name aet02_*
. The object
documentation which is accessible with the help
function,
e.g. help('aet02_1')
documents what is particular in the
_1
implementation.
We first define the data and put it in a dm
object, you
can find more details about this in the adam_db
vignette.
library(chevron)
#> Registered S3 method overwritten by 'tern':
#> method from
#> tidy.glm broom
library(dm)
#>
#> Attaching package: 'dm'
#> The following object is masked from 'package:stats':
#>
#> filter
data(syn_data, package = "chevron")
adam_study_data <- dm(adsl = syn_data$adsl, adae = syn_data$adae) %>%
dm_add_pk(adsl, c("USUBJID", "STUDYID")) %>%
dm_add_fk(adae, c("USUBJID", "STUDYID"), ref_table = "adsl") %>%
dm_add_pk(adae, c("USUBJID", "STUDYID", "ASTDTM", "AETERM", "AESEQ"))
dm_validate(adam_study_data)
A the aet02_1
output is then created as follows:
run(aet02_1, adam_study_data)
#> MedDRA System Organ Class A: Drug X B: Placebo C: Combination
#> MedDRA Preferred Term (N=134) (N=134) (N=132)
#> ———————————————————————————————————————————————————————————————————————————————————————————————————————
#> Total number of patients with at least one adverse event 122 (91.0%) 123 (91.8%) 120 (90.9%)
#> Overall total number of events 609 622 703
#> cl A.1
#> Total number of patients with at least one adverse event 78 (58.2%) 75 (56.0%) 89 (67.4%)
#> Total number of events 132 130 160
#> dcd A.1.1.1.1 50 (37.3%) 45 (33.6%) 63 (47.7%)
#> dcd A.1.1.1.2 48 (35.8%) 48 (35.8%) 50 (37.9%)
#> cl B.2
#> Total number of patients with at least one adverse event 79 (59.0%) 74 (55.2%) 85 (64.4%)
#> Total number of events 129 138 143
#> dcd B.2.2.3.1 48 (35.8%) 54 (40.3%) 51 (38.6%)
#> dcd B.2.1.2.1 49 (36.6%) 44 (32.8%) 52 (39.4%)
#> cl D.1
#> Total number of patients with at least one adverse event 79 (59.0%) 67 (50.0%) 80 (60.6%)
#> Total number of events 127 106 135
#> dcd D.1.1.1.1 50 (37.3%) 42 (31.3%) 51 (38.6%)
#> dcd D.1.1.4.2 48 (35.8%) 42 (31.3%) 50 (37.9%)
#> cl D.2
#> Total number of patients with at least one adverse event 47 (35.1%) 58 (43.3%) 57 (43.2%)
#> Total number of events 62 72 74
#> dcd D.2.1.5.3 47 (35.1%) 58 (43.3%) 57 (43.2%)
#> cl B.1
#> Total number of patients with at least one adverse event 47 (35.1%) 49 (36.6%) 43 (32.6%)
#> Total number of events 56 60 62
#> dcd B.1.1.1.1 47 (35.1%) 49 (36.6%) 43 (32.6%)
#> cl C.2
#> Total number of patients with at least one adverse event 35 (26.1%) 48 (35.8%) 55 (41.7%)
#> Total number of events 48 53 65
#> dcd C.2.1.2.1 35 (26.1%) 48 (35.8%) 55 (41.7%)
#> cl C.1
#> Total number of patients with at least one adverse event 43 (32.1%) 46 (34.3%) 43 (32.6%)
#> Total number of events 55 63 64
#> dcd C.1.1.1.3 43 (32.1%) 46 (34.3%) 43 (32.6%)
The function associated with a particular slot can be retrieved with
the corresponding method: main
, lyt
,
preprocess
postprocess
and
datasets
.
main(aet02_1)
#> function (adam_db, arm_var = "ACTARM", lbl_overall = NULL, lbl_aebodsys = "MedDRA System Organ Class",
#> lbl_aedecod = "MedDRA Preferred Term", deco = std_deco("AET02"),
#> ...)
#> {
#> dbsel <- get_db_data(adam_db, "adsl", "adae")
#> assert_colnames(adam_db$adae, c("AEBODSYS", "AEDECOD"))
#> lyt <- aet02_1_lyt(arm_var = arm_var, lbl_overall = lbl_overall,
#> lbl_aebodsys = lbl_aebodsys, lbl_aedecod = lbl_aedecod,
#> deco = deco)
#> tbl <- build_table(lyt, dbsel$adae, alt_counts_df = dbsel$adsl)
#> tbl
#> }
#> <bytecode: 0x558d64a46e50>
#> <environment: namespace:chevron>
These are standard functions that can be used on their own.
preprocess(aet02_1)(adam_study_data)
#> ── Metadata ────────────────────────────────────────────────────────────────────
#> Tables: `adsl`, `adae`
#> Columns: 159
#> Primary keys: 2
#> Foreign keys: 1
# or
foo <- aet02_1@preprocess
foo(adam_study_data)
#> ── Metadata ────────────────────────────────────────────────────────────────────
#> Tables: `adsl`, `adae`
#> Columns: 159
#> Primary keys: 2
#> Foreign keys: 1
chevron_tlg
object customization
In some instances it is useful to customize the
chevron_tlg
object, for example by changing the pre
processing functions. Be aware that you have to think carefully about
argument names and compatibility with downstream functions.
Note that this operation creates a local version of the
chevron_tlg
object. The package version of the
chevron_tlg
object (accessible with
chevron::aet01_1
) remains unchanged.
preprocess(aet02_1) <- function(adam_db, ...) adam_db
preprocess(aet02_1)
#> function(adam_db, ...) adam_db
Custom chevron_tlg
object creation
To create a chevron_tlg
object from scratch, use the
provided constructors corresponding to the desired output:
-
chevron_t()
for tables. -
chevron_l()
for listings. -
chevron_g()
for graphs.
library(rtables)
#> Loading required package: magrittr
#> Loading required package: formatters
library(tern)
my_template <- chevron_t(
main = aet02_1_main,
preprocess = aet02_1_pre,
postprocess = function(tlg, ...) {
tbl_sorted <- tlg %>%
sort_at_path(
path = c("AEBODSYS"),
scorefun = cont_n_onecol(j = 3) # sort based on your chosen column
) %>%
sort_at_path(
path = c("AEBODSYS", "*", "AEDECOD"),
scorefun = score_occurrences
)
tbl_sorted
},
adam_datasets = c("adsl", "adae")
)
run(my_template, adam_study_data)
#> MedDRA System Organ Class A: Drug X B: Placebo C: Combination
#> MedDRA Preferred Term (N=134) (N=134) (N=132)
#> ———————————————————————————————————————————————————————————————————————————————————————————————————————
#> Total number of patients with at least one adverse event 122 (91.0%) 123 (91.8%) 120 (90.9%)
#> Overall total number of events 609 622 703
#> cl A.1
#> Total number of patients with at least one adverse event 78 (58.2%) 75 (56.0%) 89 (67.4%)
#> Total number of events 132 130 160
#> dcd A.1.1.1.1 50 (37.3%) 45 (33.6%) 63 (47.7%)
#> dcd A.1.1.1.2 48 (35.8%) 48 (35.8%) 50 (37.9%)
#> cl B.2
#> Total number of patients with at least one adverse event 79 (59.0%) 74 (55.2%) 85 (64.4%)
#> Total number of events 129 138 143
#> dcd B.2.2.3.1 48 (35.8%) 54 (40.3%) 51 (38.6%)
#> dcd B.2.1.2.1 49 (36.6%) 44 (32.8%) 52 (39.4%)
#> cl D.1
#> Total number of patients with at least one adverse event 79 (59.0%) 67 (50.0%) 80 (60.6%)
#> Total number of events 127 106 135
#> dcd D.1.1.1.1 50 (37.3%) 42 (31.3%) 51 (38.6%)
#> dcd D.1.1.4.2 48 (35.8%) 42 (31.3%) 50 (37.9%)
#> cl D.2
#> Total number of patients with at least one adverse event 47 (35.1%) 58 (43.3%) 57 (43.2%)
#> Total number of events 62 72 74
#> dcd D.2.1.5.3 47 (35.1%) 58 (43.3%) 57 (43.2%)
#> cl C.2
#> Total number of patients with at least one adverse event 35 (26.1%) 48 (35.8%) 55 (41.7%)
#> Total number of events 48 53 65
#> dcd C.2.1.2.1 35 (26.1%) 48 (35.8%) 55 (41.7%)
#> cl B.1
#> Total number of patients with at least one adverse event 47 (35.1%) 49 (36.6%) 43 (32.6%)
#> Total number of events 56 60 62
#> dcd B.1.1.1.1 47 (35.1%) 49 (36.6%) 43 (32.6%)
#> cl C.1
#> Total number of patients with at least one adverse event 43 (32.1%) 46 (34.3%) 43 (32.6%)
#> Total number of events 55 63 64
#> dcd C.1.1.1.3 43 (32.1%) 46 (34.3%) 43 (32.6%)
Note that to ensure the correct execution of the run
function, the name of the first argument of the main
function must be adam_db
; the input dm
object
to pre-process. The name of the first argument of the
preprocess
function must be adam_db
; the input
dm
object to create TLG
output and finally,
the name of the first argument of the postprocess
function
must be tlg
, the input TableTree
object to
post-process. Validation criteria enforce these rules upon creation of a
chevron_tlg
object.