From 3e47c1d749af4c9bb847cc4cf4eeb5f50e0eed92 Mon Sep 17 00:00:00 2001 From: ayogasekaram Date: Mon, 25 Nov 2024 19:52:42 +0000 Subject: [PATCH 1/2] tbl_ard*() article draft --- vignettes/articles/tbl_ard-functions.Rmd | 125 +++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 vignettes/articles/tbl_ard-functions.Rmd diff --git a/vignettes/articles/tbl_ard-functions.Rmd b/vignettes/articles/tbl_ard-functions.Rmd new file mode 100644 index 000000000..cad440df8 --- /dev/null +++ b/vignettes/articles/tbl_ard-functions.Rmd @@ -0,0 +1,125 @@ +--- +title: "Building Tables using tbl_ard*()" +--- + +```{r, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) +``` + +For most tables built using {gtsummary}, ARDs for quality control or table summaries can be extracted. However, there are instances where an ARD first approach is beneficial as building more complex tables may require analysis of the data structures prior to table construction. For this ARD first approach, {gtsummary} has `tbl_ard*()` functions that will generate a tables. + +- `tbl_ard_continuous()` - for ARDs summarizing continuous variables. +- `tbl_ard_hierarchical()` - for ARDs containing nested or hierarchical data structures. +- `tbl_ard_summary()` - for ARDs with descriptive statistics for continuous, categorical and dichotomous variables. +- `tbl_ard_wide_summary()` - for ARD statistics represented in a wide table format - in separate columns. + +### Building a basic demographics table + +In this example, we will build a simple demographics and baseline characteristics table as outlined in the FDA Standard Safety Tables Guidelines. + +This table has three types of data summaries: a continuous variable summary for AGE, a categorical variable summary for AGEGR1, RACE, and ETHNIC and a dichotomous variable summary for SEX. + +```{r} +library(gtsummary) +library(cards) + +# summarizing both continuous and categorical variables, consolidate using ard_stack call +ard_stack( + data = cards::ADSL, + .by = ARM, + ard_categorical(variables = c("AGEGR1", "RACE", "SEX", "ETHNIC")), + ard_continuous(variables = "AGE"), + .attributes = TRUE, + .missing = TRUE, + .total_n = TRUE, + .overall = TRUE # generate ard with overall column included + ) |> # pass to tbl_ard_summary to generate a table. + tbl_ard_summary(by = ARM, overall = TRUE) # pass ard to table building function with the overall argument. + +``` + +Notice this ARD first approach builds an equivalent table to one built with `tbl_summary()` + +```{r} + +cards::ADSL |> + select(c("AGEGR1", "RACE", "SEX", "ETHNIC", "AGE", "ARM")) |> + tbl_summary(by = ARM) |> + add_overall() + +``` +The ARD for this table can be extracted using the `gather_ard()` function. + +### Building a disposition table +Here, we use tbl_ard_wide_summary to build a Pooled disposition table. + +```{r} +# all variables within tbl_ard_wide_summary must be the same summary type +ard_stack( + trial, + ard_dichotomous(variables = response), + ard_categorical(variables = grade), + .missing = TRUE, + .attributes = TRUE, + .total_n = TRUE +) |> + tbl_ard_wide_summary() +``` + +### Building an Adverse Events table + +For tables that require hierarchical or nested analysis, `ard_stack_hierarchical()` is recommended for building an ARD. The companion function for rendering the table using the ARD is `tbl_ard_hierarchical()` + +```{r} +# Adverse Events Rates Table + +ADAE_subset <- cards::ADAE |> + dplyr::filter( + AESOC %in% unique(cards::ADAE$AESOC)[1:5], + AETERM %in% unique(cards::ADAE$AETERM)[1:5]) + +ard <- cards::ard_stack_hierarchical( + data = ADAE_subset, + variables = c(AESOC, AETERM), + by = TRTA, + denominator = cards::ADSL|> mutate(TRT01A = ARM), + id = USUBJID + ) + +tbl_ard_hierarchical( + cards = ard, + variables = c(AESOC, AETERM), + by = TRTA + ) + +``` + +### Complex Analysis Tables + +The ARD to Table pipeline is most convenient when trying to consolidate multiple analysis steps into an ARD to feed only the relevant stats to the table building machinery. In the example below, we create ARDs that compute the survival probabilities of both treatment groups, and also conduct a one sample t-test on the survival estimates. The resulting ARD is filtered to only contain the relevant estimate values which can be used generate the table we want. Note that in this pipeline, all the survival analysis stats such as confidence intervals and and standard error are retained in the ARD object - enabling reuse of this object to generate other tables. + +```{r setup} + +library(gtsummary) +library(cardx) + +ard <- cards::bind_ard( + survival::survfit(survival::Surv(ttdeath, death) ~ trt, trial) |> + cardx::ard_survival_survfit(times = c(12, 24)) |> + dplyr::filter(stat_name %in% c("estimate")) |> # filtering only the survival probability values. + dplyr::mutate( # apply custom formatting to these values - 1 decimal place + fmt_fn = list("xx.x%"), + group1_level = unlist(group1_level) |> as.character() |> as.list() + ), + # run a one sample t-test between the means of the survival probability for each treatment group + cardx::ard_stats_t_test_onesample(trial, variables = age, by = trt) |> + dplyr::filter(stat_name %in% c("estimate")) + ) |> + dplyr::select(-cards::all_missing_columns()) + +tbl_ard_summary(ard, by = trt, statistic = ~ "{estimate}") + +``` From bc3b781f7742d71e71ec10344aa16ce07658845a Mon Sep 17 00:00:00 2001 From: ayogasekaram Date: Wed, 27 Nov 2024 21:09:16 +0000 Subject: [PATCH 2/2] address comments from review --- vignettes/articles/tbl_ard-functions.Rmd | 25 +++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/vignettes/articles/tbl_ard-functions.Rmd b/vignettes/articles/tbl_ard-functions.Rmd index cad440df8..d32860446 100644 --- a/vignettes/articles/tbl_ard-functions.Rmd +++ b/vignettes/articles/tbl_ard-functions.Rmd @@ -9,12 +9,14 @@ knitr::opts_chunk$set( ) ``` -For most tables built using {gtsummary}, ARDs for quality control or table summaries can be extracted. However, there are instances where an ARD first approach is beneficial as building more complex tables may require analysis of the data structures prior to table construction. For this ARD first approach, {gtsummary} has `tbl_ard*()` functions that will generate a tables. +For most tables built using {gtsummary}, ARDs for quality control or table summaries can be extracted. +However, there are instances where an ARD first approach is beneficial as building more complex tables may require analysis of the data structures prior to table construction. +For this ARD first approach, {gtsummary} has `tbl_ard*()` functions that will generate a tables. - `tbl_ard_continuous()` - for ARDs summarizing continuous variables. -- `tbl_ard_hierarchical()` - for ARDs containing nested or hierarchical data structures. - `tbl_ard_summary()` - for ARDs with descriptive statistics for continuous, categorical and dichotomous variables. - `tbl_ard_wide_summary()` - for ARD statistics represented in a wide table format - in separate columns. +- `tbl_ard_hierarchical()` - for ARDs containing nested or hierarchical data structures. ### Building a basic demographics table @@ -22,6 +24,11 @@ In this example, we will build a simple demographics and baseline characteristic This table has three types of data summaries: a continuous variable summary for AGE, a categorical variable summary for AGEGR1, RACE, and ETHNIC and a dichotomous variable summary for SEX. +There are three additional arguments that can be specified to improve the appearance of the table. +- `.attributes` the default labels will be the variable labels if attributes are included. +- `.missing` when missing results are included, users can include missing counts or rates for the variables. +- `.total_n` the total N is saved internally when available. + ```{r} library(gtsummary) library(cards) @@ -67,7 +74,16 @@ ard_stack( .total_n = TRUE ) |> tbl_ard_wide_summary() + ``` +Notice the extracted ARD from `tbl_ard_summary()` (using `gather_ard()`) is equivalent to the ARD built using `tbl_ard_wide_summary()`. +```{r} +trial |> + select(response, grade) |> +tbl_summary(missing = 'no') |> + gather_ard() +``` + ### Building an Adverse Events table @@ -99,7 +115,10 @@ tbl_ard_hierarchical( ### Complex Analysis Tables -The ARD to Table pipeline is most convenient when trying to consolidate multiple analysis steps into an ARD to feed only the relevant stats to the table building machinery. In the example below, we create ARDs that compute the survival probabilities of both treatment groups, and also conduct a one sample t-test on the survival estimates. The resulting ARD is filtered to only contain the relevant estimate values which can be used generate the table we want. Note that in this pipeline, all the survival analysis stats such as confidence intervals and and standard error are retained in the ARD object - enabling reuse of this object to generate other tables. +The ARD to Table pipeline is most convenient when trying to consolidate multiple analysis steps into an ARD to feed only the relevant stats to the table building machinery. +In the example below, we create ARDs that compute the survival probabilities of both treatment groups, and also conduct a one sample t-test on the survival estimates. +The resulting ARD is filtered to only contain the relevant estimate values which can be used generate the table we want. +Note that in this pipeline, all the survival analysis stats such as confidence intervals and and standard error are retained in the ARD object - enabling reuse of this object to generate other tables. ```{r setup}