Exercises

Exercises

00-warmup.R

# Let's warm-up! 
 
library(dplyr) 
 
# Using dplyr: 
#  - From the ADSL dataset: 
#   - Subset to the safety population (SAFFL == "Y") 
#   - calculate the number of unique subjects in each treatment group (TRT01A)   
 
pharmaverseadam::adsl |>  
  filter(   ) |>  
  count(   ) 

01-cards-partA.R

# ARD Exercise: Demographic summaries using {cards} 
 
# For this exercise, compute all the necessary summaries for a demographics table that includes age, age group, sex, race, ethnicity, bmi, height, and weight. We want to compute these summaries within each treatment group (High Dose, Low Dose, Placebo) and overall. 
 
# Setup 
## Load necessary packages 
library(cards) 
library(dplyr) 
library(tidyr) 
 
## Import data 
adsl <- pharmaverseadam::adsl |> 
  filter(SAFFL == "Y") |> 
  left_join( 
    pharmaverseadam::advs |> 
      filter(PARAMCD %in% c("BMI", "HEIGHT", "WEIGHT"), !is.na(AVAL)) |> 
      group_by(USUBJID, PARAMCD) |> 
      arrange(ADY) |> 
      slice(1) |> 
      ungroup() |> 
      select(USUBJID, PARAMCD, AVAL) |> 
      pivot_wider(names_from = PARAMCD, values_from = AVAL), 
    by = "USUBJID" 
  ) 
 
##  A. First, compute the continuous summaries for AGE, BMI, HEIGHT, WEIGHT by TRT01A 
 
ard_continuous( 
  data = adsl, 
  by = , 
  variables = 
) 
 
 
##  B. Next, compute the categorical summaries for AGEGR1, SEX, RACE, ETHNIC by TRT01A 
 
ard_categorical( 
  data = adsl, 
  by = , 
  variables = 
) 
 
## C. Perform all of the summaries in a single ard_stack() call, including: 
#   - summaries by TRT01A as performed above 
#      - continuous summaries from part A for AGE, BMI, HEIGHT, and WEIGHT 
#      - categorical summaries from part B for AGEGR1, SEX, RACE, ETHNIC 
ard_stack( 
  data = adsl, 
  .by = , 
 
  # add ard_* calls here 
 
) 
 
 
## D. BONUS! 
#   For part C. above, add the following pieces 
#   - overall summaries for all of the variables 
#   - total N 
# (Hint: Modify the `.overall` and `.total_n` arguments, respectively) 
 

01-cards-partB.R

# Exercise: Adverse Events summaries using {cards} 
 
# Load necessary packages 
library(cards)  
 
# Import data 
adsl <- pharmaverseadam::adsl |> dplyr::filter(SAFFL == "Y") 
adae <- pharmaverseadam::adae  
 
# Exercise: 
 
# A. Calculate the number and percentage of *unique* subjects with at least one AE: 
#  - Overall 
#  - By each SOC (AESOC) 
#  - By each Preferred term (AEDECOD) within SOC (AESOC) 
# By every combination of treatment group (TRT01A) and severity (AESEV) 
 
ard_stack_hierarchical( 
  data = , 
  variables = , 
  by = ,  
  id = , 
  denominator = , 
  over_variables =  
)  

02-cardx.R

# ARD Exercise: Demographic comparison with {cardx} 
 
# In a previous exercise, you calculated summary deomgraphic statistics by treament arm 
# Here, we will use a subset of those variables, and compare their values across treatment arms 
# Variables: AGE, SEX, RACE 
# Treatment variable: TRT01A 
 
# Compare AGE with the Kruskal-Wallis test and SEX and AGE with Pearson's Chi-square test 
# DISCLAIMER: Don't compare baseline characteristics in randomized trials in real life! 
 
 
# Setup 
 
## Import data 
adsl <- pharmaverseadam::adsl |> dplyr::filter(SAFFL == "Y") 
 
##  A. First, compute the Kruskal-Wallis test for AGE by TRT01A 
kruskal_ard <-  
  cardx::ard_stats_kruskal_test( 
    data = ,  
    by = , 
    variables =  
  ) 
 
##  B. First, compute the Chi-squared test for SEX, RACE by TRT01A 
chisq_ard <-  
  cardx::ard_stats_chisq_test( 
    data = ,  
    by = , 
    variables =  
  ) 
   
##  C. Combine your results with `cards::bind_ard()` and subset the ARD to include the rows with p-values only 
final_ard <-  
  cards::bind_ard( 
 
  ) |>  
  dplyr::filter() 
 
##  Bonus. Which test returned a warning? If any, print the warning.  
##         Note that the warning column is a list-column which requires special handling 
 
 
 

03-gtsummary-partA.R

# ARD Exercise: Demographic summary table using {gtsummary} 
 
# For this exercise, create a summary table using `tbl_summary()` 
#   1. Split summary statistics by TRT01A 
#   2. Include AGE, SEX, and RACE. For AGE, display the "mean (sd)" and "median (p25, p75)" on separate rows 
#      HINT: Use `type = AGE ~ 'continuous2'` and `statistic = AGE ~ c("{mean} ({sd})", "{median} ({p25}, {p75})")` 
#   3. Include a column of overall results using `add_overall()` 
#   BONUS: Use `cards::gather_ard()` to extract the ARD from the table object 
 
# Setup 
## Import data 
library(gtsummary) 
adsl <- pharmaverseadam::adsl |> dplyr::filter(SAFFL == "Y") 
 
# Create table 
tbl <- adsl |>  
  tbl_summary( 
    by = , 
    include = , 
    type = , 
    statistic =  
  ) |>  
  add_overall() 
tbl 
 
# Extract ARD from tbl object 

03-gtsummary-partB.R

# ARD Exercise: Demographic summary table using {cards}+{gtsummary} 
 
# For this exercise, create a summary table using `tbl_ard_summary()` 
#   1. Split summary statistics by TRT01A 
#   2. Include AGE, SEX, and RACE. For AGE, display the "mean (sd)" and "median (p25, p75)" on separate rows 
#      HINT: Use `type = AGE ~ 'continuous2'` and `statistic = AGE ~ c("{mean} ({sd})", "{median} ({p25}, {p75})")` 
#   3. Include a column of overall results using `tbl_ard_summary(overall=TRUE)` 
 
# Setup 
## Import data 
library(cards) 
library(gtsummary) 
adsl <- pharmaverseadam::adsl |> dplyr::filter(SAFFL == "Y") 
 
# Create the ARD with the needed statistics 
ard <-  
  ard_stack( 
    adsl, 
    .by = TRT01A, 
    ard_continuous(variables = AGE), 
    ard_categorical(variables = c(SEX, RACE)), 
    .attributes = TRUE,  
    .overall = TRUE 
  ) 
 
# Create table 
ard |>  
  tbl_ard_summary( 
    by = , 
    include = , 
    type = , 
    statistic = , 
    overall =  
  ) 

04-tables-tfrmt.R

  
# Setup - Modifying a table with {tfrmtbuilder} -------------------------------- 
 
# Load libraries 
library(tfrmtbuilder) 
library(tfrmt) 
 
# Import ARD and tfrmt 
ard_demog <- readRDS("exercises/data/ard_demog.rds") 
tfrmt_demog <- json_to_tfrmt("exercises/data/tfrmt_demog.json") 
 
# Run app  
tfrmtbuilder( 
  tfrmt = tfrmt_demog, 
  data = ard_demog, 
  mockmode = FALSE # to create table with values 
) 
 
# Exercise - Modifying a table with {tfrmtbuilder} ----------------------------- 
 
# 1.  Switch the order of treatment columns so Active is first 
#      (hint: Column Plan) 
 
# 2. Change the footnote marks to letters instead of numbers 
#      (hint: Footnote Plan) 
 
# 3. Split the table into 2 parts by setting a maximum of 3 rows 
#      (hint: Page Plan) 
  
# 4. Export table (hint: Export tab) 
 
 

Solutions

00-warmup-answer-answer.R

# Let's warm-up! 
 
library(dplyr) 
 
# Using dplyr: 
#  - From the ADSL dataset: 
#   - Subset to the safety population (SAFFL == "Y") 
#   - calculate the number of unique subjects in each treatment group (TRT01A)   
 
pharmaverseadam::adsl |>  
  filter(SAFFL == "Y") |>  
  count(TRT01A) 

01-cards-partA-answer.R

# ARD Exercise: Demographic summaries using {cards} 
 
# For this exercise, compute all the necessary summaries for a demographics table that includes age, age group, sex, race, ethnicity, bmi, height, and weight. We want to compute these summaries within each treatment group (High Dose, Low Dose, Placebo) and overall. 
 
# Setup 
## Load necessary packages 
library(cards) 
library(dplyr) 
library(tidyr) 
 
## Import data 
adsl <- pharmaverseadam::adsl |> 
  filter(SAFFL == "Y") |> 
  left_join( 
    pharmaverseadam::advs |> 
      filter(PARAMCD %in% c("BMI", "HEIGHT", "WEIGHT"), !is.na(AVAL)) |> 
      group_by(USUBJID, PARAMCD) |> 
      arrange(ADY) |> 
      slice(1) |> 
      ungroup() |> 
      select(USUBJID, PARAMCD, AVAL) |> 
      pivot_wider(names_from = PARAMCD, values_from = AVAL), 
    by = "USUBJID" 
  ) 
 
##  A. First, compute the continuous summaries for AGE, BMI, HEIGHT, WEIGHT by TRT01A 
 
ard_continuous( 
  data = adsl, 
  by = TRT01A, 
  variables = c(AGE, BMI, HEIGHT, WEIGHT) 
) 
 
 
##  B. Next, compute the categorical summaries for AGEGR1, SEX, RACE, ETHNIC by TRT01A 
 
ard_categorical( 
  data = adsl, 
  by = TRT01A, 
  variables = c(AGEGR1, SEX, RACE, ETHNIC) 
) 
 
## C. Perform all of the summaries in a single ard_stack() call, including: 
#   - summaries by TRT01A as performed above 
#      - continuous summaries from part A for AGE, BMI, HEIGHT, and WEIGHT 
#      - categorical summaries from part B for AGEGR1, SEX, RACE, ETHNIC 
ard_stack( 
  data = adsl, 
  .by = TRT01A, 
  ard_continuous( variables = c(AGE, BMI, HEIGHT, WEIGHT)), 
  ard_categorical(variables = c(AGEGR1, SEX, RACE, ETHNIC)) 
) 
 
 
## D. BONUS! 
#   For part C. above, add the following pieces 
#   - overall summaries for all of the variables 
#   - total N 
# (Hint: Modify the `.overall` and `.total_n` arguments, respectively) 
ard_stack( 
  data = adsl, 
  .by = TRT01A, 
  ard_continuous( variables = c(AGE, BMI, HEIGHT, WEIGHT)), 
  ard_categorical(variables = c(AGEGR1, SEX, RACE, ETHNIC)),  
  .overall = TRUE, 
  .total_n = TRUE 
) 
 

01-cards-partB-answer.R

# Exercise: Adverse Events summaries using {cards} 
 
# Load necessary packages 
library(cards)  
 
# Import data 
adsl <- pharmaverseadam::adsl |> dplyr::filter(SAFFL == "Y") 
adae <- pharmaverseadam::adae  
 
## A.  Calculate the number and percentage of *unique* subjects (USUBJID) with at least one AE: 
#  - Overall 
#  - By each SOC (AESOC) 
#  - By each Preferred term (AEDECOD) within SOC (AESOC) 
# By every combination of treatment group (TRT01A) and severity (AESEV) 
 
ard_stack_hierarchical( 
  data = adae, 
  variables = c(AESOC, AEDECOD), 
  by = c(TRT01A, AESEV),  
  id = USUBJID, 
  denominator = adsl, 
  over_variables = TRUE 
) 
  

02-cardx-answer.R

# ARD Exercise: Demographic comparison with {cardx} 
 
# In a previous exercise, you calculated summary deomgraphic statistics by treament arm 
# Here, we will use a subset of those variables, and compare their values across treatment arms 
# Variables: AGE, SEX, RACE 
# Treatment variable: TRT01A 
 
# Compare AGE with the Kruskal-Wallis test and SEX and AGE with Pearson's Chi-square test 
# DISCLAIMER: Don't compare baseline characteristics in randomized trials in real life! 
 
 
# Setup 
 
## Import data 
adsl <- pharmaverseadam::adsl |> dplyr::filter(SAFFL == "Y") 
 
##  A. First, compute the Kruskal-Wallis test for AGE by TRT01A 
kruskal_ard <-  
  cardx::ard_stats_kruskal_test( 
    data = adsl,  
    by = TRT01A, 
    variables = AGE 
  ) 
 
##  B. First, compute the Chi-squared test for SEX, RACE by TRT01A 
chisq_ard <-  
  cardx::ard_stats_chisq_test( 
    data = adsl,  
    by = TRT01A, 
    variables = c(SEX, RACE) 
  ) 
   
##  C. Combine your results with `cards::bind_ard()` and subset the ARD to include the rows with p-values only 
final_ard <-  
  cards::bind_ard( 
    kruskal_ard,  
    chisq_ard 
  ) |>  
  dplyr::filter(stat_name == "p.value") 
 
##  Bonus. Which test returned a warning? If any, print the warning.  
##         Note that the warning column is a list-column which requires special handling 
final_ard |> cards::print_ard_conditions() 
 
final_ard |> 
  dplyr::filter(purrr::map_lgl(warning, Negate(is.null))) |>  
  as.data.frame() 
 
 

03-gtsummary-partA-answer.R

# ARD Exercise: Demographic summary table using {gtsummary} 
 
# For this exercise, create a summary table using `tbl_summary()` 
#   1. Split summary statistics by TRT01A 
#   2. Include AGE, SEX, and RACE. For AGE, display the "mean (sd)" and "median (p25, p75)" on separate rows 
#      HINT: Use `type = AGE ~ 'continuous2'` and `statistic = AGE ~ c("{mean} ({sd})", "{median} ({p25}, {p75})")` 
#   3. Include a column of overall results using `add_overall()` 
#   BONUS: Use `cards::gather_ard()` to extract the ARD from the table object 
 
# Setup 
## Import data 
library(gtsummary) 
adsl <- pharmaverseadam::adsl |> dplyr::filter(SAFFL == "Y") 
 
# Create table 
tbl <- adsl |>  
  tbl_summary( 
    by = TRT01A, 
    include = c(AGE, SEX, RACE), 
    type = AGE ~ 'continuous2', 
    statistic = AGE ~ c("{mean} ({sd})", "{median} ({p25}, {p75})") 
  ) |>  
  add_overall() 
tbl 
 
# Extract ARD from tbl object 
gather_ard(tbl) 

03-gtsummary-partB-answer.R

# ARD Exercise: Demographic summary table using {cards}+{gtsummary} 
 
# For this exercise, create a summary table using `tbl_ard_summary()` 
#   1. Split summary statistics by TRT01A 
#   2. Include AGE, SEX, and RACE. For AGE, display the "mean (sd)" and "median (p25, p75)" on separate rows 
#      HINT: Use `type = AGE ~ 'continuous2'` and `statistic = AGE ~ c("{mean} ({sd})", "{median} ({p25}, {p75})")` 
#   3. Include a column of overall results using `tbl_ard_summary(overall=TRUE)` 
 
# Setup 
## Import data 
library(cards) 
library(gtsummary) 
adsl <- pharmaverseadam::adsl |> dplyr::filter(SAFFL == "Y") 
 
# Create the ARD with the needed statistics 
ard <-  
  ard_stack( 
    adsl, 
    .by = TRT01A, 
    ard_continuous(variables = AGE), 
    ard_categorical(variables = c(SEX, RACE)), 
    .attributes = TRUE,  
    .overall = TRUE 
  ) 
 
# Create table 
ard |>  
  tbl_ard_summary( 
    by = TRT01A, 
    include = c(AGE, SEX, RACE), 
    type = AGE ~ 'continuous2', 
    statistic = AGE ~ c("{mean} ({sd})", "{median} ({p25}, {p75})"), 
    overall = TRUE 
  )