library(tidyverse)
library(gtsummary)
library(gtreg)
library(labelled)
library(admiral) # for subject data
library(admiral.test) # for ae data
Introducing {gtreg}: Exercises
Instructions:
Recommended: Complete these exercises in the dedicated R in Pharma RStudio Cloud work space, which comes with
all packages pre-installed, and
an Rmarkdown document to fill in.
It may still be helpful to peek here to verify that your tables match the desired output.
Click here to enter R in Pharma RStudio Cloud work space for {gtreg}
Otherwise: Follow along this document, work on your personal computer, and challenge yourself not to peek at the code solutions until you have completed the exercise.
Packages
Output display setting
theme_gtsummary_compact()
The Data
For these exercises we will be using STDM and ADaM datasets from the {admiral.test} and {admiral} and packages.
First, prepare a subject level data set named subjects
from the admiral_adsl
data set with only the variables USUBJID
, ACTARM
, AGE
, SEX
, RACE
and subjects who screen failed removed.
<- admiral_adsl %>%
dat_subjects filter(ACTARM != "Screen Failure" & ACTARM %in% c("Placebo", "Xanomeline High Dose") ) %>%
select(USUBJID, ACTARM, AGE, SEX, RACE) %>%
mutate(across(RACE, str_to_title)) %>%
mutate(
# convert treatment arm and race to factors for table displays in a specific order
ACTARM = fct_relevel(ACTARM, "Placebo", "Xanomeline High Dose"),
RACE = fct_infreq(RACE)
%>%
) set_variable_labels(
ACTARM = "Actual treatment arm",
RACE = "Race"
)
Next, prepare an adverse event data set named ae
from admiral_ae
with the only the variables USUBJID
, AESOC
, AEDECOD
, AESEV
, AESER
, AEREL
, AESTDTC
.
Join actual treatment arm (ACTARM
) from the subjects
data frame to the ae
data.
<- admiral_ae %>%
dat_ae select(USUBJID, AESOC, AEDECOD, AESEV, AESER, AEREL, AESTDTC) %>%
left_join(dat_subjects %>% select(USUBJID, ACTARM), by = "USUBJID") %>%
# removing subjects with missing treatment arm as these were the low dose
# subjects excluded from the subjects data set
drop_na(ACTARM) %>%
mutate(
AESEV = fct_relevel(AESEV, "MILD", "MODERATE", "SEVERE"),
# converting treatment arm to factor
# note that treatment arm must be stored the same way in the two data sets
ACTARM = fct_relevel(ACTARM, "Placebo", "Xanomeline High Dose"),
year = str_sub(AESTDTC, start = 1, end = 4) %>% as.numeric()
%>%
) mutate(across(c(AESOC, AEDECOD, AESEV, AEREL), str_to_title)) %>%
# for brevity of output, only look at AEs from a single year and in
# a few SOC categories
filter(year == 2014) %>%
filter(AESOC %in% c("Eye Disorders", "Nervous System Disorders", "Skin And Subcutaneous Tissue Disorders")) %>%
::set_variable_labels(
labelledAESOC = "Primary System Organ Class",
AEDECOD = "Dictionary-Derived Term",
AESEV = "Severity/Intensity",
AEREL = "Causality"
)
Exercise 1
Create an adverse event table saved as t1
that summarizes adverse events.
Summarize the adverse events by both treatment arm and severity.
Supply
id_df
to ensure the subject denominator is correct.
Show the code solution
<- dat_ae %>%
t1 tbl_ae(
id_df = dat_subjects,
id = USUBJID,
ae = AEDECOD,
soc = AESOC,
by = AESEV,
strata = ACTARM
)
t1
Adverse Event | Placebo, N = 86 | Xanomeline High Dose, N = 72 | ||||
---|---|---|---|---|---|---|
Mild | Moderate | Severe | Mild | Moderate | Severe | |
Eye Disorders | 1 (1.2) | 1 (1.2) | — | — | — | — |
Conjunctivitis | — | 1 (1.2) | — | — | — | — |
Eye Allergy | 1 (1.2) | — | — | — | — | — |
Eye Pruritus | 1 (1.2) | — | — | — | — | — |
Eye Swelling | 1 (1.2) | — | — | — | — | — |
Nervous System Disorders | 2 (2.3) | — | — | 2 (2.8) | — | 1 (1.4) |
Burning Sensation | — | — | — | 1 (1.4) | — | — |
Dizziness | — | — | — | — | — | 1 (1.4) |
Headache | 1 (1.2) | — | — | — | — | — |
Parosmia | — | — | — | 1 (1.4) | — | — |
Psychomotor Hyperactivity | 1 (1.2) | — | — | — | — | — |
Skin And Subcutaneous Tissue Disorders | 9 (10) | 2 (2.3) | — | 7 (9.7) | 5 (6.9) | — |
Actinic Keratosis | — | — | — | 1 (1.4) | — | — |
Alopecia | 1 (1.2) | — | — | — | — | — |
Drug Eruption | 1 (1.2) | — | — | — | — | — |
Erythema | 3 (3.5) | — | — | 4 (5.6) | 2 (2.8) | — |
Hyperhidrosis | 2 (2.3) | — | — | 2 (2.8) | — | — |
Pruritus | 3 (3.5) | — | — | 6 (8.3) | 3 (4.2) | — |
Pruritus Generalised | — | — | — | 1 (1.4) | — | — |
Rash | 1 (1.2) | 2 (2.3) | — | — | 1 (1.4) | — |
Skin Irritation | — | — | — | 1 (1.4) | — | — |
Skin Odour Abnormal | — | — | — | 1 (1.4) | — | — |
Exercise 2
Create t1_modify
that modifies t1
such that:
Bold the system organ class rows.
Add an overall column to each treatment arm.
Label the overall column as
Total
.In the header, place the number of subjects on a new line in each treatment arm.
Add a table caption that states
2014 Disorders Adverse Events
(displays at the top of the table).
Show the code solution
<- t1 %>%
t1_modify bold_labels() %>%
add_overall(across = 'by') %>%
modify_header(all_overall_cols() ~ "**Total**") %>%
modify_spanning_header(all_ae_cols(TRUE, TRUE) ~ "**{strata}** \nN = {n}") %>%
modify_caption("2014 Disorders Adverse Events")
t1_modify
Adverse Event |
Placebo N = 86 |
Xanomeline High Dose N = 72 |
||||||
---|---|---|---|---|---|---|---|---|
Mild | Moderate | Severe | Total | Mild | Moderate | Severe | Total | |
Eye Disorders | 1 (1.2) | 1 (1.2) | — | 2 (2.3) | — | — | — | — |
Conjunctivitis | — | 1 (1.2) | — | 1 (1.2) | — | — | — | — |
Eye Allergy | 1 (1.2) | — | — | 1 (1.2) | — | — | — | — |
Eye Pruritus | 1 (1.2) | — | — | 1 (1.2) | — | — | — | — |
Eye Swelling | 1 (1.2) | — | — | 1 (1.2) | — | — | — | — |
Nervous System Disorders | 2 (2.3) | — | — | 2 (2.3) | 2 (2.8) | — | 1 (1.4) | 3 (4.2) |
Burning Sensation | — | — | — | — | 1 (1.4) | — | — | 1 (1.4) |
Dizziness | — | — | — | — | — | — | 1 (1.4) | 1 (1.4) |
Headache | 1 (1.2) | — | — | 1 (1.2) | — | — | — | — |
Parosmia | — | — | — | — | 1 (1.4) | — | — | 1 (1.4) |
Psychomotor Hyperactivity | 1 (1.2) | — | — | 1 (1.2) | — | — | — | — |
Skin And Subcutaneous Tissue Disorders | 9 (10) | 2 (2.3) | — | 11 (13) | 7 (9.7) | 5 (6.9) | — | 12 (17) |
Actinic Keratosis | — | — | — | — | 1 (1.4) | — | — | 1 (1.4) |
Alopecia | 1 (1.2) | — | — | 1 (1.2) | — | — | — | — |
Drug Eruption | 1 (1.2) | — | — | 1 (1.2) | — | — | — | — |
Erythema | 3 (3.5) | — | — | 3 (3.5) | 4 (5.6) | 2 (2.8) | — | 6 (8.3) |
Hyperhidrosis | 2 (2.3) | — | — | 2 (2.3) | 2 (2.8) | — | — | 2 (2.8) |
Pruritus | 3 (3.5) | — | — | 3 (3.5) | 6 (8.3) | 3 (4.2) | — | 9 (12) |
Pruritus Generalised | — | — | — | — | 1 (1.4) | — | — | 1 (1.4) |
Rash | 1 (1.2) | 2 (2.3) | — | 3 (3.5) | — | 1 (1.4) | — | 1 (1.4) |
Skin Irritation | — | — | — | — | 1 (1.4) | — | — | 1 (1.4) |
Skin Odour Abnormal | — | — | — | — | 1 (1.4) | — | — | 1 (1.4) |
Exercise 3
Create a descriptive statistics table from subjects
named t2
using tbl_reg_summary
.
Summarize the variables
AGE
,SEX
andRACE
by treatment arm (ACTARM
).Add an overall column to summarize across both treatment arms.
Bold the variable labels.
In the header, place the number of subjects on a new line in each treatment arm.
Show the code solution
<- dat_subjects %>%
t2 select(-USUBJID) %>%
tbl_reg_summary(
by = ACTARM
%>%
) add_overall(last = TRUE) %>%
bold_labels() %>%
modify_header(
list(
all_stat_cols(stat_0 = FALSE) ~ "**{level}** \nN = {n}",
~ "**Overall** \nN = {N}"
stat_0
))
t2
Characteristic | Placebo N = 861 |
Xanomeline High Dose N = 721 |
Overall N = 1581 |
---|---|---|---|
Age | |||
N | 86 | 72 | 158 |
Mean (SD) | 75 (9) | 74 (8) | 75 (8) |
Median (IQR) | 76 (69, 82) | 76 (70, 79) | 76 (69, 81) |
Range | 52, 89 | 56, 88 | 52, 89 |
N missing | 0 | 0 | 0 |
Sex | |||
F | 53 (62%) | 35 (49%) | 88 (56%) |
M | 33 (38%) | 37 (51%) | 70 (44%) |
Race | |||
White | 78 (91%) | 62 (86%) | 140 (89%) |
Black Or African American | 8 (9.3%) | 9 (12%) | 17 (11%) |
American Indian Or Alaska Native | 0 (0%) | 1 (1.4%) | 1 (0.6%) |
1 n (%) |
Exercise 4
Create a grouped table listing of adverse events named t3
.
Display only events of
Probable
causality.Sort events by system organ class and term.
Print subject id, term, and whether or not the event was serious.
Group listings by system organ class.
Bold system organ class labels.
Show the code solution
<- dat_ae %>%
dat_list filter(AEREL == "Probable") %>%
select(USUBJID, AESOC, AEDECOD, AESER) %>%
arrange(AESOC, AEDECOD)
<- dat_list %>%
t3 tbl_listing(
group_by = AESOC
%>%
) bold_labels()
t3
Unique Subject Identifier | Dictionary-Derived Term | Serious Event |
---|---|---|
Nervous System Disorders | ||
01-704-1332 | Burning Sensation | N |
Skin And Subcutaneous Tissue Disorders | ||
01-704-1074 | Erythema | N |
01-708-1158 | Erythema | N |
01-714-1288 | Erythema | N |
01-716-1177 | Erythema | N |
01-716-1441 | Erythema | N |
01-716-1447 | Erythema | N |
01-704-1074 | Pruritus | N |
01-704-1332 | Pruritus | N |
01-704-1332 | Pruritus | N |
01-716-1447 | Pruritus | N |
01-717-1109 | Pruritus Generalised | N |
01-709-1306 | Rash | N |
01-709-1306 | Rash | N |
01-709-1306 | Rash | N |
01-717-1109 | Skin Irritation | N |
Exercise 5
Create t2_shell
, a table shell from the t2
table. This is the exact same format as t2
, except with numeric values replaced by xx
.
Show the code solution
<- dat_subjects %>%
t2_shell select(-USUBJID) %>%
tbl_reg_summary(
digits = everything() ~ style_xxx,
by = ACTARM
%>%
) add_overall(last = TRUE) %>%
bold_labels() %>%
modify_header(
list(
all_stat_cols(stat_0 = FALSE) ~ "**{level}** \nN = xx",
~ "**Overall** \nN = xx"
stat_0
))
t2_shell
Characteristic | Placebo N = xx1 |
Xanomeline High Dose N = xx1 |
Overall N = xx1 |
---|---|---|---|
Age | |||
N | xx | xx | xx |
Mean (SD) | xx (xx) | xx (xx) | xx (xx) |
Median (IQR) | xx (xx, xx) | xx (xx, xx) | xx (xx, xx) |
Range | xx, xx | xx, xx | xx, xx |
N missing | xx | xx | xx |
Sex | |||
F | xx (xx%) | xx (xx%) | xx (xx%) |
M | xx (xx%) | xx (xx%) | xx (xx%) |
Race | |||
White | xx (xx%) | xx (xx%) | xx (xx%) |
Black Or African American | xx (xx%) | xx (xx%) | xx (xx%) |
American Indian Or Alaska Native | xx (xx%) | xx (xx%) | xx (xx%) |
1 n (%) |
Exercise 6
Export t2_shell
to either word or excel.
Show the code solution
%>%
t2_shell as_hux_xlsx(
file = "output/summary_shell.xlsx"
)
Show the code solution
%>%
t2_shell as_flex_table() %>%
::save_as_docx(path = "output/summary_shell.docx") flextable
Session info
::session_info() devtools
─ Session info ───────────────────────────────────────────────────────────────
setting value
version R version 4.2.1 (2022-06-23 ucrt)
os Windows 10 x64 (build 19042)
system x86_64, mingw32
ui RTerm
language (EN)
collate English_United States.utf8
ctype English_United States.utf8
tz America/New_York
date 2022-11-01
pandoc 2.18 @ C:/Program Files/RStudio/bin/quarto/bin/tools/ (via rmarkdown)
─ Packages ───────────────────────────────────────────────────────────────────
! package * version date (UTC) lib source
P admiral * 0.8.4 2022-10-14 [?] CRAN (R 4.2.1)
P admiral.test * 0.3.0 2022-09-01 [?] CRAN (R 4.2.1)
P admiraldev 0.1.0 2022-08-26 [?] CRAN (R 4.2.1)
P assertthat 0.2.1 2019-03-21 [?] CRAN (R 4.1.1)
P backports 1.4.1 2021-12-13 [?] CRAN (R 4.2.0)
P broom 1.0.1 2022-08-29 [?] CRAN (R 4.2.1)
P broom.helpers 1.9.0 2022-09-23 [?] CRAN (R 4.2.1)
P cachem 1.0.6 2021-08-19 [?] CRAN (R 4.1.1)
P callr 3.7.2 2022-08-22 [?] CRAN (R 4.2.1)
P cellranger 1.1.0 2016-07-27 [?] CRAN (R 4.1.1)
P cli 3.4.1 2022-09-23 [?] CRAN (R 4.2.1)
P colorspace 2.0-3 2022-02-21 [?] CRAN (R 4.2.0)
P commonmark 1.8.1 2022-10-14 [?] CRAN (R 4.2.1)
P crayon 1.5.2 2022-09-29 [?] CRAN (R 4.2.1)
P DBI 1.1.3 2022-06-18 [?] RSPM (R 4.2.0)
P dbplyr 2.2.1 2022-06-27 [?] RSPM (R 4.2.0)
P devtools 2.4.5 2022-10-11 [?] CRAN (R 4.2.0)
P digest 0.6.29 2021-12-01 [?] CRAN (R 4.2.0)
P dplyr * 1.0.10 2022-09-01 [?] CRAN (R 4.2.1)
P ellipsis 0.3.2 2021-04-29 [?] CRAN (R 4.2.0)
P evaluate 0.17 2022-10-07 [?] CRAN (R 4.2.1)
P fansi 1.0.3 2022-03-24 [?] CRAN (R 4.2.0)
P fastmap 1.1.0 2021-01-25 [?] CRAN (R 4.2.0)
P forcats * 0.5.2 2022-08-19 [?] CRAN (R 4.2.1)
P fs 1.5.2 2021-12-08 [?] CRAN (R 4.1.2)
P gargle 1.2.1 2022-09-08 [?] CRAN (R 4.2.1)
P generics 0.1.3 2022-07-05 [?] RSPM (R 4.2.0)
P ggplot2 * 3.3.6 2022-05-03 [?] CRAN (R 4.2.0)
P glue 1.6.2 2022-02-24 [?] CRAN (R 4.1.3)
P googledrive 2.0.0 2021-07-08 [?] CRAN (R 4.1.1)
P googlesheets4 1.0.1 2022-08-13 [?] CRAN (R 4.2.1)
P gt 0.7.0 2022-08-25 [?] CRAN (R 4.2.0)
P gtable 0.3.1 2022-09-01 [?] CRAN (R 4.2.1)
P gtreg * 0.2.0 2022-10-18 [?] CRAN (R 4.2.1)
P gtsummary * 1.6.2 2022-09-30 [?] CRAN (R 4.2.1)
P haven 2.5.1 2022-08-22 [?] CRAN (R 4.2.1)
P hms 1.1.2 2022-08-19 [?] CRAN (R 4.2.1)
P htmltools 0.5.3 2022-07-18 [?] RSPM (R 4.2.0)
P htmlwidgets 1.5.4 2021-09-08 [?] CRAN (R 4.1.1)
P httpuv 1.6.6 2022-09-08 [?] CRAN (R 4.2.1)
P httr 1.4.4 2022-08-17 [?] CRAN (R 4.2.1)
P jsonlite 1.8.2 2022-10-02 [?] CRAN (R 4.2.1)
P knitr 1.40 2022-08-24 [?] CRAN (R 4.2.1)
P labelled * 2.10.0 2022-09-14 [?] CRAN (R 4.2.1)
P later 1.3.0 2021-08-18 [?] CRAN (R 4.1.1)
P lifecycle 1.0.3 2022-10-07 [?] CRAN (R 4.2.1)
P lubridate 1.8.0 2021-10-07 [?] CRAN (R 4.2.0)
P magrittr 2.0.3 2022-03-30 [?] CRAN (R 4.2.0)
P memoise 2.0.1 2021-11-26 [?] CRAN (R 4.2.1)
P mime 0.12 2021-09-28 [?] CRAN (R 4.2.0)
P miniUI 0.1.1.1 2018-05-18 [?] CRAN (R 4.2.1)
P modelr 0.1.9 2022-08-19 [?] CRAN (R 4.2.1)
P munsell 0.5.0 2018-06-12 [?] CRAN (R 4.1.1)
P pillar 1.8.1 2022-08-19 [?] CRAN (R 4.2.1)
P pkgbuild 1.3.1 2021-12-20 [?] CRAN (R 4.2.1)
P pkgconfig 2.0.3 2019-09-22 [?] CRAN (R 4.1.1)
P pkgload 1.3.0 2022-06-27 [?] CRAN (R 4.2.1)
P prettyunits 1.1.1 2020-01-24 [?] CRAN (R 4.1.1)
P processx 3.7.0 2022-07-07 [?] RSPM (R 4.2.0)
P profvis 0.3.7 2020-11-02 [?] CRAN (R 4.2.1)
P promises 1.2.0.1 2021-02-11 [?] CRAN (R 4.1.1)
P ps 1.7.1 2022-06-18 [?] RSPM (R 4.2.0)
P purrr * 0.3.5 2022-10-06 [?] CRAN (R 4.2.0)
P R6 2.5.1 2021-08-19 [?] CRAN (R 4.2.0)
Rcpp 1.0.9 2022-07-08 [1] CRAN (R 4.2.1)
P readr * 2.1.3 2022-10-01 [?] CRAN (R 4.2.1)
P readxl 1.4.1 2022-08-17 [?] CRAN (R 4.2.1)
P remotes 2.4.2 2021-11-30 [?] CRAN (R 4.2.1)
renv 0.16.0 2022-09-29 [1] CRAN (R 4.2.1)
P reprex 2.0.2 2022-08-17 [?] CRAN (R 4.2.1)
P rlang 1.0.6 2022-09-24 [?] CRAN (R 4.2.1)
P rmarkdown 2.17 2022-10-07 [?] CRAN (R 4.2.1)
P rstudioapi 0.14 2022-08-22 [?] CRAN (R 4.2.1)
P rvest 1.0.3 2022-08-19 [?] CRAN (R 4.2.1)
P sass 0.4.2 2022-07-16 [?] RSPM (R 4.2.0)
P scales 1.2.1 2022-08-20 [?] CRAN (R 4.2.1)
P sessioninfo 1.2.2 2021-12-06 [?] CRAN (R 4.2.1)
P shiny 1.7.2 2022-07-19 [?] CRAN (R 4.2.1)
P stringi 1.7.8 2022-07-11 [?] RSPM (R 4.2.0)
P stringr * 1.4.1 2022-08-20 [?] CRAN (R 4.2.1)
P tibble * 3.1.8 2022-07-22 [?] RSPM (R 4.2.0)
P tidyr * 1.2.1 2022-09-08 [?] CRAN (R 4.2.0)
P tidyselect 1.2.0 2022-10-10 [?] CRAN (R 4.2.1)
P tidyverse * 1.3.2 2022-07-18 [?] RSPM (R 4.2.0)
P tzdb 0.3.0 2022-03-28 [?] CRAN (R 4.2.0)
P urlchecker 1.0.1 2021-11-30 [?] CRAN (R 4.2.1)
P usethis 2.1.6 2022-05-25 [?] CRAN (R 4.2.1)
P utf8 1.2.2 2021-07-24 [?] CRAN (R 4.1.1)
P vctrs 0.4.2 2022-09-29 [?] CRAN (R 4.2.1)
P withr 2.5.0 2022-03-03 [?] CRAN (R 4.2.0)
P xfun 0.33 2022-09-12 [?] CRAN (R 4.2.1)
P xml2 1.3.3 2021-11-30 [?] CRAN (R 4.2.0)
P xtable 1.8-4 2019-04-21 [?] CRAN (R 4.1.1)
P yaml 2.3.6 2022-10-18 [?] CRAN (R 4.2.1)
[1] C:/Users/pileggis/Documents/gh-personal/gtreg-workshop-rinpharma-2022/renv/library/R-4.2/x86_64-w64-mingw32
[2] C:/Users/pileggis/AppData/Local/Temp/RtmpO65FZZ/renv-system-library
P ── Loaded and on-disk path mismatch.
──────────────────────────────────────────────────────────────────────────────