library(metalite)
library(metalite.ae)
The purpose of this tutorial is to create production ready AE summary analyses by extending examples shown in the AE summary chapter of the R for Clinical Study Reports and Submission book.
The AE summary analysis provides tables to summarize adverse events information. With a metadata object created by metalite, there are three required functions to create AE summary analysis tables using metalite.ae:
prepare_ae_summary()
: prepare analysis raw
datasets.format_ae_summary()
: prepare analysis (mock) outdata
with proper format.tlf_ae_summary()
: transfer (mock) output dataset to RTF
table.There is one optional function to extend AE summary analysis:
extend_ae_specific_inference()
: add risk difference
inference results based on M&N method.An example output:
In metalite.ae, we created an example dataset using ADSL and ADAE datasets from the metalite package.
<- meta_ae_example()
meta
meta#> ADaM Meta Data:
#> .$data_population Population data with 254 subjects
#> .$data_observation Observation data with 1191 records
#> .$plan Analysis plan with 16 plans
#>
#>
#> Analysis population type:
#> name id group var subset label
#> 1 'apat' 'USUBJID' 'TRTA' SAFFL == 'Y' 'All Participants as Treated'
#>
#>
#> Analysis observation type:
#> name id group var subset label
#> 1 'wk12' 'USUBJID' 'TRTA' SAFFL == 'Y' 'Weeks 0 to 12'
#> 2 'wk24' 'USUBJID' 'TRTA' AOCC01FL == 'Y' 'Weeks 0 to 24'
#>
#>
#> Analysis parameter type:
#> name label
#> 1 'rel' 'drug-related adverse events'
#> 2 'aeosi' 'adverse events of special interest'
#> 3 'any' 'any adverse events'
#> 4 'ser' 'serious adverse events'
#> subset
#> 1 AEREL %in% c('POSSIBLE', 'PROBABLE')
#> 2 AEOSI == 'Y'
#> 3
#> 4 AESER == 'Y'
#>
#>
#> Analysis function:
#> name label
#> 1 'ae_summary' 'Table: adverse event summary'
#> 2 'ae_listing' 'Listing: adverse event'
#> 3 'ae_specific' 'Table: specific adverse event'
The same metadata structure is used to support all analysis examples in metalite.ae. More details can be found on the metalite package website.
The prepare_ae_summary()
function is used to calculate
statistics required for AE summary analysis using pre-specified keywords
in meta
. The input of the function is a meta
object created by metalite. The output of the function is an
outdata
object that contains a list of analysis raw
datasets.
<- prepare_ae_summary(
outdata
meta,population = "apat",
observation = "wk12",
parameter = "any;rel;ser"
)#> [1] "any"
#> [1] "rel"
#> [1] "ser"
outdata#> List of 12
#> $ meta :List of 7
#> $ population : chr "apat"
#> $ observation : chr "wk12"
#> $ parameter : chr "any;rel;ser"
#> $ n :'data.frame': 5 obs. of 4 variables:
#> $ order : num [1:5] 1 100 200 300 400
#> $ group : chr [1:4] "Placebo" "Low Dose" "High Dose" "Total"
#> $ reference_group: num 1
#> $ prop :'data.frame': 5 obs. of 4 variables:
#> $ diff :'data.frame': 5 obs. of 2 variables:
#> $ n_pop :'data.frame': 1 obs. of 4 variables:
#> $ name : chr [1:5] "Participants in population" "with one or more adverse events" "with no adverse events" "with drug-related{^a} adverse events" ...
The output dataset contains commonly used statistics. The variable is
indexed by the order of outdata$group
.
$group
outdata#> [1] "Placebo" "Low Dose" "High Dose" "Total"
The row is indexed by the order of outdata$name
.
head(data.frame(outdata$order, outdata$name))
#> outdata.order outdata.name
#> 1 1 Participants in population
#> 2 100 with one or more adverse events
#> 3 200 with no adverse events
#> 4 300 with drug-related{^a} adverse events
#> 5 400 with serious adverse events
n_pop
: participants in population.$n_pop
outdata#> n_1 n_2 n_3 n_4
#> 1 86 84 84 254
n
: number of subjects with AE.head(outdata$n)
#> n_1 n_2 n_3 n_4
#> 1 86 84 84 254
#> 2 69 77 79 225
#> 3 17 7 5 29
#> 21 44 73 70 187
#> 22 0 1 2 3
prop
: proportion of subjects with AE.head(outdata$prop)
#> prop_1 prop_2 prop_3 prop_4
#> 1 NA NA NA NA
#> 2 80.23256 91.666667 94.047619 88.582677
#> 3 19.76744 8.333333 5.952381 11.417323
#> 21 51.16279 86.904762 83.333333 73.622047
#> 22 0.00000 1.190476 2.380952 1.181102
diff
: risk difference compared with the
reference_group
.head(outdata$diff)
#> diff_2 diff_3
#> 1 NA NA
#> 2 11.434109 13.815061
#> 21 35.741971 32.170543
#> 22 1.190476 2.380952
#> 3 -11.434109 -13.815061
After we have the raw analysis results, we can use
format_ae_summary()
to prepare the outdata for production
ready RTF tables.
<- outdata |> format_ae_summary()
tbl $tbl
tbl#> name n_1 prop_1 n_2 prop_2 n_3 prop_3 n_4
#> 1 Participants in population 86 <NA> 84 <NA> 84 <NA> 254
#> 2 with one or more adverse events 69 (80.2) 77 (91.7) 79 (94.0) 225
#> 3 with no adverse events 17 (19.8) 7 (8.3) 5 (6.0) 29
#> 21 with drug-related{^a} adverse events 44 (51.2) 73 (86.9) 70 (83.3) 187
#> 22 with serious adverse events 0 (0.0) 1 (1.2) 2 (2.4) 3
#> prop_4
#> 1 <NA>
#> 2 (88.6)
#> 3 (11.4)
#> 21 (73.6)
#> 22 (1.2)
The display
argument allows us to select statistics. For
example, we can add risk difference.
<- outdata |> format_ae_summary(display = c("n", "prop", "diff"))
tbl $tbl
tbl#> name n_1 prop_1 n_2 prop_2 n_3 prop_3 diff_2
#> 1 Participants in population 86 <NA> 84 <NA> 84 <NA> NA
#> 2 with one or more adverse events 69 (80.2) 77 (91.7) 79 (94.0) 11.4
#> 3 with no adverse events 17 (19.8) 7 (8.3) 5 (6.0) 35.7
#> 21 with drug-related{^a} adverse events 44 (51.2) 73 (86.9) 70 (83.3) 1.2
#> 22 with serious adverse events 0 (0.0) 1 (1.2) 2 (2.4) -11.4
#> diff_3
#> 1 NA
#> 2 13.8
#> 3 32.2
#> 21 2.4
#> 22 -13.8
For advanced analysis, we need
extend_ae_specific_inference()
. For example, we can add 95%
confidence interval based on Miettinen and Nurminen (M&N) method.
The details of the M&N method can be found in the rate
compare vignette.
<- outdata |>
tbl extend_ae_specific_inference() |>
format_ae_summary(display = c("n", "prop", "diff", "diff_ci"))
$tbl
tbl#> name n_1 prop_1 n_2 prop_2 n_3 prop_3 diff_2
#> 1 Participants in population 86 <NA> 84 <NA> 84 <NA> NA
#> 2 with one or more adverse events 69 (80.2) 77 (91.7) 79 (94.0) 11.4
#> 3 with no adverse events 17 (19.8) 7 (8.3) 5 (6.0) 35.7
#> 21 with drug-related{^a} adverse events 44 (51.2) 73 (86.9) 70 (83.3) 1.2
#> 22 with serious adverse events 0 (0.0) 1 (1.2) 2 (2.4) -11.4
#> ci_2 diff_3 ci_3
#> 1 (-4.4, 0.0) NA (-4.4, 0.0)
#> 2 ( 1.0, 22.2) 13.8 ( 4.0, 24.3)
#> 3 (-22.2, -1.0) 32.2 (-24.3, -4.0)
#> 21 (22.4, 48.0) 2.4 (18.4, 44.8)
#> 22 (-3.1, 6.5) -13.8 (-2.0, 8.3)
The mock
argument allows us to create a mock table
easily.
Note: The purpose of the mock
argument is not to create
a comprehensive mock table template, but a handy way to help user create
a mock table that mimics the exact output layout.
Additional work is required to develop a flexible mock table generation tool (for example, a dedicated mock table generation package).
<- outdata |> format_ae_summary(mock = TRUE)
tbl $tbl
tbl#> name n_1 prop_1 n_2 prop_2 n_3 prop_3 n_4
#> 1 Participants in population xx <NA> xx <NA> xx <NA> xxx
#> 2 with one or more adverse events xx (xx.x) xx (xx.x) xx (xx.x) xxx
#> 3 with no adverse events xx (xx.x) x (x.x) x (x.x) xx
#> 4 with drug-related{^a} adverse events xx (xx.x) xx (xx.x) xx (xx.x) xxx
#> 5 with serious adverse events x (x.x) x (x.x) x (x.x) x
#> prop_4
#> 1 <NA>
#> 2 (xx.x)
#> 3 (xx.x)
#> 4 (xx.x)
#> 5 (x.x)
The last step is to prepare the RTF table using
tlf_ae_summary()
.
|>
outdata format_ae_summary() |>
tlf_ae_summary(
source = "Source: [CDISCpilot: adam-adsl; adae]",
path_outtable = "rtf/ae0summary1.rtf"
)#> The output is saved in/rtmp/RtmpPhK17m/Rbuild1a125d24fe88/metalite.ae/vignettes/rtf/ae0summary1.rtf
The tlf_ae_summary()
function also provides some
commonly used argument to customize the table.
|>
outdata format_ae_summary() |>
tlf_ae_summary(
source = "Source: [CDISCpilot: adam-adsl; adae]",
col_rel_width = c(6, rep(1, 8)),
text_font_size = 8,
orientation = "landscape",
path_outtable = "rtf/ae0summary2.rtf"
)#> The output is saved in/rtmp/RtmpPhK17m/Rbuild1a125d24fe88/metalite.ae/vignettes/rtf/ae0summary2.rtf
The mock table can also be generated.
|>
outdata format_ae_summary(mock = TRUE) |>
tlf_ae_summary(
source = "Source: [CDISCpilot: adam-adsl; adae]",
path_outtable = "rtf/mock_ae0summary1.rtf"
)#> The output is saved in/rtmp/RtmpPhK17m/Rbuild1a125d24fe88/metalite.ae/vignettes/rtf/mock_ae0summary1.rtf