From 867534c1d34552d0f75d26c5ad7308be664264e7 Mon Sep 17 00:00:00 2001 From: Daniel Sjoberg Date: Thu, 12 Sep 2024 21:37:05 -0700 Subject: [PATCH 01/14] Adding gtsummary demographics example --- tlg/demographic.R | 89 +++++++++++++++++++++++------- tlg/demographic.qmd | 129 ++++++++++++++++++++++++++++++++------------ 2 files changed, 166 insertions(+), 52 deletions(-) diff --git a/tlg/demographic.R b/tlg/demographic.R index 8a83614..9a4fffc 100644 --- a/tlg/demographic.R +++ b/tlg/demographic.R @@ -1,31 +1,82 @@ -## ----r setup, message=FALSE, warning=FALSE, results='hold'-------------------- -library(pharmaverseadam) -library(tern) +## ----r preproc---------------------------------------------------------------- library(dplyr) -adsl <- adsl %>% - df_explicit_na() - -## ----r preproc---------------------------------------------------------------- -# Create categorical variables -adsl <- adsl %>% +# Create categorical variables, remove scren failures, and assign column labels +adsl <- pharmaverseadam::adsl |> + filter(!ACTARM %in% "Screen Failure") |> mutate( - SEX = factor(case_when( + SEX = case_when( SEX == "M" ~ "Male", - SEX == "F" ~ "Female", - SEX == "U" ~ "Unknown", - SEX == "UNDIFFERENTIATED" ~ "Undifferentiated" - )), - AGEGR1 = factor( + SEX == "F" ~ "Female" + ) |> + factor(), + AGEGR1 = case_when( between(AGE, 18, 40) ~ "18-40", between(AGE, 41, 64) ~ "41-64", AGE > 64 ~ ">=65" - ), - levels = c("18-40", "41-64", ">=65") - ) + ) |> + factor(levels = c("18-40", "41-64", ">=65") + ) + ) |> + labelled::set_variable_labels(AGE = "Age (yr)", + AGEGR1 = "Age group", + SEX = "Sex", + RACE = "Race") + +## ----r------------------------------------------------------------------------ +library(cards) +library(gtsummary) +theme_gtsummary_compact() # reduce default padding and font size for a gt table + +# build the ARD with the needed summary statistics using {cards} +ard <- + ard_stack( + adsl, + ard_continuous(variables = AGE), + ard_categorical(variables = c(AGEGR1, SEX, RACE)), + .by = ACTARM, # split results by treatment arm + .missing = TRUE, # add information about missingness rates ) +# use the ARD to create a demographics table +tbl_ard_summary( + cards = ard, + by = ACTARM, + include = c(AGE, AGEGR1, SEX, RACE), + type = AGE ~ "continuous2", + statistic = AGE ~ c("{mean} ({sd})", + "{median} ({p25}, {p75})", + "{min}, {max}"), + missing = "always" +) |> + bold_labels() |> + modify_header(all_stat_cols() ~ "**{level}** \nN = {n}") |> # add Ns to header + modify_footnote(everything() ~ NA) # remove default footnote + +## ----r------------------------------------------------------------------------ +tbl <- adsl |> + tbl_summary( + by = ACTARM, + include = c(AGE, AGEGR1, SEX, RACE), + # display summary stats for AGE on multiple rows + type = AGE ~ "continuous2", + statistic = AGE ~ c("{mean} ({sd})", + "{median} ({p25}, {p75})", + "{min}, {max}"), + missing = "always" + ) |> + bold_labels() |> + modify_footnote(everything() ~ NA) # remove default footnote + +gather_ard(tbl) + +## ----r setup, message=FALSE, warning=FALSE, results='hold'-------------------- +library(tern) + +adsl2 <- adsl %>% + df_explicit_na() + ## ----r table------------------------------------------------------------------ vars <- c("AGE", "AGEGR1", "SEX", "RACE") var_labels <- c( @@ -43,7 +94,7 @@ lyt <- basic_table(show_colcounts = TRUE) %>% var_labels = var_labels ) -result <- build_table(lyt, adsl) +result <- build_table(lyt, adsl2) result diff --git a/tlg/demographic.qmd b/tlg/demographic.qmd index c25c1b6..66fe072 100644 --- a/tlg/demographic.qmd +++ b/tlg/demographic.qmd @@ -13,53 +13,116 @@ knitr::opts_chunk$set(echo = TRUE) This guide will show you how pharmaverse packages, along with some from tidyverse, can be used to create a Demographic table, using the `{pharmaverseadam}` `ADSL` data as an input. +## Data preprocessing + +Now we will add some pre-processing to create some extra formatted variables ready for display in the table. + +```{r preproc} +library(dplyr) + +# Create categorical variables, remove scren failures, and assign column labels +adsl <- pharmaverseadam::adsl |> + filter(!ACTARM %in% "Screen Failure") |> + mutate( + SEX = case_when( + SEX == "M" ~ "Male", + SEX == "F" ~ "Female" + ) |> + factor(), + AGEGR1 = + case_when( + between(AGE, 18, 40) ~ "18-40", + between(AGE, 41, 64) ~ "41-64", + AGE > 64 ~ ">=65" + ) |> + factor(levels = c("18-40", "41-64", ">=65") + ) + ) |> + labelled::set_variable_labels(AGE = "Age (yr)", + AGEGR1 = "Age group", + SEX = "Sex", + RACE = "Race") +``` + +## {gtsummary} & {cards} + +In the example below, we will use the [{gtsummary}](https://www.danieldsjoberg.com/gtsummary/) and [{cards}](https://github.com/insightsengineering/cards) packages to create a demographics tables. + +- The {cards} package creates Analysis Results Datasets (ARDs, which are a part of the emerging [CDSIC Analyis Results Standard](https://www.cdisc.org/standards/foundational/analysis-results-standard)). +- The {gtsummary} utilizes ARDs to create tables. + +In the example below, we first build an ARD with the needed summary statistics using {cards}. +Then, we use the ARD to build the demogrphics table. + +```{r} +library(cards) +library(gtsummary) +theme_gtsummary_compact() # reduce default padding and font size for a gt table + +# build the ARD with the needed summary statistics using {cards} +ard <- + ard_stack( + adsl, + ard_continuous(variables = AGE), + ard_categorical(variables = c(AGEGR1, SEX, RACE)), + .by = ACTARM, # split results by treatment arm + .missing = TRUE, # add information about missingness rates + ) + +# use the ARD to create a demographics table +tbl_ard_summary( + cards = ard, + by = ACTARM, + include = c(AGE, AGEGR1, SEX, RACE), + type = AGE ~ "continuous2", + statistic = AGE ~ c("{mean} ({sd})", + "{median} ({p25}, {p75})", + "{min}, {max}"), + missing = "always" +) |> + bold_labels() |> + modify_header(all_stat_cols() ~ "**{level}** \nN = {n}") |> # add Ns to header + modify_footnote(everything() ~ NA) # remove default footnote +``` + +One may also build the deomgraphics in the classic way using `tbl_summary()` from a data frame, then extract the ARD from the table object. + +```{r} +tbl <- adsl |> + tbl_summary( + by = ACTARM, + include = c(AGE, AGEGR1, SEX, RACE), + # display summary stats for AGE on multiple rows + type = AGE ~ "continuous2", + statistic = AGE ~ c("{mean} ({sd})", + "{median} ({p25}, {p75})", + "{min}, {max}"), + missing = "always" + ) |> + bold_labels() |> + modify_footnote(everything() ~ NA) # remove default footnote + +gather_ard(tbl) +``` + +## {rtables} & {tern} + The packages used with a brief description of their purpose are as follows: * [`{rtables}`](https://insightsengineering.github.io/rtables/): designed to create and display complex tables with R. * [`{tern}`](https://insightsengineering.github.io/tern/): contains analysis functions to create tables and graphs used for clinical trial reporting. -## Load Data and Required pharmaverse Package - After installation of packages, the first step is to load our pharmaverse packages and input data. Here, we are going to encode missing entries in a data frame `adsl`. Note that `{tern}` depends on `{rtables}` so the latter is automatically attached. ```{r setup, message=FALSE, warning=FALSE, results='hold'} -library(pharmaverseadam) library(tern) -library(dplyr) -adsl <- adsl %>% +adsl2 <- adsl %>% df_explicit_na() ``` -## Start preprocessing - -Now we will add some pre-processing to create some extra formatted variables ready for display in the table. - -```{r preproc} -# Create categorical variables -adsl <- adsl %>% - mutate( - SEX = factor(case_when( - SEX == "M" ~ "Male", - SEX == "F" ~ "Female", - SEX == "U" ~ "Unknown", - SEX == "UNDIFFERENTIATED" ~ "Undifferentiated" - )), - AGEGR1 = factor( - case_when( - between(AGE, 18, 40) ~ "18-40", - between(AGE, 41, 64) ~ "41-64", - AGE > 64 ~ ">=65" - ), - levels = c("18-40", "41-64", ">=65") - ) - ) -``` - -## Demographic table - Now we create the demographic table. ```{r table} @@ -79,7 +142,7 @@ lyt <- basic_table(show_colcounts = TRUE) %>% var_labels = var_labels ) -result <- build_table(lyt, adsl) +result <- build_table(lyt, adsl2) result ``` From 3039be8cb2dd00f1a35e05e03a2a225d14ee61fe Mon Sep 17 00:00:00 2001 From: Daniel Sjoberg Date: Fri, 13 Sep 2024 07:08:06 -0700 Subject: [PATCH 02/14] Update DESCRIPTION --- DESCRIPTION | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index d017e12..5ea8243 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -9,14 +9,18 @@ Authors@R: person("Jeffrey", "Dickinson", role = "aut"), person("Ege Can", "Taşlıçukur", role = "aut"), person("Vedha", "Viyash", role = "aut"), - person("David", "Blair", role = "aut") + person("David", "Blair", role = "aut"), + person("Daniel D.", "Sjoberg", , "danield.sjoberg@gmail.com", role = "aut", comment = c(ORCID = "0000-0003-0862-2018")) Description: This is not a package, but we just use this file to declare the dependencies of the site. URL: https://github.com/pharmaverse/examples Imports: admiral, + cards, dplyr, + gtsummary, lubridate, + labelled, magrittr, metacore, metatools, From 757ff3190aab4a8da0ab52a7137e5c1a77038bbe Mon Sep 17 00:00:00 2001 From: Daniel Sjoberg Date: Tue, 17 Sep 2024 15:57:28 -0700 Subject: [PATCH 03/14] updates --- tlg/demographic.R | 8 ++++---- tlg/demographic.qmd | 21 +++++++++++---------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/tlg/demographic.R b/tlg/demographic.R index 9a4fffc..92eef00 100644 --- a/tlg/demographic.R +++ b/tlg/demographic.R @@ -24,7 +24,7 @@ adsl <- pharmaverseadam::adsl |> SEX = "Sex", RACE = "Race") -## ----r------------------------------------------------------------------------ +## ----r gtsummary-table-------------------------------------------------------- library(cards) library(gtsummary) theme_gtsummary_compact() # reduce default padding and font size for a gt table @@ -54,7 +54,7 @@ tbl_ard_summary( modify_header(all_stat_cols() ~ "**{level}** \nN = {n}") |> # add Ns to header modify_footnote(everything() ~ NA) # remove default footnote -## ----r------------------------------------------------------------------------ +## ----r gtsummary-ard---------------------------------------------------------- tbl <- adsl |> tbl_summary( by = ACTARM, @@ -71,13 +71,13 @@ tbl <- adsl |> gather_ard(tbl) -## ----r setup, message=FALSE, warning=FALSE, results='hold'-------------------- +## ----r rtables-setup, message=FALSE, warning=FALSE, results='hold'------------ library(tern) adsl2 <- adsl %>% df_explicit_na() -## ----r table------------------------------------------------------------------ +## ----r rtables-table---------------------------------------------------------- vars <- c("AGE", "AGEGR1", "SEX", "RACE") var_labels <- c( "Age (yr)", diff --git a/tlg/demographic.qmd b/tlg/demographic.qmd index 66fe072..e97f61b 100644 --- a/tlg/demographic.qmd +++ b/tlg/demographic.qmd @@ -18,6 +18,7 @@ This guide will show you how pharmaverse packages, along with some from tidyvers Now we will add some pre-processing to create some extra formatted variables ready for display in the table. ```{r preproc} +#| message: false library(dplyr) # Create categorical variables, remove scren failures, and assign column labels @@ -52,9 +53,10 @@ In the example below, we will use the [{gtsummary}](https://www.danieldsjoberg.c - The {gtsummary} utilizes ARDs to create tables. In the example below, we first build an ARD with the needed summary statistics using {cards}. -Then, we use the ARD to build the demogrphics table. +Then, we use the ARD to build the demographics table. -```{r} +```{r gtsummary-table} +#| message: false library(cards) library(gtsummary) theme_gtsummary_compact() # reduce default padding and font size for a gt table @@ -67,6 +69,7 @@ ard <- ard_categorical(variables = c(AGEGR1, SEX, RACE)), .by = ACTARM, # split results by treatment arm .missing = TRUE, # add information about missingness rates + .attributes = TRUE # optionally include column labels in the ARD ) # use the ARD to create a demographics table @@ -85,24 +88,22 @@ tbl_ard_summary( modify_footnote(everything() ~ NA) # remove default footnote ``` -One may also build the deomgraphics in the classic way using `tbl_summary()` from a data frame, then extract the ARD from the table object. +One may also build the demographics in the classic way using `tbl_summary()` from a data frame, then extract the ARD from the table object. -```{r} +```{r gtsummary-ard} tbl <- adsl |> tbl_summary( by = ACTARM, include = c(AGE, AGEGR1, SEX, RACE), # display summary stats for AGE on multiple rows type = AGE ~ "continuous2", - statistic = AGE ~ c("{mean} ({sd})", - "{median} ({p25}, {p75})", - "{min}, {max}"), + statistic = AGE ~ c("{mean} ({sd})", "{median} ({p25}, {p75})", "{min}, {max}"), missing = "always" ) |> bold_labels() |> modify_footnote(everything() ~ NA) # remove default footnote -gather_ard(tbl) +gather_ard(tbl)[[1]] |> select(-gts_column) # removing column so ARD fits on page ``` ## {rtables} & {tern} @@ -116,7 +117,7 @@ After installation of packages, the first step is to load our pharmaverse packag Note that `{tern}` depends on `{rtables}` so the latter is automatically attached. -```{r setup, message=FALSE, warning=FALSE, results='hold'} +```{r rtables-setup, message=FALSE, warning=FALSE, results='hold'} library(tern) adsl2 <- adsl %>% @@ -125,7 +126,7 @@ adsl2 <- adsl %>% Now we create the demographic table. -```{r table} +```{r rtables-table} vars <- c("AGE", "AGEGR1", "SEX", "RACE") var_labels <- c( "Age (yr)", From cc9bf1df623cf95579dcf3f9e36146c7640521d7 Mon Sep 17 00:00:00 2001 From: Daniel Sjoberg Date: Tue, 17 Sep 2024 15:59:49 -0700 Subject: [PATCH 04/14] Update demographic.qmd --- tlg/demographic.qmd | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tlg/demographic.qmd b/tlg/demographic.qmd index e97f61b..fbf2a7a 100644 --- a/tlg/demographic.qmd +++ b/tlg/demographic.qmd @@ -52,6 +52,8 @@ In the example below, we will use the [{gtsummary}](https://www.danieldsjoberg.c - The {cards} package creates Analysis Results Datasets (ARDs, which are a part of the emerging [CDSIC Analyis Results Standard](https://www.cdisc.org/standards/foundational/analysis-results-standard)). - The {gtsummary} utilizes ARDs to create tables. +#### ARD to Table + In the example below, we first build an ARD with the needed summary statistics using {cards}. Then, we use the ARD to build the demographics table. @@ -88,6 +90,8 @@ tbl_ard_summary( modify_footnote(everything() ~ NA) # remove default footnote ``` +#### Table to ARD + One may also build the demographics in the classic way using `tbl_summary()` from a data frame, then extract the ARD from the table object. ```{r gtsummary-ard} From f1bbb374fdac962f5df1017ec4f28c73e7c26651 Mon Sep 17 00:00:00 2001 From: Daniel Sjoberg Date: Tue, 17 Sep 2024 16:01:34 -0700 Subject: [PATCH 05/14] Update demographic.qmd --- tlg/demographic.qmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tlg/demographic.qmd b/tlg/demographic.qmd index fbf2a7a..f6ade09 100644 --- a/tlg/demographic.qmd +++ b/tlg/demographic.qmd @@ -74,7 +74,7 @@ ard <- .attributes = TRUE # optionally include column labels in the ARD ) -# use the ARD to create a demographics table +# use the ARD to create a demographics table using {gtsummary} tbl_ard_summary( cards = ard, by = ACTARM, From 377550508145ec5004f8e58a19f427ef3420c170 Mon Sep 17 00:00:00 2001 From: Daniel Sjoberg Date: Tue, 17 Sep 2024 16:06:47 -0700 Subject: [PATCH 06/14] Update demographic.qmd --- tlg/demographic.qmd | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tlg/demographic.qmd b/tlg/demographic.qmd index f6ade09..cedaec2 100644 --- a/tlg/demographic.qmd +++ b/tlg/demographic.qmd @@ -21,7 +21,7 @@ Now we will add some pre-processing to create some extra formatted variables rea #| message: false library(dplyr) -# Create categorical variables, remove scren failures, and assign column labels +# Create categorical variables, remove screen failures, and assign column labels adsl <- pharmaverseadam::adsl |> filter(!ACTARM %in% "Screen Failure") |> mutate( @@ -80,9 +80,7 @@ tbl_ard_summary( by = ACTARM, include = c(AGE, AGEGR1, SEX, RACE), type = AGE ~ "continuous2", - statistic = AGE ~ c("{mean} ({sd})", - "{median} ({p25}, {p75})", - "{min}, {max}"), + statistic = AGE ~ c("{mean} ({sd})", "{median} ({p25}, {p75})", "{min}, {max}"), missing = "always" ) |> bold_labels() |> From bfcd8691163bd117e7fa0106f8699aa9020530ad Mon Sep 17 00:00:00 2001 From: Daniel Sjoberg Date: Tue, 17 Sep 2024 16:14:22 -0700 Subject: [PATCH 07/14] Update demographic.qmd --- tlg/demographic.qmd | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/tlg/demographic.qmd b/tlg/demographic.qmd index cedaec2..c59a726 100644 --- a/tlg/demographic.qmd +++ b/tlg/demographic.qmd @@ -25,19 +25,14 @@ library(dplyr) adsl <- pharmaverseadam::adsl |> filter(!ACTARM %in% "Screen Failure") |> mutate( - SEX = case_when( - SEX == "M" ~ "Male", - SEX == "F" ~ "Female" - ) |> - factor(), + SEX = case_match(SEX, "M" ~ "Male", "F" ~ "Female"), AGEGR1 = case_when( between(AGE, 18, 40) ~ "18-40", between(AGE, 41, 64) ~ "41-64", AGE > 64 ~ ">=65" ) |> - factor(levels = c("18-40", "41-64", ">=65") - ) + factor(levels = c("18-40", "41-64", ">=65")) ) |> labelled::set_variable_labels(AGE = "Age (yr)", AGEGR1 = "Age group", From cac9671623e300af89fb9ae6ec865410e293f72b Mon Sep 17 00:00:00 2001 From: Daniel Sjoberg Date: Tue, 17 Sep 2024 16:16:45 -0700 Subject: [PATCH 08/14] Update demographic.qmd --- tlg/demographic.qmd | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tlg/demographic.qmd b/tlg/demographic.qmd index c59a726..6a957d6 100644 --- a/tlg/demographic.qmd +++ b/tlg/demographic.qmd @@ -88,6 +88,7 @@ tbl_ard_summary( One may also build the demographics in the classic way using `tbl_summary()` from a data frame, then extract the ARD from the table object. ```{r gtsummary-ard} +# build demographics table directly from a data frame tbl <- adsl |> tbl_summary( by = ACTARM, @@ -100,6 +101,7 @@ tbl <- adsl |> bold_labels() |> modify_footnote(everything() ~ NA) # remove default footnote +# extract ARD from table object gather_ard(tbl)[[1]] |> select(-gts_column) # removing column so ARD fits on page ``` From 17c1991f4abc79266938a69d48fa96f8cfb8d6e3 Mon Sep 17 00:00:00 2001 From: Daniel Sjoberg Date: Wed, 18 Sep 2024 08:49:20 -0700 Subject: [PATCH 09/14] added arrows --- tlg/demographic.qmd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tlg/demographic.qmd b/tlg/demographic.qmd index 6a957d6..929ef17 100644 --- a/tlg/demographic.qmd +++ b/tlg/demographic.qmd @@ -47,7 +47,7 @@ In the example below, we will use the [{gtsummary}](https://www.danieldsjoberg.c - The {cards} package creates Analysis Results Datasets (ARDs, which are a part of the emerging [CDSIC Analyis Results Standard](https://www.cdisc.org/standards/foundational/analysis-results-standard)). - The {gtsummary} utilizes ARDs to create tables. -#### ARD to Table +#### ARD ➡ Table In the example below, we first build an ARD with the needed summary statistics using {cards}. Then, we use the ARD to build the demographics table. @@ -83,7 +83,7 @@ tbl_ard_summary( modify_footnote(everything() ~ NA) # remove default footnote ``` -#### Table to ARD +#### Table ➡ ARD One may also build the demographics in the classic way using `tbl_summary()` from a data frame, then extract the ARD from the table object. From 0b9828b938d702d31b049a59e6cb6c94fe2e12cb Mon Sep 17 00:00:00 2001 From: Daniel Sjoberg Date: Wed, 18 Sep 2024 08:55:35 -0700 Subject: [PATCH 10/14] Update demographic.qmd --- tlg/demographic.qmd | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tlg/demographic.qmd b/tlg/demographic.qmd index 929ef17..9753891 100644 --- a/tlg/demographic.qmd +++ b/tlg/demographic.qmd @@ -50,7 +50,7 @@ In the example below, we will use the [{gtsummary}](https://www.danieldsjoberg.c #### ARD ➡ Table In the example below, we first build an ARD with the needed summary statistics using {cards}. -Then, we use the ARD to build the demographics table. +Then, we use the ARD to build the demographics table with {gtsummary}. ```{r gtsummary-table} #| message: false @@ -65,7 +65,7 @@ ard <- ard_continuous(variables = AGE), ard_categorical(variables = c(AGEGR1, SEX, RACE)), .by = ACTARM, # split results by treatment arm - .missing = TRUE, # add information about missingness rates + .missing = TRUE, # optionally include information about missingness rates .attributes = TRUE # optionally include column labels in the ARD ) @@ -85,7 +85,7 @@ tbl_ard_summary( #### Table ➡ ARD -One may also build the demographics in the classic way using `tbl_summary()` from a data frame, then extract the ARD from the table object. +One may also build the demographics in the classic way using `gtsummary::tbl_summary()` from a data frame, then extract the ARD from the table object. ```{r gtsummary-ard} # build demographics table directly from a data frame From dd6ae8ac4203ec7e4e1fda3c436a66a3b942ae72 Mon Sep 17 00:00:00 2001 From: Daniel Sjoberg Date: Wed, 18 Sep 2024 20:03:28 -0700 Subject: [PATCH 11/14] Added Data arrow in doc --- tlg/demographic.qmd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tlg/demographic.qmd b/tlg/demographic.qmd index 9753891..2cdecc2 100644 --- a/tlg/demographic.qmd +++ b/tlg/demographic.qmd @@ -47,7 +47,7 @@ In the example below, we will use the [{gtsummary}](https://www.danieldsjoberg.c - The {cards} package creates Analysis Results Datasets (ARDs, which are a part of the emerging [CDSIC Analyis Results Standard](https://www.cdisc.org/standards/foundational/analysis-results-standard)). - The {gtsummary} utilizes ARDs to create tables. -#### ARD ➡ Table +#### Data ➡ ARD ➡ Table In the example below, we first build an ARD with the needed summary statistics using {cards}. Then, we use the ARD to build the demographics table with {gtsummary}. @@ -83,7 +83,7 @@ tbl_ard_summary( modify_footnote(everything() ~ NA) # remove default footnote ``` -#### Table ➡ ARD +#### Data ➡ Table ➡ ARD One may also build the demographics in the classic way using `gtsummary::tbl_summary()` from a data frame, then extract the ARD from the table object. From c4332dd676782697bbd8f4a3e25c0e1fc335d329 Mon Sep 17 00:00:00 2001 From: Daniel Sjoberg Date: Sun, 22 Sep 2024 08:36:21 -0700 Subject: [PATCH 12/14] Update demographic.qmd --- tlg/demographic.qmd | 38 +++++++++++++++----------------------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/tlg/demographic.qmd b/tlg/demographic.qmd index 2cdecc2..0817e1a 100644 --- a/tlg/demographic.qmd +++ b/tlg/demographic.qmd @@ -13,6 +13,10 @@ knitr::opts_chunk$set(echo = TRUE) This guide will show you how pharmaverse packages, along with some from tidyverse, can be used to create a Demographic table, using the `{pharmaverseadam}` `ADSL` data as an input. +In the examples below, we illustrate two general approaches for creating a demographics table. +The first utilizes Analysis Results Datasets---part of the emerging [CDISC Analyis Results Standard](https://www.cdisc.org/standards/foundational/analysis-results-standard). +The second is the classic method of creating summary tables directly from a data set. + ## Data preprocessing Now we will add some pre-processing to create some extra formatted variables ready for display in the table. @@ -25,7 +29,7 @@ library(dplyr) adsl <- pharmaverseadam::adsl |> filter(!ACTARM %in% "Screen Failure") |> mutate( - SEX = case_match(SEX, "M" ~ "Male", "F" ~ "Female"), + SEX = case_match(SEX, "M" ~ "MALE", "F" ~ "FEMALE"), AGEGR1 = case_when( between(AGE, 18, 40) ~ "18-40", @@ -42,12 +46,12 @@ adsl <- pharmaverseadam::adsl |> ## {gtsummary} & {cards} -In the example below, we will use the [{gtsummary}](https://www.danieldsjoberg.com/gtsummary/) and [{cards}](https://github.com/insightsengineering/cards) packages to create a demographics tables. +In the example below, we will use the [{gtsummary}](https://www.danieldsjoberg.com/gtsummary/) and [{cards}](https://insightsengineering.github.io/cards/) packages to create a demographics tables. -- The {cards} package creates Analysis Results Datasets (ARDs, which are a part of the emerging [CDSIC Analyis Results Standard](https://www.cdisc.org/standards/foundational/analysis-results-standard)). +- The {cards} package creates Analysis Results Datasets (ARDs, which are a part of the [CDSIC Analysis Results Standard](https://www.cdisc.org/standards/foundational/analysis-results-standard)). - The {gtsummary} utilizes ARDs to create tables. -#### Data ➡ ARD ➡ Table +#### ARD ➡ Table In the example below, we first build an ARD with the needed summary statistics using {cards}. Then, we use the ARD to build the demographics table with {gtsummary}. @@ -65,7 +69,6 @@ ard <- ard_continuous(variables = AGE), ard_categorical(variables = c(AGEGR1, SEX, RACE)), .by = ACTARM, # split results by treatment arm - .missing = TRUE, # optionally include information about missingness rates .attributes = TRUE # optionally include column labels in the ARD ) @@ -75,31 +78,20 @@ tbl_ard_summary( by = ACTARM, include = c(AGE, AGEGR1, SEX, RACE), type = AGE ~ "continuous2", - statistic = AGE ~ c("{mean} ({sd})", "{median} ({p25}, {p75})", "{min}, {max}"), - missing = "always" + statistic = AGE ~ c("{N}", "{mean} ({sd})", "{median} ({p25}, {p75})", "{min}, {max}") ) |> bold_labels() |> modify_header(all_stat_cols() ~ "**{level}** \nN = {n}") |> # add Ns to header modify_footnote(everything() ~ NA) # remove default footnote ``` -#### Data ➡ Table ➡ ARD +#### Table ➡ ARD One may also build the demographics in the classic way using `gtsummary::tbl_summary()` from a data frame, then extract the ARD from the table object. ```{r gtsummary-ard} # build demographics table directly from a data frame -tbl <- adsl |> - tbl_summary( - by = ACTARM, - include = c(AGE, AGEGR1, SEX, RACE), - # display summary stats for AGE on multiple rows - type = AGE ~ "continuous2", - statistic = AGE ~ c("{mean} ({sd})", "{median} ({p25}, {p75})", "{min}, {max}"), - missing = "always" - ) |> - bold_labels() |> - modify_footnote(everything() ~ NA) # remove default footnote +tbl <- adsl |> tbl_summary(by = ACTARM, include = c(AGE, AGEGR1, SEX, RACE)) # extract ARD from table object gather_ard(tbl)[[1]] |> select(-gts_column) # removing column so ARD fits on page @@ -119,7 +111,7 @@ Note that `{tern}` depends on `{rtables}` so the latter is automatically attache ```{r rtables-setup, message=FALSE, warning=FALSE, results='hold'} library(tern) -adsl2 <- adsl %>% +adsl2 <- adsl |> df_explicit_na() ``` @@ -134,9 +126,9 @@ var_labels <- c( "Race" ) -lyt <- basic_table(show_colcounts = TRUE) %>% - split_cols_by(var = "ACTARM") %>% - add_overall_col("All Patients") %>% +lyt <- basic_table(show_colcounts = TRUE) |> + split_cols_by(var = "ACTARM") |> + add_overall_col("All Patients") |> analyze_vars( vars = vars, var_labels = var_labels From a95feb4bcd4216a45aeed39a679063343c54a3a5 Mon Sep 17 00:00:00 2001 From: Ross Farrugia <82581364+rossfarrugia@users.noreply.github.com> Date: Mon, 23 Sep 2024 11:35:57 +0100 Subject: [PATCH 13/14] Update tlg/demographic.qmd --- tlg/demographic.qmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tlg/demographic.qmd b/tlg/demographic.qmd index 0817e1a..ec4cb7b 100644 --- a/tlg/demographic.qmd +++ b/tlg/demographic.qmd @@ -48,7 +48,7 @@ adsl <- pharmaverseadam::adsl |> In the example below, we will use the [{gtsummary}](https://www.danieldsjoberg.com/gtsummary/) and [{cards}](https://insightsengineering.github.io/cards/) packages to create a demographics tables. -- The {cards} package creates Analysis Results Datasets (ARDs, which are a part of the [CDSIC Analysis Results Standard](https://www.cdisc.org/standards/foundational/analysis-results-standard)). +- The {cards} package creates Analysis Results Datasets (ARDs, which are a part of the [CDISC Analysis Results Standard](https://www.cdisc.org/standards/foundational/analysis-results-standard)). - The {gtsummary} utilizes ARDs to create tables. #### ARD ➡ Table From ed1f4ec5abd996fd79b856e6964b676961b62334 Mon Sep 17 00:00:00 2001 From: Daniel Sjoberg Date: Mon, 23 Sep 2024 06:53:19 -0700 Subject: [PATCH 14/14] Update demographic.R --- tlg/demographic.R | 46 ++++++++++++++-------------------------------- 1 file changed, 14 insertions(+), 32 deletions(-) diff --git a/tlg/demographic.R b/tlg/demographic.R index 92eef00..735073a 100644 --- a/tlg/demographic.R +++ b/tlg/demographic.R @@ -1,23 +1,18 @@ ## ----r preproc---------------------------------------------------------------- library(dplyr) -# Create categorical variables, remove scren failures, and assign column labels +# Create categorical variables, remove screen failures, and assign column labels adsl <- pharmaverseadam::adsl |> filter(!ACTARM %in% "Screen Failure") |> mutate( - SEX = case_when( - SEX == "M" ~ "Male", - SEX == "F" ~ "Female" - ) |> - factor(), + SEX = case_match(SEX, "M" ~ "MALE", "F" ~ "FEMALE"), AGEGR1 = case_when( between(AGE, 18, 40) ~ "18-40", between(AGE, 41, 64) ~ "41-64", AGE > 64 ~ ">=65" ) |> - factor(levels = c("18-40", "41-64", ">=65") - ) + factor(levels = c("18-40", "41-64", ">=65")) ) |> labelled::set_variable_labels(AGE = "Age (yr)", AGEGR1 = "Age group", @@ -36,45 +31,32 @@ ard <- ard_continuous(variables = AGE), ard_categorical(variables = c(AGEGR1, SEX, RACE)), .by = ACTARM, # split results by treatment arm - .missing = TRUE, # add information about missingness rates + .attributes = TRUE # optionally include column labels in the ARD ) -# use the ARD to create a demographics table +# use the ARD to create a demographics table using {gtsummary} tbl_ard_summary( cards = ard, by = ACTARM, include = c(AGE, AGEGR1, SEX, RACE), type = AGE ~ "continuous2", - statistic = AGE ~ c("{mean} ({sd})", - "{median} ({p25}, {p75})", - "{min}, {max}"), - missing = "always" + statistic = AGE ~ c("{N}", "{mean} ({sd})", "{median} ({p25}, {p75})", "{min}, {max}") ) |> bold_labels() |> modify_header(all_stat_cols() ~ "**{level}** \nN = {n}") |> # add Ns to header modify_footnote(everything() ~ NA) # remove default footnote ## ----r gtsummary-ard---------------------------------------------------------- -tbl <- adsl |> - tbl_summary( - by = ACTARM, - include = c(AGE, AGEGR1, SEX, RACE), - # display summary stats for AGE on multiple rows - type = AGE ~ "continuous2", - statistic = AGE ~ c("{mean} ({sd})", - "{median} ({p25}, {p75})", - "{min}, {max}"), - missing = "always" - ) |> - bold_labels() |> - modify_footnote(everything() ~ NA) # remove default footnote +# build demographics table directly from a data frame +tbl <- adsl |> tbl_summary(by = ACTARM, include = c(AGE, AGEGR1, SEX, RACE)) -gather_ard(tbl) +# extract ARD from table object +gather_ard(tbl)[[1]] |> select(-gts_column) # removing column so ARD fits on page ## ----r rtables-setup, message=FALSE, warning=FALSE, results='hold'------------ library(tern) -adsl2 <- adsl %>% +adsl2 <- adsl |> df_explicit_na() ## ----r rtables-table---------------------------------------------------------- @@ -86,9 +68,9 @@ var_labels <- c( "Race" ) -lyt <- basic_table(show_colcounts = TRUE) %>% - split_cols_by(var = "ACTARM") %>% - add_overall_col("All Patients") %>% +lyt <- basic_table(show_colcounts = TRUE) |> + split_cols_by(var = "ACTARM") |> + add_overall_col("All Patients") |> analyze_vars( vars = vars, var_labels = var_labels