From c49c66ec0e0287c18bba8e173a47010c112419b7 Mon Sep 17 00:00:00 2001 From: ayogasekaram Date: Thu, 23 May 2024 17:31:19 +0000 Subject: [PATCH 01/21] initial commit - create make_table_02 ARD function. --- DESCRIPTION | 2 + NAMESPACE | 2 - R/fda-table_02.R | 117 +++++++++++++++++++++++++++++++++++++------ man/make_table_02.Rd | 44 ++++++++++++++-- 4 files changed, 143 insertions(+), 22 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 611c7918..b17b1301 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -14,6 +14,8 @@ Depends: R (>= 3.6), tern (>= 0.9.4) Imports: + cards, + cardx, checkmate, cowplot (>= 0.7.0), dplyr, diff --git a/NAMESPACE b/NAMESPACE index b19cae96..0534ec77 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -6,8 +6,6 @@ export(make_fig_01) export(make_fig_02) export(make_fig_14) export(make_table_02) -export(make_table_02_gtsum) -export(make_table_02_tplyr) export(make_table_03) export(make_table_04) export(make_table_05) diff --git a/R/fda-table_02.R b/R/fda-table_02.R index e9ce5cdb..5104dc46 100644 --- a/R/fda-table_02.R +++ b/R/fda-table_02.R @@ -1,7 +1,7 @@ #' FDA Table 2: Baseline Demographic and Clinical Characteristics, Safety Population, Pooled Analyses #' #' @details -#' * `df` must contain the variables specified by `vars`, `arm_var`, and `saffl_var`. +#' * `data` must contain the variables specified by `continuous_vars`, and `categorical_vars`. #' * If specified, `alt_counts_df` must contain the variables specified by `arm_var`, `id_var`, and `saffl_var`. #' * Flag variables (i.e. `XXXFL`) are expected to have two levels: `"Y"` (true) and `"N"` (false). Missing values in #' flag variables are treated as `"N"`. @@ -18,7 +18,8 @@ NULL #' @describeIn make_table_02 Create FDA table 2 using functions from `rtables` and `tern`. #' #' @return -#' * `make_table_02` returns an `rtable` object. +#' * `make_table_02` returns an object matching the selected `tbl_engine` argument. +#' The intermediary `ARD` object is also returned by default #' #' @examples #' library(dplyr) @@ -32,21 +33,105 @@ NULL #' )) %>% formatters::with_label("Age Group, years")) %>% #' formatters::var_relabel(AGE = "Age, years") #' -#' tbl <- make_table_02(df = adsl) +#' tbl <- make_table_02(data = adsl) #' tbl #' #' @export -make_table_02 <- function(df, - alt_counts_df = NULL, - show_colcounts = TRUE, - arm_var = "ARM", - saffl_var = "SAFFL", - vars = c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY"), - lbl_vars = formatters::var_labels(df, fill = TRUE)[vars], - lbl_overall = "Total Population", - na_rm = FALSE, - prune_0 = TRUE, - annotations = NULL) { + +make_table_02 <- function(data, + ..., + tbl_engine = "gtsummary", + return_ard = TRUE) { + # check data viability + assert_subset(continuous_vars, names(data)) + assert_subset(categorical_vars, names(data)) + + if (tbl_engine == "rtables") { + ard <- "ARD not available for {rtables}" + tbl <- make_table_02_rtables(df = data) + } else { + ard <- make_ard_02(...) + # commenting out this table building portion until package refactor + # if (tbl_engine == "gtsummary") { + # tbl <- make_table_02_gtsum(ard, ...) + # } else { + # tbl <- make_table_02_tplyr(ard, ...) + # } + } + + if (return_ard) { + res <- list(ard = ard) + } else { + res <- tbl + } +} + + +make_ard_02 <- function(data = data, + by = "ARM", + continuous_vars = c("AGE"), + categorical_vars = c("SEX", "AGEGR1", "RACE", "ETHNIC")) { + ard <- cards::ard_stack( + data = data, + by = by, + cards::ard_continuous( + variables = continuous_vars, + statistic = ~ continuous_summary_fns(c("mean", "sd", "median", "min", "max")) + ), + cards::ard_categorical(variables = categorical_vars) + ) + + return(ard) +} + + +#' @details +#' * `df` must contain the variables specified by `continuous_vars`, and `categorical_vars`. +#' * If specified, `alt_counts_df` must contain the variables specified by `arm_var`, `id_var`, and `saffl_var`. +#' * Flag variables (i.e. `XXXFL`) are expected to have two levels: `"Y"` (true) and `"N"` (false). Missing values in +#' flag variables are treated as `"N"`. +#' * Columns are split by arm. Overall population column is included by default (see `lbl_overall` argument). +#' * Information from either ADSUB or ADVS is generally included into `df` prior to analysis. +#' * Numbers in table for non-numeric variables represent the absolute numbers of patients and fraction of `N`. +#' * All-zero rows are removed by default (see `prune_0` argument). +#' +#' @inheritParams argument_convention +#' +#' @name make_table_02 +NULL + +#' @describeIn make_table_02 Create FDA table 2 using functions from `rtables` and `tern`. +#' +#' @return +#' * `make_table_02` returns an object matching the selected `tbl_engine` argument. +#' The intermediary `ARD` object is also returned by default +#' +#' @examples +#' library(dplyr) +#' +#' adsl <- random.cdisc.data::cadsl %>% +#' mutate(AGEGR1 = as.factor(case_when( +#' AGE >= 17 & AGE < 65 ~ ">=17 to <65", +#' AGE >= 65 ~ ">=65", +#' AGE >= 65 & AGE < 75 ~ ">=65 to <75", +#' AGE >= 75 ~ ">=75" +#' )) %>% formatters::with_label("Age Group, years")) %>% +#' formatters::var_relabel(AGE = "Age, years") +#' +#' tbl <- make_table_02(data = adsl) +#' tbl +#' @keywords Internal +make_table_02_rtables <- function(df, + alt_counts_df = NULL, + show_colcounts = TRUE, + arm_var = "ARM", + saffl_var = "SAFFL", + vars = c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY"), + lbl_vars = formatters::var_labels(df, fill = TRUE)[vars], + lbl_overall = "Total Population", + na_rm = FALSE, + prune_0 = TRUE, + annotations = NULL) { assert_subset(c(vars, arm_var, saffl_var), names(df)) assert_flag_variables(df, saffl_var) @@ -91,7 +176,7 @@ make_table_02 <- function(df, #' tbl <- make_table_02_tplyr(df = adsl) #' tbl #' -#' @export +#' @keywords Internal make_table_02_tplyr <- function(df, alt_counts_df = NULL, show_colcounts = TRUE, @@ -255,7 +340,7 @@ make_table_02_tplyr <- function(df, #' tbl <- make_table_02_gtsum(df = adsl) #' tbl #' -#' @export +#' @keywords Internal make_table_02_gtsum <- function(df, show_colcounts = TRUE, arm_var = "ARM", diff --git a/man/make_table_02.Rd b/man/make_table_02.Rd index dc34b673..7de32aba 100644 --- a/man/make_table_02.Rd +++ b/man/make_table_02.Rd @@ -2,11 +2,14 @@ % Please edit documentation in R/fda-table_02.R \name{make_table_02} \alias{make_table_02} +\alias{make_table_02_rtables} \alias{make_table_02_tplyr} \alias{make_table_02_gtsum} \title{FDA Table 2: Baseline Demographic and Clinical Characteristics, Safety Population, Pooled Analyses} \usage{ -make_table_02( +make_table_02(data, ..., tbl_engine = "gtsummary", return_ard = TRUE) + +make_table_02_rtables( df, alt_counts_df = NULL, show_colcounts = TRUE, @@ -78,7 +81,13 @@ table formatted using functions from \code{tfrmt} should be returned (default).} } \value{ \itemize{ -\item \code{make_table_02} returns an \code{rtable} object. +\item \code{make_table_02} returns an object matching the selected \code{tbl_engine} argument. +The intermediary \code{ARD} object is also returned by default +} + +\itemize{ +\item \code{make_table_02} returns an object matching the selected \code{tbl_engine} argument. +The intermediary \code{ARD} object is also returned by default } \itemize{ @@ -95,7 +104,18 @@ FDA Table 2: Baseline Demographic and Clinical Characteristics, Safety Populatio } \details{ \itemize{ -\item \code{df} must contain the variables specified by \code{vars}, \code{arm_var}, and \code{saffl_var}. +\item \code{data} must contain the variables specified by \code{continuous_vars}, and \code{categorical_vars}. +\item If specified, \code{alt_counts_df} must contain the variables specified by \code{arm_var}, \code{id_var}, and \code{saffl_var}. +\item Flag variables (i.e. \code{XXXFL}) are expected to have two levels: \code{"Y"} (true) and \code{"N"} (false). Missing values in +flag variables are treated as \code{"N"}. +\item Columns are split by arm. Overall population column is included by default (see \code{lbl_overall} argument). +\item Information from either ADSUB or ADVS is generally included into \code{df} prior to analysis. +\item Numbers in table for non-numeric variables represent the absolute numbers of patients and fraction of \code{N}. +\item All-zero rows are removed by default (see \code{prune_0} argument). +} + +\itemize{ +\item \code{df} must contain the variables specified by \code{continuous_vars}, and \code{categorical_vars}. \item If specified, \code{alt_counts_df} must contain the variables specified by \code{arm_var}, \code{id_var}, and \code{saffl_var}. \item Flag variables (i.e. \code{XXXFL}) are expected to have two levels: \code{"Y"} (true) and \code{"N"} (false). Missing values in flag variables are treated as \code{"N"}. @@ -109,6 +129,8 @@ flag variables are treated as \code{"N"}. \itemize{ \item \code{make_table_02()}: Create FDA table 2 using functions from \code{rtables} and \code{tern}. +\item \code{make_table_02_rtables()}: Create FDA table 2 using functions from \code{rtables} and \code{tern}. + \item \code{make_table_02_tplyr()}: Create FDA table 2 using functions from \code{Tplyr} and \code{tfrmt}. \item \code{make_table_02_gtsum()}: Create FDA table 2 using functions from \code{gtsummary}. @@ -132,9 +154,22 @@ adsl <- random.cdisc.data::cadsl \%>\% )) \%>\% formatters::with_label("Age Group, years")) \%>\% formatters::var_relabel(AGE = "Age, years") -tbl <- make_table_02(df = adsl) +tbl <- make_table_02(data = adsl) tbl +library(dplyr) + +adsl <- random.cdisc.data::cadsl \%>\% + mutate(AGEGR1 = as.factor(case_when( + AGE >= 17 & AGE < 65 ~ ">=17 to <65", + AGE >= 65 ~ ">=65", + AGE >= 65 & AGE < 75 ~ ">=65 to <75", + AGE >= 75 ~ ">=75" + )) \%>\% formatters::with_label("Age Group, years")) \%>\% + formatters::var_relabel(AGE = "Age, years") + +tbl <- make_table_02(data = adsl) +tbl tbl <- make_table_02_tplyr(df = adsl) tbl @@ -142,3 +177,4 @@ tbl <- make_table_02_gtsum(df = adsl) tbl } +\keyword{Internal} From 51a9608c822f0304e9d3c2fa8d8b8fe2e291cf67 Mon Sep 17 00:00:00 2001 From: ayogasekaram Date: Thu, 23 May 2024 20:28:50 +0000 Subject: [PATCH 02/21] update function name in tests. rework documentation --- R/fda-table_02.R | 55 ++++------------------------ man/make_table_02.Rd | 59 ++---------------------------- tests/testthat/test-fda-table_02.R | 6 +-- 3 files changed, 14 insertions(+), 106 deletions(-) diff --git a/R/fda-table_02.R b/R/fda-table_02.R index 5104dc46..b2f3066c 100644 --- a/R/fda-table_02.R +++ b/R/fda-table_02.R @@ -2,24 +2,19 @@ #' #' @details #' * `data` must contain the variables specified by `continuous_vars`, and `categorical_vars`. -#' * If specified, `alt_counts_df` must contain the variables specified by `arm_var`, `id_var`, and `saffl_var`. -#' * Flag variables (i.e. `XXXFL`) are expected to have two levels: `"Y"` (true) and `"N"` (false). Missing values in -#' flag variables are treated as `"N"`. -#' * Columns are split by arm. Overall population column is included by default (see `lbl_overall` argument). -#' * Information from either ADSUB or ADVS is generally included into `df` prior to analysis. -#' * Numbers in table for non-numeric variables represent the absolute numbers of patients and fraction of `N`. -#' * All-zero rows are removed by default (see `prune_0` argument). +#' * `tbl_engine` must be one of `gtsummary`, `rtables`, `tplyr`. +#' * `return_ard` set to `TRUE` or `FALSE`; whether the intermediate ARD object should be returned. #' #' @inheritParams argument_convention #' #' @name make_table_02 NULL -#' @describeIn make_table_02 Create FDA table 2 using functions from `rtables` and `tern`. +#' @describeIn make_table_02 Create FDA table 2 using an ARD. #' #' @return #' * `make_table_02` returns an object matching the selected `tbl_engine` argument. -#' The intermediary `ARD` object is also returned by default +#' The intermediary `ARD` object can also be returned with `return_ard` set to `TRUE`. #' #' @examples #' library(dplyr) @@ -30,8 +25,7 @@ NULL #' AGE >= 65 ~ ">=65", #' AGE >= 65 & AGE < 75 ~ ">=65 to <75", #' AGE >= 75 ~ ">=75" -#' )) %>% formatters::with_label("Age Group, years")) %>% -#' formatters::var_relabel(AGE = "Age, years") +#' )) #' #' tbl <- make_table_02(data = adsl) #' tbl @@ -66,7 +60,7 @@ make_table_02 <- function(data, } } - +#' @keywords Internal make_ard_02 <- function(data = data, by = "ARM", continuous_vars = c("AGE"), @@ -85,41 +79,6 @@ make_ard_02 <- function(data = data, } -#' @details -#' * `df` must contain the variables specified by `continuous_vars`, and `categorical_vars`. -#' * If specified, `alt_counts_df` must contain the variables specified by `arm_var`, `id_var`, and `saffl_var`. -#' * Flag variables (i.e. `XXXFL`) are expected to have two levels: `"Y"` (true) and `"N"` (false). Missing values in -#' flag variables are treated as `"N"`. -#' * Columns are split by arm. Overall population column is included by default (see `lbl_overall` argument). -#' * Information from either ADSUB or ADVS is generally included into `df` prior to analysis. -#' * Numbers in table for non-numeric variables represent the absolute numbers of patients and fraction of `N`. -#' * All-zero rows are removed by default (see `prune_0` argument). -#' -#' @inheritParams argument_convention -#' -#' @name make_table_02 -NULL - -#' @describeIn make_table_02 Create FDA table 2 using functions from `rtables` and `tern`. -#' -#' @return -#' * `make_table_02` returns an object matching the selected `tbl_engine` argument. -#' The intermediary `ARD` object is also returned by default -#' -#' @examples -#' library(dplyr) -#' -#' adsl <- random.cdisc.data::cadsl %>% -#' mutate(AGEGR1 = as.factor(case_when( -#' AGE >= 17 & AGE < 65 ~ ">=17 to <65", -#' AGE >= 65 ~ ">=65", -#' AGE >= 65 & AGE < 75 ~ ">=65 to <75", -#' AGE >= 75 ~ ">=75" -#' )) %>% formatters::with_label("Age Group, years")) %>% -#' formatters::var_relabel(AGE = "Age, years") -#' -#' tbl <- make_table_02(data = adsl) -#' tbl #' @keywords Internal make_table_02_rtables <- function(df, alt_counts_df = NULL, @@ -385,3 +344,5 @@ make_table_02_gtsum <- function(df, expr = as_gt(tbl) ) } + + diff --git a/man/make_table_02.Rd b/man/make_table_02.Rd index 7de32aba..b6baf1a5 100644 --- a/man/make_table_02.Rd +++ b/man/make_table_02.Rd @@ -2,27 +2,12 @@ % Please edit documentation in R/fda-table_02.R \name{make_table_02} \alias{make_table_02} -\alias{make_table_02_rtables} \alias{make_table_02_tplyr} \alias{make_table_02_gtsum} \title{FDA Table 2: Baseline Demographic and Clinical Characteristics, Safety Population, Pooled Analyses} \usage{ make_table_02(data, ..., tbl_engine = "gtsummary", return_ard = TRUE) -make_table_02_rtables( - df, - alt_counts_df = NULL, - show_colcounts = TRUE, - arm_var = "ARM", - saffl_var = "SAFFL", - vars = c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY"), - lbl_vars = formatters::var_labels(df, fill = TRUE)[vars], - lbl_overall = "Total Population", - na_rm = FALSE, - prune_0 = TRUE, - annotations = NULL -) - make_table_02_tplyr( df, alt_counts_df = NULL, @@ -82,12 +67,7 @@ table formatted using functions from \code{tfrmt} should be returned (default).} \value{ \itemize{ \item \code{make_table_02} returns an object matching the selected \code{tbl_engine} argument. -The intermediary \code{ARD} object is also returned by default -} - -\itemize{ -\item \code{make_table_02} returns an object matching the selected \code{tbl_engine} argument. -The intermediary \code{ARD} object is also returned by default +The intermediary \code{ARD} object can also be returned with \code{return_ard} set to \code{TRUE}. } \itemize{ @@ -105,32 +85,13 @@ FDA Table 2: Baseline Demographic and Clinical Characteristics, Safety Populatio \details{ \itemize{ \item \code{data} must contain the variables specified by \code{continuous_vars}, and \code{categorical_vars}. -\item If specified, \code{alt_counts_df} must contain the variables specified by \code{arm_var}, \code{id_var}, and \code{saffl_var}. -\item Flag variables (i.e. \code{XXXFL}) are expected to have two levels: \code{"Y"} (true) and \code{"N"} (false). Missing values in -flag variables are treated as \code{"N"}. -\item Columns are split by arm. Overall population column is included by default (see \code{lbl_overall} argument). -\item Information from either ADSUB or ADVS is generally included into \code{df} prior to analysis. -\item Numbers in table for non-numeric variables represent the absolute numbers of patients and fraction of \code{N}. -\item All-zero rows are removed by default (see \code{prune_0} argument). -} - -\itemize{ -\item \code{df} must contain the variables specified by \code{continuous_vars}, and \code{categorical_vars}. -\item If specified, \code{alt_counts_df} must contain the variables specified by \code{arm_var}, \code{id_var}, and \code{saffl_var}. -\item Flag variables (i.e. \code{XXXFL}) are expected to have two levels: \code{"Y"} (true) and \code{"N"} (false). Missing values in -flag variables are treated as \code{"N"}. -\item Columns are split by arm. Overall population column is included by default (see \code{lbl_overall} argument). -\item Information from either ADSUB or ADVS is generally included into \code{df} prior to analysis. -\item Numbers in table for non-numeric variables represent the absolute numbers of patients and fraction of \code{N}. -\item All-zero rows are removed by default (see \code{prune_0} argument). +\item \code{tbl_engine} must be one of \code{gtsummary}, \code{rtables}, \code{tplyr}. } } \section{Functions}{ \itemize{ \item \code{make_table_02()}: Create FDA table 2 using functions from \code{rtables} and \code{tern}. -\item \code{make_table_02_rtables()}: Create FDA table 2 using functions from \code{rtables} and \code{tern}. - \item \code{make_table_02_tplyr()}: Create FDA table 2 using functions from \code{Tplyr} and \code{tfrmt}. \item \code{make_table_02_gtsum()}: Create FDA table 2 using functions from \code{gtsummary}. @@ -151,25 +112,11 @@ adsl <- random.cdisc.data::cadsl \%>\% AGE >= 65 ~ ">=65", AGE >= 65 & AGE < 75 ~ ">=65 to <75", AGE >= 75 ~ ">=75" - )) \%>\% formatters::with_label("Age Group, years")) \%>\% - formatters::var_relabel(AGE = "Age, years") + )) tbl <- make_table_02(data = adsl) tbl -library(dplyr) - -adsl <- random.cdisc.data::cadsl \%>\% - mutate(AGEGR1 = as.factor(case_when( - AGE >= 17 & AGE < 65 ~ ">=17 to <65", - AGE >= 65 ~ ">=65", - AGE >= 65 & AGE < 75 ~ ">=65 to <75", - AGE >= 75 ~ ">=75" - )) \%>\% formatters::with_label("Age Group, years")) \%>\% - formatters::var_relabel(AGE = "Age, years") - -tbl <- make_table_02(data = adsl) -tbl tbl <- make_table_02_tplyr(df = adsl) tbl diff --git a/tests/testthat/test-fda-table_02.R b/tests/testthat/test-fda-table_02.R index 56bf742b..48dee518 100644 --- a/tests/testthat/test-fda-table_02.R +++ b/tests/testthat/test-fda-table_02.R @@ -3,7 +3,7 @@ adsl <- adsl_raw %>% df_explicit_na() test_that("Table 02 generation works with default values", { - result <- make_table_02(adsl) + result <- make_table_02_rtables(adsl) res <- expect_silent(result) expect_snapshot(res) @@ -16,7 +16,7 @@ test_that("Table 02 generation works with custom values", { anl <- dplyr::left_join(adsl, advs, by = "USUBJID") %>% df_explicit_na() - result <- make_table_02( + result <- make_table_02_rtables( anl, vars = c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY", "AVAL"), lbl_vars = c( @@ -44,7 +44,7 @@ test_that("Table 02 generation works with some NA values", { adsl <- adsl %>% df_explicit_na() - result <- make_table_02(adsl, vars = "SEX", lbl_vars = "Sex") + result <- make_table_02_rtables(adsl, vars = "SEX", lbl_vars = "Sex") res <- expect_silent(result) expect_snapshot(res) From ccb50a084f8425b0f7bd0069b55cf7b536d07629 Mon Sep 17 00:00:00 2001 From: ayogasekaram Date: Mon, 11 Nov 2024 16:00:54 +0000 Subject: [PATCH 03/21] new table_02 function using gtsummary and ards --- R/fda-table_02.R | 312 ++++--------------------------------------- man/make_table_02.Rd | 76 ++--------- 2 files changed, 33 insertions(+), 355 deletions(-) diff --git a/R/fda-table_02.R b/R/fda-table_02.R index b2f3066c..d129fead 100644 --- a/R/fda-table_02.R +++ b/R/fda-table_02.R @@ -1,8 +1,7 @@ #' FDA Table 2: Baseline Demographic and Clinical Characteristics, Safety Population, Pooled Analyses #' #' @details -#' * `data` must contain the variables specified by `continuous_vars`, and `categorical_vars`. -#' * `tbl_engine` must be one of `gtsummary`, `rtables`, `tplyr`. +#' * `data` must contain the variables specified by `vars`. #' * `return_ard` set to `TRUE` or `FALSE`; whether the intermediate ARD object should be returned. #' #' @inheritParams argument_convention @@ -13,7 +12,7 @@ NULL #' @describeIn make_table_02 Create FDA table 2 using an ARD. #' #' @return -#' * `make_table_02` returns an object matching the selected `tbl_engine` argument. +#' * `make_table_02` returns a list containing a gtsummary table object. #' The intermediary `ARD` object can also be returned with `return_ard` set to `TRUE`. #' #' @examples @@ -25,7 +24,7 @@ NULL #' AGE >= 65 ~ ">=65", #' AGE >= 65 & AGE < 75 ~ ">=65 to <75", #' AGE >= 75 ~ ">=75" -#' )) +#' ))) #' #' tbl <- make_table_02(data = adsl) #' tbl @@ -33,292 +32,27 @@ NULL #' @export make_table_02 <- function(data, + show_colcounts = TRUE, + arm_var = "ARM", + saffl_var = "SAFFL", + vars = c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY"), + lbl_vars = formatters::var_labels(data, fill = TRUE)[vars], + lbl_overall = "Total Population", + na_rm = FALSE, ..., - tbl_engine = "gtsummary", return_ard = TRUE) { # check data viability - assert_subset(continuous_vars, names(data)) - assert_subset(categorical_vars, names(data)) + checkmate::assert_subset(c(vars, arm_var, saffl_var), names(data)) + assert_flag_variables(data, saffl_var) - if (tbl_engine == "rtables") { - ard <- "ARD not available for {rtables}" - tbl <- make_table_02_rtables(df = data) - } else { - ard <- make_ard_02(...) - # commenting out this table building portion until package refactor - # if (tbl_engine == "gtsummary") { - # tbl <- make_table_02_gtsum(ard, ...) - # } else { - # tbl <- make_table_02_tplyr(ard, ...) - # } - } - - if (return_ard) { - res <- list(ard = ard) - } else { - res <- tbl - } -} - -#' @keywords Internal -make_ard_02 <- function(data = data, - by = "ARM", - continuous_vars = c("AGE"), - categorical_vars = c("SEX", "AGEGR1", "RACE", "ETHNIC")) { - ard <- cards::ard_stack( - data = data, - by = by, - cards::ard_continuous( - variables = continuous_vars, - statistic = ~ continuous_summary_fns(c("mean", "sd", "median", "min", "max")) - ), - cards::ard_categorical(variables = categorical_vars) - ) - - return(ard) -} - - -#' @keywords Internal -make_table_02_rtables <- function(df, - alt_counts_df = NULL, - show_colcounts = TRUE, - arm_var = "ARM", - saffl_var = "SAFFL", - vars = c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY"), - lbl_vars = formatters::var_labels(df, fill = TRUE)[vars], - lbl_overall = "Total Population", - na_rm = FALSE, - prune_0 = TRUE, - annotations = NULL) { - assert_subset(c(vars, arm_var, saffl_var), names(df)) - assert_flag_variables(df, saffl_var) - - df <- df %>% - filter(.data[[saffl_var]] == "Y") %>% - df_explicit_na() - - alt_counts_df <- alt_counts_df_preproc(alt_counts_df, id_var, arm_var, saffl_var) - - lyt <- basic_table_annot(show_colcounts, annotations) %>% - split_cols_by_arm(arm_var, lbl_overall) %>% - analyze_vars( - vars = vars, - var_labels = lbl_vars, - show_labels = "visible", - .stats = c("mean_sd", "median_range", "count_fraction"), - .formats = NULL, - na.rm = na_rm - ) %>% - append_topleft("Characteristic") - - tbl <- build_table(lyt, df = df, alt_counts_df = alt_counts_df) - if (prune_0) tbl <- prune_table(tbl) - - tbl -} - -#' @describeIn make_table_02 Create FDA table 2 using functions from `Tplyr` and `tfrmt`. -#' -#' @param tplyr_raw (`flag`)\cr whether the raw `tibble` created using `Tplyr` functions should be returned, or the -#' table formatted using functions from `tfrmt` should be returned (default). -#' -#' @note -#' * `make_table_02_tplyr` does not currently support footnote annotations -#' * `make_table_02_tplyr` does not currently support `alt_counts_df` when `tplyr_raw = TRUE`. -#' -#' @return -#' * `make_table_02_tplyr` returns a `gt_tbl` object when `tplyr_raw = FALSE` (default) and -#' a `tibble` object when `tplyr_raw = TRUE`. -#' -#' @examples -#' tbl <- make_table_02_tplyr(df = adsl) -#' tbl -#' -#' @keywords Internal -make_table_02_tplyr <- function(df, - alt_counts_df = NULL, - show_colcounts = TRUE, - arm_var = "ARM", - saffl_var = "SAFFL", - vars = c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY"), - lbl_vars = formatters::var_labels(df, fill = TRUE)[vars], - lbl_overall = "Total Population", - na_rm = FALSE, - prune_0 = TRUE, - annotations = NULL, - tplyr_raw = FALSE) { - assert_subset(c(saffl_var, vars, arm_var), names(df)) - assert_flag_variables(df, saffl_var) - - df <- df %>% df_explicit_na() - for (lbl in lbl_vars) { - df[[lbl]] <- lbl - } - - var_types <- lapply(df[vars], function(x) if (is.numeric(x)) "numeric" else "count") - - lyt <- tplyr_table(df, treat_var = !!sym(arm_var), where = !!sym(saffl_var) == "Y") - - if (!is.null(lbl_overall)) lyt <- lyt %>% add_total_group(group_name = lbl_overall) - - for (i in seq_along(vars)) { - var <- vars[i] - var_lbl <- lbl_vars[i] - if (var_types[[var]] == "numeric") { - if (tplyr_raw) { - lyt <- lyt %>% add_layer( - group_desc(vars(!!sym(var)), by = !!sym(var_lbl)) %>% - set_format_strings( - "Mean (SD)" = f_str("xx.x (xx.x)", mean, sd), - "Median (Min - Max)" = f_str("xx.x (xx.x - xx.x)", median, min, max) - ) - ) - } else { - lyt <- lyt %>% add_layer( - group_desc(vars(!!sym(var)), by = !!sym(var_lbl)) %>% - set_format_strings( - "Mean" = f_str("xx.xxxx", mean), "SD" = f_str("xx.xxxx", sd), "Median" = f_str("xx.xxxx", median), - "Min" = f_str("xx.xxxx", min), "Max" = f_str("xx.xxxx", max) - ) - ) - } - } else { - if (tplyr_raw) { - lyt <- lyt %>% add_layer( - group_count(vars(!!sym(var)), by = !!sym(var_lbl)) %>% - set_format_strings(f_str("xx (xx.x%)", n, pct)) - ) - } else { - lyt <- lyt %>% add_layer( - group_count(vars(!!sym(var)), by = !!sym(var_lbl)) %>% - set_format_strings(f_str("xx;xx.xxxx", n, pct)) - ) - } - } - } - tbl <- lyt %>% build() - - if (na_rm) { - na_ind <- tbl[, 2] != "" - tbl <- tbl[na_ind, ] - } - - if (tplyr_raw) { - tbl <- tbl %>% - arrange(ord_layer_index, ord_layer_1, ord_layer_2) %>% - apply_row_masks(row_breaks = TRUE) %>% - select(starts_with("row_label"), starts_with("var1_")) %>% - add_column_headers( - paste0( - "Characteristic | | ", - paste0( - levels(df[[arm_var]]), if (show_colcounts) paste0("\n(N=**", levels(df[[arm_var]]), "**)| ") else "| ", - collapse = "" - ), - ifelse(!is.null(lbl_overall), paste0(lbl_overall, ifelse(show_colcounts, c("\n(N=**Total**)"), ""), "")) - ), - header_n = header_n(lyt) - ) - - if (prune_0) { - prune_ind <- apply(tbl, MARGIN = 1, function(x) all(x == "") || !all(gsub("[0()\\% ]", "", x[-c(1:2)]) == "")) - tbl <- tbl[prune_ind, ] - } - } else { - tbl <- tbl %>% - tidyr::pivot_longer(head(names(.)[-c(1:2)], -3), names_to = "column", values_to = "value") %>% - mutate( - tbl_lbl = "Characteristic", - column = gsub("var1_", "", column), - param = ifelse(row_label2 %in% c("Mean", "SD", "Median", "Min", "Max"), row_label2, "n;pct"), - row_label2 = case_when( - row_label2 %in% c("Mean", "SD") ~ "Mean (SD)", - row_label2 %in% c("Median", "Min", "Max") ~ "Median (Min - Max)", - .default = row_label2 - ) - ) %>% - tidyr::separate_rows(c("param", "value"), sep = ";") %>% - mutate(value = as.numeric(value)) - - if (show_colcounts) { - colcounts <- summary(if (!is.null(alt_counts_df)) alt_counts_df[[arm_var]] else df[[arm_var]]) - big_ns <- tibble( - column = c(levels(df[[arm_var]]), lbl_overall), - param = "bigN", - value = if (!is.null(lbl_overall)) c(colcounts, sum(colcounts)) else colcounts, - ) - tbl <- bind_rows(tbl, big_ns) - } - - if (prune_0) { - tbl <- tbl %>% - group_by(ord_layer_index, ord_layer_2) %>% - filter(sum(value) > 0) %>% - ungroup() - } - big_n_tbl <- if (show_colcounts) big_n_structure(param_val = "bigN", n_frmt = frmt("\n(N=xx)")) else NULL - - tbl <- tfrmt( - group = c(tbl_lbl, row_label1), - label = row_label2, - column = column, - param = param, - value = value, - title = annotations[["title"]], - subtitle = paste(annotations[["subtitles"]], collapse = ", "), - sorting_cols = c(ord_layer_1, ord_layer_2), - body_plan = body_plan( - frmt_structure( - group_val = ".default", label_val = ".default", - frmt_combine("{n} {pct}", n = frmt("xx"), pct = frmt_when("==0" ~ "", TRUE ~ frmt("(xx.x%)"))) - ), - frmt_structure( - group_val = ".default", label_val = "Mean (SD)", - frmt_combine("{Mean} ({SD})", Mean = frmt("xx.x"), SD = frmt("xx.x")) - ), - frmt_structure( - group_val = ".default", label_val = "Median (Min - Max)", - frmt_combine("{Median} ({Min} - {Max})", Median = frmt("xx.x"), Min = frmt("xx.x"), Max = frmt("xx.x")) - ) - ), - col_plan = col_plan(-starts_with("ord")), - big_n = big_n_tbl - ) %>% - print_to_gt(tbl) - } - tbl -} - -#' @describeIn make_table_02 Create FDA table 2 using functions from `gtsummary`. -#' -#' @return -#' * `make_table_02_gtsum` returns a `tbl_summary` object. -#' -#' @examples -#' tbl <- make_table_02_gtsum(df = adsl) -#' tbl -#' -#' @keywords Internal -make_table_02_gtsum <- function(df, - show_colcounts = TRUE, - arm_var = "ARM", - saffl_var = "SAFFL", - vars = c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY"), - lbl_vars = formatters::var_labels(df, fill = TRUE)[vars], - lbl_overall = "Total Population", - na_rm = FALSE) { - assert_subset(c(vars, arm_var, saffl_var), names(df)) - assert_flag_variables(df, saffl_var) - - df <- df %>% + df <- data %>% filter(.data[[saffl_var]] == "Y") %>% select(all_of(c(vars, arm_var))) if (!na_rm) df <- df %>% df_explicit_na() tbl <- df %>% - tbl_summary( + gtsummary::tbl_summary( by = arm_var, type = all_continuous() ~ "continuous2", statistic = list( @@ -333,16 +67,16 @@ make_table_02_gtsum <- function(df, label = as.list(lbl_vars) %>% setNames(vars) ) %>% gtsummary::bold_labels() %>% - modify_header(all_stat_cols() ~ "**{level}** \nN = {n}") %>% - add_overall(last = TRUE, col_label = paste0("**", lbl_overall, "** \nN = {n}")) %>% + gtsummary::modify_header(all_stat_cols() ~ "**{level}** \nN = {n}") %>% + gtsummary::add_overall(last = TRUE, col_label = paste0("**", lbl_overall, "** \nN = {n}")) %>% gtsummary::add_stat_label(label = all_continuous2() ~ c("Mean (SD)", "Median (min - max)")) %>% - modify_footnote(update = everything() ~ NA) %>% + gtsummary::modify_footnote(update = everything() ~ NA) %>% gtsummary::modify_column_alignment(columns = all_stat_cols(), align = "right") - gtsummary::with_gtsummary_theme( - x = gtsummary::theme_gtsummary_compact(), - expr = as_gt(tbl) - ) + if (return_ard) { + ard <- gtsummary::gather_ard(tbl) + res <- list(tbl = tbl, ard = ard) + } else { + res <- list(tbl = tbl) + } } - - diff --git a/man/make_table_02.Rd b/man/make_table_02.Rd index b6baf1a5..d08458b8 100644 --- a/man/make_table_02.Rd +++ b/man/make_table_02.Rd @@ -2,43 +2,22 @@ % Please edit documentation in R/fda-table_02.R \name{make_table_02} \alias{make_table_02} -\alias{make_table_02_tplyr} -\alias{make_table_02_gtsum} \title{FDA Table 2: Baseline Demographic and Clinical Characteristics, Safety Population, Pooled Analyses} \usage{ -make_table_02(data, ..., tbl_engine = "gtsummary", return_ard = TRUE) - -make_table_02_tplyr( - df, - alt_counts_df = NULL, +make_table_02( + data, show_colcounts = TRUE, arm_var = "ARM", saffl_var = "SAFFL", vars = c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY"), - lbl_vars = formatters::var_labels(df, fill = TRUE)[vars], + lbl_vars = formatters::var_labels(data, fill = TRUE)[vars], lbl_overall = "Total Population", na_rm = FALSE, - prune_0 = TRUE, - annotations = NULL, - tplyr_raw = FALSE -) - -make_table_02_gtsum( - df, - show_colcounts = TRUE, - arm_var = "ARM", - saffl_var = "SAFFL", - vars = c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY"), - lbl_vars = formatters::var_labels(df, fill = TRUE)[vars], - lbl_overall = "Total Population", - na_rm = FALSE + ..., + return_ard = TRUE ) } \arguments{ -\item{df}{(\code{data.frame})\cr dataset required to build table.} - -\item{alt_counts_df}{(\code{character})\cr alternative dataset (typically ADSL) used only to calculate column counts.} - \item{show_colcounts}{(\code{flag})\cr Whether column counts should be printed. Boolean.} \item{arm_var}{(\code{character})\cr Name of the treatment arm variable used to split table into columns.} @@ -54,55 +33,27 @@ in the table. Labels should be ordered according to the order of variables in \c the given value as the column label.} \item{na_rm}{(\code{flag})\cr whether \code{NA} levels should be removed from the table.} - -\item{prune_0}{(\code{flag})\cr Whether all-zero rows should be removed from the table. Boolean.} - -\item{annotations}{(named \code{list} of \code{character})\cr list of annotations to add to the table. Valid -annotation types are \code{title}, \code{subtitles}, \code{main_footer}, and \code{prov_footer}. Each name-value pair should -use the annotation type as name and the desired string as value.} - -\item{tplyr_raw}{(\code{flag})\cr whether the raw \code{tibble} created using \code{Tplyr} functions should be returned, or the -table formatted using functions from \code{tfrmt} should be returned (default).} } \value{ \itemize{ -\item \code{make_table_02} returns an object matching the selected \code{tbl_engine} argument. +\item \code{make_table_02} returns a list containing a gtsummary table object. The intermediary \code{ARD} object can also be returned with \code{return_ard} set to \code{TRUE}. } - -\itemize{ -\item \code{make_table_02_tplyr} returns a \code{gt_tbl} object when \code{tplyr_raw = FALSE} (default) and -a \code{tibble} object when \code{tplyr_raw = TRUE}. -} - -\itemize{ -\item \code{make_table_02_gtsum} returns a \code{tbl_summary} object. -} } \description{ FDA Table 2: Baseline Demographic and Clinical Characteristics, Safety Population, Pooled Analyses } \details{ \itemize{ -\item \code{data} must contain the variables specified by \code{continuous_vars}, and \code{categorical_vars}. -\item \code{tbl_engine} must be one of \code{gtsummary}, \code{rtables}, \code{tplyr}. +\item \code{data} must contain the variables specified by \code{vars}. +\item \code{return_ard} set to \code{TRUE} or \code{FALSE}; whether the intermediate ARD object should be returned. } } \section{Functions}{ \itemize{ -\item \code{make_table_02()}: Create FDA table 2 using functions from \code{rtables} and \code{tern}. - -\item \code{make_table_02_tplyr()}: Create FDA table 2 using functions from \code{Tplyr} and \code{tfrmt}. - -\item \code{make_table_02_gtsum()}: Create FDA table 2 using functions from \code{gtsummary}. +\item \code{make_table_02()}: Create FDA table 2 using an ARD. }} -\note{ -\itemize{ -\item \code{make_table_02_tplyr} does not currently support footnote annotations -\item \code{make_table_02_tplyr} does not currently support \code{alt_counts_df} when \code{tplyr_raw = TRUE}. -} -} \examples{ library(dplyr) @@ -112,16 +63,9 @@ adsl <- random.cdisc.data::cadsl \%>\% AGE >= 65 ~ ">=65", AGE >= 65 & AGE < 75 ~ ">=65 to <75", AGE >= 75 ~ ">=75" - )) + ))) tbl <- make_table_02(data = adsl) tbl -tbl <- make_table_02_tplyr(df = adsl) -tbl - -tbl <- make_table_02_gtsum(df = adsl) -tbl - } -\keyword{Internal} From f0daa13caa3c01a1c69c04a8d765e6fe7424c693 Mon Sep 17 00:00:00 2001 From: ayogasekaram Date: Mon, 11 Nov 2024 17:09:01 +0000 Subject: [PATCH 04/21] update tests, update spelling, update quarto page --- R/fda-table_02.R | 6 +- quarto/table-templates/template-table_02.qmd | 117 +---- tests/testthat/_snaps/fda-table_02.md | 427 ++++--------------- tests/testthat/test-fda-table_02.R | 146 +------ 4 files changed, 96 insertions(+), 600 deletions(-) diff --git a/R/fda-table_02.R b/R/fda-table_02.R index d129fead..a4774342 100644 --- a/R/fda-table_02.R +++ b/R/fda-table_02.R @@ -12,7 +12,7 @@ NULL #' @describeIn make_table_02 Create FDA table 2 using an ARD. #' #' @return -#' * `make_table_02` returns a list containing a gtsummary table object. +#' * `make_table_02` returns a list containing a `gtsummary` table object. #' The intermediary `ARD` object can also be returned with `return_ard` set to `TRUE`. #' #' @examples @@ -35,7 +35,7 @@ make_table_02 <- function(data, show_colcounts = TRUE, arm_var = "ARM", saffl_var = "SAFFL", - vars = c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY"), + vars = c("SEX", "AGE", "RACE", "ETHNIC", "COUNTRY"), lbl_vars = formatters::var_labels(data, fill = TRUE)[vars], lbl_overall = "Total Population", na_rm = FALSE, @@ -70,7 +70,7 @@ make_table_02 <- function(data, gtsummary::modify_header(all_stat_cols() ~ "**{level}** \nN = {n}") %>% gtsummary::add_overall(last = TRUE, col_label = paste0("**", lbl_overall, "** \nN = {n}")) %>% gtsummary::add_stat_label(label = all_continuous2() ~ c("Mean (SD)", "Median (min - max)")) %>% - gtsummary::modify_footnote(update = everything() ~ NA) %>% + gtsummary::modify_footnote(everything() ~ NA) %>% gtsummary::modify_column_alignment(columns = all_stat_cols(), align = "right") if (return_ard) { diff --git a/quarto/table-templates/template-table_02.qmd b/quarto/table-templates/template-table_02.qmd index 9de0066b..ea757af3 100644 --- a/quarto/table-templates/template-table_02.qmd +++ b/quarto/table-templates/template-table_02.qmd @@ -36,77 +36,7 @@ anl <- left_join(adsl, advs, by = "USUBJID") # Output Table make_table_02( - df = anl, - vars = c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY", "AVAL"), - lbl_vars = c( - "Sex", "Age, years", "Age Group, years", "Race", "Ethnicity", - "Country of Participation", "Baseline Temperature (C)" - ) -) -``` - -## rtables Table Setup - -```{r tbl, eval=FALSE, echo=TRUE} -``` - -## Function Details: `make_table_02` - -### `make_table_02()` - ------------------------------------------------------------------------- - -Required variables: - -- **`df`**: The variables specified by `vars`, `arm_var`, and `saffl_var`. -- **`alt_counts_df`** (if specified): `USUBJID` and the variables specified by `arm_var` and `saffl_var`. - -| **Argument** | **Description** | **Default** | -|:-----------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------| -| `df` | (`data.frame`) Dataset (typically ADSL) required to build table. | *No default* | -| `alt_counts_df` | (`character`) Alternative dataset used only to calculate column counts. | `NULL` | -| `show_colcounts` | (`flag`) Whether column counts should be printed. | `TRUE` | -| `arm_var` | (`character`) Arm variable used to split table into columns. | `"ARM"` | -| `saffl_var` | (`character`) Flag variable used to indicate inclusion in safety population. | `"SAFFL"` | -| `vars` | (`character`) Variables from `df` to include in the table. | `c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY")` | -| `lbl_vars` | (`character`) Labels corresponding to variables in `vars` to print in the table. Labels should be ordered according to the order of variables in `vars`. | `formatters::var_labels(df, fill = TRUE)[vars]` | -| `lbl_overall` | (`character`) If specified, an overall column will be added to the table with the given value as the column label. | `"Total Population"` | -| `.stats` | (`character`) Statistics to include in the table. Includes statistics for all variable types (only the statistics that are valid for a given variable's type will be printed). See [`tern::analyze_vars()`](https://insightsengineering.github.io/tern/main/reference/analyze_variables.html#value) for options. | `c("mean_sd", "median_range", "count_fraction")` | -| `.formats` | (named `list` of `character`) List of formats corresponding to each value in `.stats`. Each name is a value in `.stats` and the corresponding value is the format that should be applied to that statistic. See [`formatters::list_valid_format_labels()`](https://insightsengineering.github.io/formatters/main/reference/list_valid_format_labels.html#ref-examples) for a list of valid formats. | `NULL` | -| `prune_0` | (`flag`) Whether all-zero rows should be removed from the table. | `TRUE` | -| `na_rm` | (`flag`) Whether `NA` levels should be removed from the table. | `FALSE` | -| `annotations` | (named `list` of `character`) List of annotations to add to the table. Valid annotation types are `title`, `subtitles`, `main_footer`, and `prov_footer.` Each name-value pair should use the annotation type as name and the desired string as value. | `NULL` | - -Source code for this function is available [here](https://github.com/pharmaverse/cardinal/blob/main/R/fda-table_02.R#L39). - -## Tplyr Table - -```{r tbl_tplyr, message=FALSE, warning=FALSE} -# Load Libraries & Data -library(cardinal) -library(dplyr) - -adsl <- random.cdisc.data::cadsl -advs <- random.cdisc.data::cadvs - -# Pre-Processing - Add any variables needed in your table to df -adsl <- adsl %>% - mutate(AGEGR1 = as.factor(case_when( - AGE >= 17 & AGE < 65 ~ ">=17 to <65", - AGE >= 65 ~ ">=65", - AGE >= 65 & AGE < 75 ~ ">=65 to <75", - AGE >= 75 ~ ">=75" - ))) - -advs <- advs %>% - filter(AVISIT == "BASELINE", VSTESTCD == "TEMP") %>% - select("USUBJID", "AVAL") - -anl <- left_join(adsl, advs, by = "USUBJID") - -# Output Table -make_table_02_tplyr( - df = anl, + data = anl, vars = c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY", "AVAL"), lbl_vars = c( "Sex", "Age, years", "Age Group, years", "Race", "Ethnicity", @@ -115,40 +45,7 @@ make_table_02_tplyr( ) ``` -## Tplyr Table Setup - -```{r tbl_tplyr, eval=FALSE, echo=TRUE} -``` - -## Function Details: `make_table_02_tplyr` - -### `make_table_02_tplyr()` - ------------------------------------------------------------------------- - -Required variables: - -- **`df`**: `SAFFL` and the variables specified by `vars` and `arm_var`. -- **`alt_counts_df`** (if specified and `tplyr_raw = FALSE`): `SAFFL`, `USUBJID`, and the variable specified by `arm_var`. - -| **Argument** | **Description** | **Default** | -|:-----------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------| -| `df` | (`data.frame`) Dataset (typically ADSL) required to build table. | *No default* | -| `alt_counts_df` | (`character`) Alternative dataset used only to calculate column counts. | `NULL` | -| `show_colcounts` | (`flag`) Whether column counts should be printed. | `TRUE` | -| `arm_var` | (`character`) Arm variable used to split table into columns. | `"ARM"` | -| `saffl_var` | (`character`) Flag variable used to indicate inclusion in safety population. | `"SAFFL"` | -| `vars` | (`character`) Variables from `df` to include in the table. | `c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY")` | -| `lbl_vars` | (`character`) Labels corresponding to variables in `vars` to print in the table. Labels should be ordered according to the order of variables in `vars`. | `formatters::var_labels(df, fill = TRUE)[vars]` | -| `lbl_overall` | (`character`) If specified, an overall column will be added to the table with the given value as the column label. | `"Total Population"` | -| `prune_0` | (`flag`) Whether all-zero rows should be removed from the table. | `TRUE` | -| `na_rm` | (`flag`) Whether `NA` levels should be removed from the table. | `FALSE` | -| `annotations` | (named `list` of `character`) List of annotations to add to the table. Valid annotation types are `title` and `subtitles.` Each name-value pair should use the annotation type as name and the desired string as value. | `NULL` | -| `tplyr_raw` | (`flag`) Whether the raw `tibble` created using `Tplyr` functions should be returned, or the table formatted using functions from `tfrmt` should be returned (default). | `FALSE` | - -Source code for this function is available [here](https://github.com/pharmaverse/cardinal/blob/main/R/fda-table_02.R#L94). - -## gtsummary Table +## Table ```{r tbl_gtsummary, message=FALSE, warning=FALSE} # Load Libraries & Data @@ -174,7 +71,7 @@ advs <- advs %>% anl <- left_join(adsl, advs, by = "USUBJID") # Output Table -make_table_02_gtsum( +make_table_02( df = anl, vars = c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY", "AVAL"), lbl_vars = c( @@ -189,15 +86,15 @@ make_table_02_gtsum( ```{r tbl_gtsummary, eval=FALSE, echo=TRUE} ``` -## Function Details: `make_table_02_gtsum` +## Function Details: `make_table_02` -### `make_table_02_gtsum()` +### `make_table_02()` ------------------------------------------------------------------------ Required variables: -- **`df`**: `SAFFL` and the variables specified by `vars` and `arm_var`. +- **`data`**: `SAFFL` and the variables specified by `vars` and `arm_var`. - **`alt_counts_df`** (if specified and `tplyr_raw = FALSE`): `SAFFL`, `USUBJID`, and the variable specified by `arm_var`. | **Argument** | **Description** | **Default** | @@ -211,5 +108,5 @@ Required variables: | `lbl_vars` | (`character`) Labels corresponding to variables in `vars` to print in the table. Labels should be ordered according to the order of variables in `vars`. | `formatters::var_labels(df, fill = TRUE)[vars]` | | `lbl_overall` | (`character`) If specified, an overall column will be added to the table with the given value as the column label. | `"Total Population"` | -Source code for this function is available [here](https://github.com/pharmaverse/cardinal/blob/main/R/fda-table_02.R#L257). +Source code for this function is available [here](https://github.com/pharmaverse/cardinal/blob/main/R/fda-table_02.R#L34). ::: diff --git a/tests/testthat/_snaps/fda-table_02.md b/tests/testthat/_snaps/fda-table_02.md index a23f2b1e..2a8a53fb 100644 --- a/tests/testthat/_snaps/fda-table_02.md +++ b/tests/testthat/_snaps/fda-table_02.md @@ -1,367 +1,90 @@ # Table 02 generation works with default values Code - res + as.data.frame(result$tbl) Output - A: Drug X B: Placebo C: Combination Total Population - Characteristic (N=134) (N=134) (N=132) (N=400) - ——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————— - Sex - F 79 (59%) 82 (61.2%) 70 (53%) 231 (57.8%) - M 55 (41%) 52 (38.8%) 62 (47%) 169 (42.2%) - Age - Mean (SD) 33.8 (6.6) 35.4 (7.9) 35.4 (7.7) 34.9 (7.4) - Median (Min - Max) 33.0 (21.0 - 50.0) 35.0 (21.0 - 62.0) 35.0 (20.0 - 69.0) 34.0 (20.0 - 69.0) - Age Group - >=17 to <65 134 (100%) 134 (100%) 131 (99.2%) 399 (99.8%) - >=65 0 0 1 (0.8%) 1 (0.2%) - Race - ASIAN 68 (50.7%) 67 (50%) 73 (55.3%) 208 (52%) - BLACK OR AFRICAN AMERICAN 31 (23.1%) 28 (20.9%) 32 (24.2%) 91 (22.8%) - WHITE 27 (20.1%) 26 (19.4%) 21 (15.9%) 74 (18.5%) - AMERICAN INDIAN OR ALASKA NATIVE 8 (6%) 11 (8.2%) 6 (4.5%) 25 (6.2%) - MULTIPLE 0 1 (0.7%) 0 1 (0.2%) - NATIVE HAWAIIAN OR OTHER PACIFIC ISLANDER 0 1 (0.7%) 0 1 (0.2%) - Ethnicity - HISPANIC OR LATINO 15 (11.2%) 18 (13.4%) 15 (11.4%) 48 (12%) - NOT HISPANIC OR LATINO 104 (77.6%) 103 (76.9%) 101 (76.5%) 308 (77%) - NOT REPORTED 6 (4.5%) 10 (7.5%) 11 (8.3%) 27 (6.8%) - UNKNOWN 9 (6.7%) 3 (2.2%) 5 (3.8%) 17 (4.2%) - Country - CHN 74 (55.2%) 81 (60.4%) 64 (48.5%) 219 (54.8%) - USA 10 (7.5%) 13 (9.7%) 17 (12.9%) 40 (10%) - BRA 13 (9.7%) 7 (5.2%) 10 (7.6%) 30 (7.5%) - PAK 12 (9%) 9 (6.7%) 10 (7.6%) 31 (7.8%) - NGA 8 (6%) 7 (5.2%) 11 (8.3%) 26 (6.5%) - RUS 5 (3.7%) 8 (6%) 6 (4.5%) 19 (4.8%) - JPN 5 (3.7%) 4 (3%) 9 (6.8%) 18 (4.5%) - GBR 4 (3%) 3 (2.2%) 2 (1.5%) 9 (2.2%) - CAN 3 (2.2%) 2 (1.5%) 3 (2.3%) 8 (2%) + **Characteristic** **A: Drug X** \nN = 134 **B: Placebo** \nN = 134 **C: Combination** \nN = 132 **Total Population** \nN = 400 + 1 __Sex, n (%)__ + 2 F 79 (59%) 82 (61%) 70 (53%) 231 (58%) + 3 M 55 (41%) 52 (39%) 62 (47%) 169 (42%) + 4 __Age__ + 5 Mean (SD) 33.8 (6.6) 35.4 (7.9) 35.4 (7.7) 34.9 (7.4) + 6 Median (min - max) 33.0 (21.0 - 50.0) 35.0 (21.0 - 62.0) 35.0 (20.0 - 69.0) 34.0 (20.0 - 69.0) + 7 __Race, n (%)__ + 8 ASIAN 68 (51%) 67 (50%) 73 (55%) 208 (52%) + 9 BLACK OR AFRICAN AMERICAN 31 (23%) 28 (21%) 32 (24%) 91 (23%) + 10 WHITE 27 (20%) 26 (19%) 21 (16%) 74 (19%) + 11 AMERICAN INDIAN OR ALASKA NATIVE 8 (6.0%) 11 (8.2%) 6 (4.5%) 25 (6.3%) + 12 MULTIPLE 0 (0%) 1 (0.7%) 0 (0%) 1 (0.3%) + 13 NATIVE HAWAIIAN OR OTHER PACIFIC ISLANDER 0 (0%) 1 (0.7%) 0 (0%) 1 (0.3%) + 14 OTHER 0 (0%) 0 (0%) 0 (0%) 0 (0%) + 15 UNKNOWN 0 (0%) 0 (0%) 0 (0%) 0 (0%) + 16 __Ethnicity, n (%)__ + 17 HISPANIC OR LATINO 15 (11%) 18 (13%) 15 (11%) 48 (12%) + 18 NOT HISPANIC OR LATINO 104 (78%) 103 (77%) 101 (77%) 308 (77%) + 19 NOT REPORTED 6 (4.5%) 10 (7.5%) 11 (8.3%) 27 (6.8%) + 20 UNKNOWN 9 (6.7%) 3 (2.2%) 5 (3.8%) 17 (4.3%) + 21 __Country, n (%)__ + 22 CHN 74 (55%) 81 (60%) 64 (48%) 219 (55%) + 23 USA 10 (7.5%) 13 (9.7%) 17 (13%) 40 (10%) + 24 BRA 13 (9.7%) 7 (5.2%) 10 (7.6%) 30 (7.5%) + 25 PAK 12 (9.0%) 9 (6.7%) 10 (7.6%) 31 (7.8%) + 26 NGA 8 (6.0%) 7 (5.2%) 11 (8.3%) 26 (6.5%) + 27 RUS 5 (3.7%) 8 (6.0%) 6 (4.5%) 19 (4.8%) + 28 JPN 5 (3.7%) 4 (3.0%) 9 (6.8%) 18 (4.5%) + 29 GBR 4 (3.0%) 3 (2.2%) 2 (1.5%) 9 (2.3%) + 30 CAN 3 (2.2%) 2 (1.5%) 3 (2.3%) 8 (2.0%) + 31 CHE 0 (0%) 0 (0%) 0 (0%) 0 (0%) # Table 02 generation works with custom values Code - res + as.data.frame(result$tbl) Output - Table 2. Baseline Demographic and Clinical Characteristics Safety Population, Pooled Analyses - - ——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————— - A: Drug X B: Placebo C: Combination Total Population - Characteristic (N=134) (N=134) (N=132) (N=400) - ——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————— - Sex - F 79 (59%) 82 (61.2%) 70 (53%) 231 (57.8%) - M 55 (41%) 52 (38.8%) 62 (47%) 169 (42.2%) - Age, years - Mean (SD) 33.8 (6.6) 35.4 (7.9) 35.4 (7.7) 34.9 (7.4) - Median (Min - Max) 33.0 (21.0 - 50.0) 35.0 (21.0 - 62.0) 35.0 (20.0 - 69.0) 34.0 (20.0 - 69.0) - Age Group, years - >=17 to <65 134 (100%) 134 (100%) 131 (99.2%) 399 (99.8%) - >=65 0 0 1 (0.8%) 1 (0.2%) - Race - ASIAN 68 (50.7%) 67 (50%) 73 (55.3%) 208 (52%) - BLACK OR AFRICAN AMERICAN 31 (23.1%) 28 (20.9%) 32 (24.2%) 91 (22.8%) - WHITE 27 (20.1%) 26 (19.4%) 21 (15.9%) 74 (18.5%) - AMERICAN INDIAN OR ALASKA NATIVE 8 (6%) 11 (8.2%) 6 (4.5%) 25 (6.2%) - MULTIPLE 0 1 (0.7%) 0 1 (0.2%) - NATIVE HAWAIIAN OR OTHER PACIFIC ISLANDER 0 1 (0.7%) 0 1 (0.2%) - Ethnicity - HISPANIC OR LATINO 15 (11.2%) 18 (13.4%) 15 (11.4%) 48 (12%) - NOT HISPANIC OR LATINO 104 (77.6%) 103 (76.9%) 101 (76.5%) 308 (77%) - NOT REPORTED 6 (4.5%) 10 (7.5%) 11 (8.3%) 27 (6.8%) - UNKNOWN 9 (6.7%) 3 (2.2%) 5 (3.8%) 17 (4.2%) - Country of Participation - CHN 74 (55.2%) 81 (60.4%) 64 (48.5%) 219 (54.8%) - USA 10 (7.5%) 13 (9.7%) 17 (12.9%) 40 (10%) - BRA 13 (9.7%) 7 (5.2%) 10 (7.6%) 30 (7.5%) - PAK 12 (9%) 9 (6.7%) 10 (7.6%) 31 (7.8%) - NGA 8 (6%) 7 (5.2%) 11 (8.3%) 26 (6.5%) - RUS 5 (3.7%) 8 (6%) 6 (4.5%) 19 (4.8%) - JPN 5 (3.7%) 4 (3%) 9 (6.8%) 18 (4.5%) - GBR 4 (3%) 3 (2.2%) 2 (1.5%) 9 (2.2%) - CAN 3 (2.2%) 2 (1.5%) 3 (2.3%) 8 (2%) - Baseline Temperature (C) - Mean (SD) 36.7 (1.0) 36.6 (1.1) 36.5 (1.0) 36.6 (1.0) - Median (Min - Max) 36.7 (34.0 - 39.3) 36.6 (33.6 - 38.9) 36.5 (34.2 - 38.9) 36.6 (33.6 - 39.3) - ——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————— - - Source: [include Applicant source, datasets and/or software tools used]. - - Abbreviations: N, number of patients in treatment arm; n, number of patients with given characteristic; SD, standard deviation - -# Table 02 generation works with some NA values - - Code - res - Output - A: Drug X B: Placebo C: Combination Total Population - Characteristic (N=134) (N=134) (N=132) (N=400) - ———————————————————————————————————————————————————————————————————————————— - Sex - F 68 (50.7%) 68 (50.7%) 62 (47%) 198 (49.5%) - M 50 (37.3%) 48 (35.8%) 54 (40.9%) 152 (38%) - 16 (11.9%) 18 (13.4%) 16 (12.1%) 50 (12.5%) - -# Table 02 generation (tplyr) works with default values - - Code - res - Output - # A tibble: 32 x 6 - row_label2 `A: Drug X\n(N=134)` `B: Placebo\n(N=134)` `C: Combination\n(N=132)` `Total Population\n(N=400)` ..tfrmt_row_grp_lbl - - 1 "Characteristic" TRUE - 2 " Sex" TRUE - 3 " F" "79 (59.0%)" "82 (61.2%)" "70 (53.0%)" "231 (57.8%)" FALSE - 4 " M" "55 (41.0%)" "52 (38.8%)" "62 (47.0%)" "169 (42.2%)" FALSE - 5 " Age" TRUE - 6 " Mean (SD)" "33.8 ( 6.6)" "35.4 ( 7.9)" "35.4 ( 7.7)" "34.9 ( 7.4)" FALSE - 7 " Median (Min - Max)" "33.0 (21.0 - 50.0)" "35.0 (21.0 - 62.0)" "35.0 (20.0 - 69.0)" "34.0 (20.0 - 69.0)" FALSE - 8 " Age Group" TRUE - 9 " >=17 to <65" "134 (100.0%)" "134 (100.0%)" "131 (99.2%)" "399 (99.8%)" FALSE - 10 " >=65" " 0 " " 0 " " 1 ( 0.8%)" " 1 ( 0.2%)" FALSE - 11 " Race" TRUE - 12 " ASIAN" "68 (50.7%)" "67 (50.0%)" "73 (55.3%)" "208 (52.0%)" FALSE - 13 " BLACK OR AFRICAN AMERICAN" "31 (23.1%)" "28 (20.9%)" "32 (24.2%)" "91 (22.8%)" FALSE - 14 " WHITE" "27 (20.1%)" "26 (19.4%)" "21 (15.9%)" "74 (18.5%)" FALSE - 15 " AMERICAN INDIAN OR ALASKA NATIVE" " 8 ( 6.0%)" "11 ( 8.2%)" " 6 ( 4.5%)" "25 ( 6.2%)" FALSE - 16 " MULTIPLE" " 0 " " 1 ( 0.7%)" " 0 " " 1 ( 0.2%)" FALSE - 17 " NATIVE HAWAIIAN OR OTHER PACIFIC ISLANDER" " 0 " " 1 ( 0.7%)" " 0 " " 1 ( 0.2%)" FALSE - 18 " Ethnicity" TRUE - 19 " HISPANIC OR LATINO" "15 (11.2%)" "18 (13.4%)" "15 (11.4%)" "48 (12.0%)" FALSE - 20 " NOT HISPANIC OR LATINO" "104 (77.6%)" "103 (76.9%)" "101 (76.5%)" "308 (77.0%)" FALSE - 21 " NOT REPORTED" " 6 ( 4.5%)" "10 ( 7.5%)" "11 ( 8.3%)" "27 ( 6.8%)" FALSE - 22 " UNKNOWN" " 9 ( 6.7%)" " 3 ( 2.2%)" " 5 ( 3.8%)" "17 ( 4.2%)" FALSE - 23 " Country" TRUE - 24 " CHN" "74 (55.2%)" "81 (60.4%)" "64 (48.5%)" "219 (54.8%)" FALSE - 25 " USA" "10 ( 7.5%)" "13 ( 9.7%)" "17 (12.9%)" "40 (10.0%)" FALSE - 26 " BRA" "13 ( 9.7%)" " 7 ( 5.2%)" "10 ( 7.6%)" "30 ( 7.5%)" FALSE - 27 " PAK" "12 ( 9.0%)" " 9 ( 6.7%)" "10 ( 7.6%)" "31 ( 7.8%)" FALSE - 28 " NGA" " 8 ( 6.0%)" " 7 ( 5.2%)" "11 ( 8.3%)" "26 ( 6.5%)" FALSE - 29 " RUS" " 5 ( 3.7%)" " 8 ( 6.0%)" " 6 ( 4.5%)" "19 ( 4.8%)" FALSE - 30 " JPN" " 5 ( 3.7%)" " 4 ( 3.0%)" " 9 ( 6.8%)" "18 ( 4.5%)" FALSE - 31 " GBR" " 4 ( 3.0%)" " 3 ( 2.2%)" " 2 ( 1.5%)" " 9 ( 2.2%)" FALSE - 32 " CAN" " 3 ( 2.2%)" " 2 ( 1.5%)" " 3 ( 2.3%)" " 8 ( 2.0%)" FALSE - -# Table 02 generation (tplyr) works with `tplyr_raw` = TRUE - - Code - res - Output - # A tibble: 35 x 6 - row_label1 row_label2 `var1_A: Drug X` `var1_B: Placebo` `var1_C: Combination` `var1_Total Population` - - 1 "Characteristic" "" "A: Drug X\n(N=134)" "B: Placebo\n(N=134)" "C: Combination\n(N=132)" "Total Population\n(N=0)" - 2 "Sex" "F" "79 (59.0%)" "82 (61.2%)" "70 (53.0%)" "231 (57.8%)" - 3 "" "M" "55 (41.0%)" "52 (38.8%)" "62 (47.0%)" "169 (42.2%)" - 4 "" "" "" "" "" "" - 5 "Age" "Mean (SD)" "33.8 ( 6.6)" "35.4 ( 7.9)" "35.4 ( 7.7)" "34.9 ( 7.4)" - 6 "" "Median (Min - Max)" "33.0 (21.0 - 50.0)" "35.0 (21.0 - 62.0)" "35.0 (20.0 - 69.0)" "34.0 (20.0 - 69.0)" - 7 "" "" "" "" "" "" - 8 "Age Group" ">=17 to <65" "134 (100.0%)" "134 (100.0%)" "131 (99.2%)" "399 (99.8%)" - 9 "" ">=65" " 0 ( 0.0%)" " 0 ( 0.0%)" " 1 ( 0.8%)" " 1 ( 0.2%)" - 10 "" "" "" "" "" "" - 11 "Race" "ASIAN" "68 (50.7%)" "67 (50.0%)" "73 (55.3%)" "208 (52.0%)" - 12 "" "BLACK OR AFRICAN AMERICAN" "31 (23.1%)" "28 (20.9%)" "32 (24.2%)" "91 (22.8%)" - 13 "" "WHITE" "27 (20.1%)" "26 (19.4%)" "21 (15.9%)" "74 (18.5%)" - 14 "" "AMERICAN INDIAN OR ALASKA NATIVE" " 8 ( 6.0%)" "11 ( 8.2%)" " 6 ( 4.5%)" "25 ( 6.2%)" - 15 "" "MULTIPLE" " 0 ( 0.0%)" " 1 ( 0.7%)" " 0 ( 0.0%)" " 1 ( 0.2%)" - 16 "" "NATIVE HAWAIIAN OR OTHER PACIFIC ISLANDER" " 0 ( 0.0%)" " 1 ( 0.7%)" " 0 ( 0.0%)" " 1 ( 0.2%)" - 17 "" "OTHER" " 0 ( 0.0%)" " 0 ( 0.0%)" " 0 ( 0.0%)" " 0 ( 0.0%)" - 18 "" "UNKNOWN" " 0 ( 0.0%)" " 0 ( 0.0%)" " 0 ( 0.0%)" " 0 ( 0.0%)" - 19 "" "" "" "" "" "" - 20 "Ethnicity" "HISPANIC OR LATINO" "15 (11.2%)" "18 (13.4%)" "15 (11.4%)" "48 (12.0%)" - 21 "" "NOT HISPANIC OR LATINO" "104 (77.6%)" "103 (76.9%)" "101 (76.5%)" "308 (77.0%)" - 22 "" "NOT REPORTED" " 6 ( 4.5%)" "10 ( 7.5%)" "11 ( 8.3%)" "27 ( 6.8%)" - 23 "" "UNKNOWN" " 9 ( 6.7%)" " 3 ( 2.2%)" " 5 ( 3.8%)" "17 ( 4.2%)" - 24 "" "" "" "" "" "" - 25 "Country" "CHN" "74 (55.2%)" "81 (60.4%)" "64 (48.5%)" "219 (54.8%)" - 26 "" "USA" "10 ( 7.5%)" "13 ( 9.7%)" "17 (12.9%)" "40 (10.0%)" - 27 "" "BRA" "13 ( 9.7%)" " 7 ( 5.2%)" "10 ( 7.6%)" "30 ( 7.5%)" - 28 "" "PAK" "12 ( 9.0%)" " 9 ( 6.7%)" "10 ( 7.6%)" "31 ( 7.8%)" - 29 "" "NGA" " 8 ( 6.0%)" " 7 ( 5.2%)" "11 ( 8.3%)" "26 ( 6.5%)" - 30 "" "RUS" " 5 ( 3.7%)" " 8 ( 6.0%)" " 6 ( 4.5%)" "19 ( 4.8%)" - 31 "" "JPN" " 5 ( 3.7%)" " 4 ( 3.0%)" " 9 ( 6.8%)" "18 ( 4.5%)" - 32 "" "GBR" " 4 ( 3.0%)" " 3 ( 2.2%)" " 2 ( 1.5%)" " 9 ( 2.2%)" - 33 "" "CAN" " 3 ( 2.2%)" " 2 ( 1.5%)" " 3 ( 2.3%)" " 8 ( 2.0%)" - 34 "" "CHE" " 0 ( 0.0%)" " 0 ( 0.0%)" " 0 ( 0.0%)" " 0 ( 0.0%)" - 35 "" "" "" "" "" "" - -# Table 02 generation (tplyr) works with custom values - - Code - res - Output - # A tibble: 38 x 6 - row_label2 `A: Drug X\n(N=134)` `B: Placebo\n(N=134)` `C: Combination\n(N=132)` `Total Population\n(N=400)` ..tfrmt_row_grp_lbl - - 1 "Characteristic" TRUE - 2 " Sex" TRUE - 3 " F" "79 (59.0%)" "82 (61.2%)" "70 (53.0%)" "231 (57.8%)" FALSE - 4 " M" "55 (41.0%)" "52 (38.8%)" "62 (47.0%)" "169 (42.2%)" FALSE - 5 " Age, years" TRUE - 6 " Mean (SD)" "33.8 ( 6.6)" "35.4 ( 7.9)" "35.4 ( 7.7)" "34.9 ( 7.4)" FALSE - 7 " Median (Min - Max)" "33.0 (21.0 - 50.0)" "35.0 (21.0 - 62.0)" "35.0 (20.0 - 69.0)" "34.0 (20.0 - 69.0)" FALSE - 8 " Age Group, years" TRUE - 9 " >=17 to <65" "134 (100.0%)" "134 (100.0%)" "131 (99.2%)" "399 (99.8%)" FALSE - 10 " >=65" " 0 " " 0 " " 1 ( 0.8%)" " 1 ( 0.2%)" FALSE - 11 " Race" TRUE - 12 " ASIAN" "68 (50.7%)" "67 (50.0%)" "73 (55.3%)" "208 (52.0%)" FALSE - 13 " BLACK OR AFRICAN AMERICAN" "31 (23.1%)" "28 (20.9%)" "32 (24.2%)" "91 (22.8%)" FALSE - 14 " WHITE" "27 (20.1%)" "26 (19.4%)" "21 (15.9%)" "74 (18.5%)" FALSE - 15 " AMERICAN INDIAN OR ALASKA NATIVE" " 8 ( 6.0%)" "11 ( 8.2%)" " 6 ( 4.5%)" "25 ( 6.2%)" FALSE - 16 " MULTIPLE" " 0 " " 1 ( 0.7%)" " 0 " " 1 ( 0.2%)" FALSE - 17 " NATIVE HAWAIIAN OR OTHER PACIFIC ISLANDER" " 0 " " 1 ( 0.7%)" " 0 " " 1 ( 0.2%)" FALSE - 18 " OTHER" " 0 " " 0 " " 0 " " 0 " FALSE - 19 " UNKNOWN" " 0 " " 0 " " 0 " " 0 " FALSE - 20 " Ethnicity" TRUE - 21 " HISPANIC OR LATINO" "15 (11.2%)" "18 (13.4%)" "15 (11.4%)" "48 (12.0%)" FALSE - 22 " NOT HISPANIC OR LATINO" "104 (77.6%)" "103 (76.9%)" "101 (76.5%)" "308 (77.0%)" FALSE - 23 " NOT REPORTED" " 6 ( 4.5%)" "10 ( 7.5%)" "11 ( 8.3%)" "27 ( 6.8%)" FALSE - 24 " UNKNOWN" " 9 ( 6.7%)" " 3 ( 2.2%)" " 5 ( 3.8%)" "17 ( 4.2%)" FALSE - 25 " Country of Participation" TRUE - 26 " CHN" "74 (55.2%)" "81 (60.4%)" "64 (48.5%)" "219 (54.8%)" FALSE - 27 " USA" "10 ( 7.5%)" "13 ( 9.7%)" "17 (12.9%)" "40 (10.0%)" FALSE - 28 " BRA" "13 ( 9.7%)" " 7 ( 5.2%)" "10 ( 7.6%)" "30 ( 7.5%)" FALSE - 29 " PAK" "12 ( 9.0%)" " 9 ( 6.7%)" "10 ( 7.6%)" "31 ( 7.8%)" FALSE - 30 " NGA" " 8 ( 6.0%)" " 7 ( 5.2%)" "11 ( 8.3%)" "26 ( 6.5%)" FALSE - 31 " RUS" " 5 ( 3.7%)" " 8 ( 6.0%)" " 6 ( 4.5%)" "19 ( 4.8%)" FALSE - 32 " JPN" " 5 ( 3.7%)" " 4 ( 3.0%)" " 9 ( 6.8%)" "18 ( 4.5%)" FALSE - 33 " GBR" " 4 ( 3.0%)" " 3 ( 2.2%)" " 2 ( 1.5%)" " 9 ( 2.2%)" FALSE - 34 " CAN" " 3 ( 2.2%)" " 2 ( 1.5%)" " 3 ( 2.3%)" " 8 ( 2.0%)" FALSE - 35 " CHE" " 0 " " 0 " " 0 " " 0 " FALSE - 36 " Baseline Temperature (C)" TRUE - 37 " Mean (SD)" "36.7 ( 1.0)" "36.6 ( 1.1)" "36.5 ( 1.0)" "36.6 ( 1.0)" FALSE - 38 " Median (Min - Max)" "36.7 (34.0 - 39.3)" "36.6 (33.6 - 38.9)" "36.5 (34.2 - 38.9)" "36.6 (33.6 - 39.3)" FALSE - ---- - - Code - res - Output - $title - [1] "Table 2. Baseline Demographic and Clinical Characteristics Safety Population, Pooled Analyses" - - $subtitle - [1] "" - - $preheader - NULL - - -# Table 02 generation (tplyr) works with some NA values - - Code - res - Output - # A tibble: 5 x 6 - row_label2 `A: Drug X\n(N=134)` `B: Placebo\n(N=134)` `C: Combination\n(N=132)` `Total Population\n(N=400)` ..tfrmt_row_grp_lbl - - 1 "Characteristic" TRUE - 2 " Sex" TRUE - 3 " F" 68 (50.7%) 68 (50.7%) 62 (47.0%) 198 (49.5%) FALSE - 4 " M" 50 (37.3%) 48 (35.8%) 54 (40.9%) 152 (38.0%) FALSE - 5 " " 16 (11.9%) 18 (13.4%) 16 (12.1%) 50 (12.5%) FALSE - -# Table 02 generation (gtsum) works with default values - - Code - res - Output - # A tibble: 34 x 10 - variable var_type var_label row_type label stat_label stat_1 stat_2 stat_3 stat_0 - - 1 SEX categorical Sex label Sex, n (%) n (%)



- 2 SEX categorical Sex level     F
79 (59%) 82 (61%) 70 (53%) 231 (58%) - 3 SEX categorical Sex level     M
55 (41%) 52 (39%) 62 (47%) 169 (42%) - 4 AGE continuous2 Age label Age




- 5 AGE continuous2 Age level     Mean (SD)
33.8 (6.6) 35.4 (7.9) 35.4 (7.7) 34.9 (7.4) - 6 AGE continuous2 Age level     Median (min - max)
33.0 (21.0 - 50.0) 35.0 (21.0 - 62.0) 35.0 (20.0 - 69.0) 34.0 (20.0 - 69.0) - 7 AGEGR1 categorical Age Group label Age Group, n (%) n (%)



- 8 AGEGR1 categorical Age Group level     >=17 to <65
134 (100%) 134 (100%) 131 (99%) 399 (100%) - 9 AGEGR1 categorical Age Group level     >=65
0 (0%) 0 (0%) 1 (0.8%) 1 (0.3%) - 10 RACE categorical Race label Race, n (%) n (%)



- 11 RACE categorical Race level     ASIAN
68 (51%) 67 (50%) 73 (55%) 208 (52%) - 12 RACE categorical Race level     BLACK OR AFRICAN AMERICAN
31 (23%) 28 (21%) 32 (24%) 91 (23%) - 13 RACE categorical Race level     WHITE
27 (20%) 26 (19%) 21 (16%) 74 (19%) - 14 RACE categorical Race level     AMERICAN INDIAN OR ALASKA NATIVE
8 (6.0%) 11 (8.2%) 6 (4.5%) 25 (6.3%) - 15 RACE categorical Race level     MULTIPLE
0 (0%) 1 (0.7%) 0 (0%) 1 (0.3%) - 16 RACE categorical Race level     NATIVE HAWAIIAN OR OTHER PACIFIC ISLANDER
0 (0%) 1 (0.7%) 0 (0%) 1 (0.3%) - 17 RACE categorical Race level     OTHER
0 (0%) 0 (0%) 0 (0%) 0 (0%) - 18 RACE categorical Race level     UNKNOWN
0 (0%) 0 (0%) 0 (0%) 0 (0%) - 19 ETHNIC categorical Ethnicity label Ethnicity, n (%) n (%)



- 20 ETHNIC categorical Ethnicity level     HISPANIC OR LATINO
15 (11%) 18 (13%) 15 (11%) 48 (12%) - 21 ETHNIC categorical Ethnicity level     NOT HISPANIC OR LATINO
104 (78%) 103 (77%) 101 (77%) 308 (77%) - 22 ETHNIC categorical Ethnicity level     NOT REPORTED
6 (4.5%) 10 (7.5%) 11 (8.3%) 27 (6.8%) - 23 ETHNIC categorical Ethnicity level     UNKNOWN
9 (6.7%) 3 (2.2%) 5 (3.8%) 17 (4.3%) - 24 COUNTRY categorical Country label Country, n (%) n (%)



- 25 COUNTRY categorical Country level     CHN
74 (55%) 81 (60%) 64 (48%) 219 (55%) - 26 COUNTRY categorical Country level     USA
10 (7.5%) 13 (9.7%) 17 (13%) 40 (10%) - 27 COUNTRY categorical Country level     BRA
13 (9.7%) 7 (5.2%) 10 (7.6%) 30 (7.5%) - 28 COUNTRY categorical Country level     PAK
12 (9.0%) 9 (6.7%) 10 (7.6%) 31 (7.8%) - 29 COUNTRY categorical Country level     NGA
8 (6.0%) 7 (5.2%) 11 (8.3%) 26 (6.5%) - 30 COUNTRY categorical Country level     RUS
5 (3.7%) 8 (6.0%) 6 (4.5%) 19 (4.8%) - 31 COUNTRY categorical Country level     JPN
5 (3.7%) 4 (3.0%) 9 (6.8%) 18 (4.5%) - 32 COUNTRY categorical Country level     GBR
4 (3.0%) 3 (2.2%) 2 (1.5%) 9 (2.3%) - 33 COUNTRY categorical Country level     CAN
3 (2.2%) 2 (1.5%) 3 (2.3%) 8 (2.0%) - 34 COUNTRY categorical Country level     CHE
0 (0%) 0 (0%) 0 (0%) 0 (0%) - -# Table 02 generation (gtsum) works with custom values - - Code - res - Output - # A tibble: 37 x 10 - variable var_type var_label row_type label stat_label stat_1 stat_2 stat_3 stat_0 - - 1 SEX categorical Sex label Sex, n (%) n (%)



- 2 SEX categorical Sex level     F
79 (59%) 82 (61%) 70 (53%) 231 (58%) - 3 SEX categorical Sex level     M
55 (41%) 52 (39%) 62 (47%) 169 (42%) - 4 AGE continuous2 Age label Age




- 5 AGE continuous2 Age level     Mean (SD)
33.8 (6.6) 35.4 (7.9) 35.4 (7.7) 34.9 (7.4) - 6 AGE continuous2 Age level     Median (min - max)
33.0 (21.0 - 50.0) 35.0 (21.0 - 62.0) 35.0 (20.0 - 69.0) 34.0 (20.0 - 69.0) - 7 AGEGR1 categorical Age Group label Age Group, n (%) n (%)



- 8 AGEGR1 categorical Age Group level     >=17 to <65
134 (100%) 134 (100%) 131 (99%) 399 (100%) - 9 AGEGR1 categorical Age Group level     >=65
0 (0%) 0 (0%) 1 (0.8%) 1 (0.3%) - 10 RACE categorical Race label Race, n (%) n (%)



- 11 RACE categorical Race level     ASIAN
68 (51%) 67 (50%) 73 (55%) 208 (52%) - 12 RACE categorical Race level     BLACK OR AFRICAN AMERICAN
31 (23%) 28 (21%) 32 (24%) 91 (23%) - 13 RACE categorical Race level     WHITE
27 (20%) 26 (19%) 21 (16%) 74 (19%) - 14 RACE categorical Race level     AMERICAN INDIAN OR ALASKA NATIVE
8 (6.0%) 11 (8.2%) 6 (4.5%) 25 (6.3%) - 15 RACE categorical Race level     MULTIPLE
0 (0%) 1 (0.7%) 0 (0%) 1 (0.3%) - 16 RACE categorical Race level     NATIVE HAWAIIAN OR OTHER PACIFIC ISLANDER
0 (0%) 1 (0.7%) 0 (0%) 1 (0.3%) - 17 RACE categorical Race level     OTHER
0 (0%) 0 (0%) 0 (0%) 0 (0%) - 18 RACE categorical Race level     UNKNOWN
0 (0%) 0 (0%) 0 (0%) 0 (0%) - 19 ETHNIC categorical Ethnicity label Ethnicity, n (%) n (%)



- 20 ETHNIC categorical Ethnicity level     HISPANIC OR LATINO
15 (11%) 18 (13%) 15 (11%) 48 (12%) - 21 ETHNIC categorical Ethnicity level     NOT HISPANIC OR LATINO
104 (78%) 103 (77%) 101 (77%) 308 (77%) - 22 ETHNIC categorical Ethnicity level     NOT REPORTED
6 (4.5%) 10 (7.5%) 11 (8.3%) 27 (6.8%) - 23 ETHNIC categorical Ethnicity level     UNKNOWN
9 (6.7%) 3 (2.2%) 5 (3.8%) 17 (4.3%) - 24 COUNTRY categorical Country label Country, n (%) n (%)



- 25 COUNTRY categorical Country level     CHN
74 (55%) 81 (60%) 64 (48%) 219 (55%) - 26 COUNTRY categorical Country level     USA
10 (7.5%) 13 (9.7%) 17 (13%) 40 (10%) - 27 COUNTRY categorical Country level     BRA
13 (9.7%) 7 (5.2%) 10 (7.6%) 30 (7.5%) - 28 COUNTRY categorical Country level     PAK
12 (9.0%) 9 (6.7%) 10 (7.6%) 31 (7.8%) - 29 COUNTRY categorical Country level     NGA
8 (6.0%) 7 (5.2%) 11 (8.3%) 26 (6.5%) - 30 COUNTRY categorical Country level     RUS
5 (3.7%) 8 (6.0%) 6 (4.5%) 19 (4.8%) - 31 COUNTRY categorical Country level     JPN
5 (3.7%) 4 (3.0%) 9 (6.8%) 18 (4.5%) - 32 COUNTRY categorical Country level     GBR
4 (3.0%) 3 (2.2%) 2 (1.5%) 9 (2.3%) - 33 COUNTRY categorical Country level     CAN
3 (2.2%) 2 (1.5%) 3 (2.3%) 8 (2.0%) - 34 COUNTRY categorical Country level     CHE
0 (0%) 0 (0%) 0 (0%) 0 (0%) - 35 AVAL continuous2 Analysis Value label Analysis Value




- 36 AVAL continuous2 Analysis Value level     Mean (SD)
36.7 (1.0) 36.6 (1.1) 36.5 (1.0) 36.6 (1.0) - 37 AVAL continuous2 Analysis Value level     Median (min - max)
36.7 (34.0 - 39.3) 36.6 (33.6 - 38.9) 36.5 (34.2 - 38.9) 36.6 (33.6 - 39.3) + **Characteristic** **A: Drug X** \nN = 134 **B: Placebo** \nN = 134 **C: Combination** \nN = 132 **Total Population** \nN = 400 + 1 __Sex, n (%)__ + 2 F 79 (59%) 82 (61%) 70 (53%) 231 (58%) + 3 M 55 (41%) 52 (39%) 62 (47%) 169 (42%) + 4 __Age__ + 5 Mean (SD) 33.8 (6.6) 35.4 (7.9) 35.4 (7.7) 34.9 (7.4) + 6 Median (min - max) 33.0 (21.0 - 50.0) 35.0 (21.0 - 62.0) 35.0 (20.0 - 69.0) 34.0 (20.0 - 69.0) + 7 __Race, n (%)__ + 8 ASIAN 68 (51%) 67 (50%) 73 (55%) 208 (52%) + 9 BLACK OR AFRICAN AMERICAN 31 (23%) 28 (21%) 32 (24%) 91 (23%) + 10 WHITE 27 (20%) 26 (19%) 21 (16%) 74 (19%) + 11 AMERICAN INDIAN OR ALASKA NATIVE 8 (6.0%) 11 (8.2%) 6 (4.5%) 25 (6.3%) + 12 MULTIPLE 0 (0%) 1 (0.7%) 0 (0%) 1 (0.3%) + 13 NATIVE HAWAIIAN OR OTHER PACIFIC ISLANDER 0 (0%) 1 (0.7%) 0 (0%) 1 (0.3%) + 14 OTHER 0 (0%) 0 (0%) 0 (0%) 0 (0%) + 15 UNKNOWN 0 (0%) 0 (0%) 0 (0%) 0 (0%) + 16 __Ethnicity, n (%)__ + 17 HISPANIC OR LATINO 15 (11%) 18 (13%) 15 (11%) 48 (12%) + 18 NOT HISPANIC OR LATINO 104 (78%) 103 (77%) 101 (77%) 308 (77%) + 19 NOT REPORTED 6 (4.5%) 10 (7.5%) 11 (8.3%) 27 (6.8%) + 20 UNKNOWN 9 (6.7%) 3 (2.2%) 5 (3.8%) 17 (4.3%) + 21 __Country, n (%)__ + 22 CHN 74 (55%) 81 (60%) 64 (48%) 219 (55%) + 23 USA 10 (7.5%) 13 (9.7%) 17 (13%) 40 (10%) + 24 BRA 13 (9.7%) 7 (5.2%) 10 (7.6%) 30 (7.5%) + 25 PAK 12 (9.0%) 9 (6.7%) 10 (7.6%) 31 (7.8%) + 26 NGA 8 (6.0%) 7 (5.2%) 11 (8.3%) 26 (6.5%) + 27 RUS 5 (3.7%) 8 (6.0%) 6 (4.5%) 19 (4.8%) + 28 JPN 5 (3.7%) 4 (3.0%) 9 (6.8%) 18 (4.5%) + 29 GBR 4 (3.0%) 3 (2.2%) 2 (1.5%) 9 (2.3%) + 30 CAN 3 (2.2%) 2 (1.5%) 3 (2.3%) 8 (2.0%) + 31 CHE 0 (0%) 0 (0%) 0 (0%) 0 (0%) + 32 __Analysis Value__ + 33 Mean (SD) 36.7 (1.0) 36.6 (1.1) 36.5 (1.0) 36.6 (1.0) + 34 Median (min - max) 36.7 (34.0 - 39.3) 36.6 (33.6 - 38.9) 36.5 (34.2 - 38.9) 36.6 (33.6 - 39.3) # Table 02 generation (gtsum) works with some NA values Code - res + as.data.frame(result$tbl) Output - # A tibble: 4 x 10 - variable var_type var_label row_type label stat_label stat_1 stat_2 stat_3 stat_0 - - 1 SEX categorical Sex label Sex, n (%) n (%)



- 2 SEX categorical Sex level     F
68 (51%) 68 (51%) 62 (47%) 198 (50%) - 3 SEX categorical Sex level     M
50 (37%) 48 (36%) 54 (41%) 152 (38%) - 4 SEX categorical Sex level     
16 (12%) 18 (13%) 16 (12%) 50 (13%) + **Characteristic** **A: Drug X** \nN = 134 **B: Placebo** \nN = 134 **C: Combination** \nN = 132 **Total Population** \nN = 400 + 1 __Sex, n (%)__ + 2 F 68 (51%) 68 (51%) 62 (47%) 198 (50%) + 3 M 50 (37%) 48 (36%) 54 (41%) 152 (38%) + 4 16 (12%) 18 (13%) 16 (12%) 50 (13%) diff --git a/tests/testthat/test-fda-table_02.R b/tests/testthat/test-fda-table_02.R index 48dee518..b370b164 100644 --- a/tests/testthat/test-fda-table_02.R +++ b/tests/testthat/test-fda-table_02.R @@ -3,152 +3,28 @@ adsl <- adsl_raw %>% df_explicit_na() test_that("Table 02 generation works with default values", { - result <- make_table_02_rtables(adsl) - - res <- expect_silent(result) - expect_snapshot(res) -}) - -test_that("Table 02 generation works with custom values", { - advs <- advs_raw %>% - dplyr::filter(AVISIT == "BASELINE", VSTESTCD == "TEMP") %>% - dplyr::select("USUBJID", "AVAL") - - anl <- dplyr::left_join(adsl, advs, by = "USUBJID") %>% df_explicit_na() - - result <- make_table_02_rtables( - anl, - vars = c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY", "AVAL"), - lbl_vars = c( - "Sex", "Age, years", "Age Group, years", "Race", "Ethnicity", - "Country of Participation", "Baseline Temperature (C)" - ), - na_rm = TRUE, - annotations = list( - title = "Table 2. Baseline Demographic and Clinical Characteristics Safety Population, Pooled Analyses", - main_footer = "Source: [include Applicant source, datasets and/or software tools used].", - prov_footer = paste( - "Abbreviations: N, number of patients in treatment arm;", - "n, number of patients with given characteristic; SD, standard deviation" - ) - ) - ) - - res <- expect_silent(result) - expect_snapshot(res) -}) - -test_that("Table 02 generation works with some NA values", { - set.seed(1) - adsl[sample(seq_len(nrow(adsl)), 50), "SEX"] <- NA - - adsl <- adsl %>% df_explicit_na() - - result <- make_table_02_rtables(adsl, vars = "SEX", lbl_vars = "Sex") - - res <- expect_silent(result) - expect_snapshot(res) -}) - -test_that("Table 02 generation (tplyr) works with default values", { - options(pillar.print_max = 50, width = 200) - - result <- withr::with_options( - opts_partial_match_old, - make_table_02_tplyr(adsl) - ) - - res <- expect_silent(result[["_data"]]) - expect_snapshot(res) -}) - -test_that("Table 02 generation (tplyr) works with `tplyr_raw` = TRUE", { - options(pillar.print_max = 50, width = 200) - - result <- withr::with_options( - opts_partial_match_old, - make_table_02_tplyr(adsl, tplyr_raw = TRUE) - ) - - res <- expect_silent(result) - expect_snapshot(res) -}) - -test_that("Table 02 generation (tplyr) works with custom values", { options(pillar.print_max = 50, width = 200) - advs <- advs_raw %>% - dplyr::filter(AVISIT == "BASELINE", VSTESTCD == "TEMP") %>% - dplyr::select("USUBJID", "AVAL") - - anl <- dplyr::left_join(adsl, advs, by = "USUBJID") %>% df_explicit_na() + result <- make_table_02(adsl) + expect_snapshot(result$tbl |> as.data.frame()) + }) - result <- withr::with_options( - opts_partial_match_old, - make_table_02_tplyr( - anl, - vars = c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY", "AVAL"), - lbl_vars = c( - "Sex", "Age, years", "Age Group, years", "Race", "Ethnicity", - "Country of Participation", "Baseline Temperature (C)" - ), - na_rm = TRUE, - annotations = list( - title = "Table 2. Baseline Demographic and Clinical Characteristics Safety Population, Pooled Analyses" - ), - prune_0 = FALSE - ) - ) - - res <- expect_silent(result[["_data"]]) - expect_snapshot(res) - - res <- expect_silent(result[["_heading"]]) - expect_snapshot(res) -}) - -test_that("Table 02 generation (tplyr) works with some NA values", { - options(pillar.print_max = 50, width = 200) - - set.seed(1) - adsl[sample(seq_len(nrow(adsl)), 50), "SEX"] <- NA - - adsl <- adsl %>% df_explicit_na() - - result <- withr::with_options( - opts_partial_match_old, - make_table_02_tplyr(adsl, vars = "SEX", lbl_vars = "Sex") - ) - - res <- expect_silent(result[["_data"]]) - expect_snapshot(res) -}) - -test_that("Table 02 generation (gtsum) works with default values", { - options(pillar.print_max = 50, width = 200) - - result <- suppressWarnings(make_table_02_gtsum(adsl) %>% gt::extract_body()) - - res <- expect_silent(result) - expect_snapshot(res) -}) - -test_that("Table 02 generation (gtsum) works with custom values", { +test_that("Table 02 generation works with custom values", { options(pillar.print_max = 50, width = 200) advs <- advs_raw %>% dplyr::filter(AVISIT == "BASELINE", VSTESTCD == "TEMP") %>% - dplyr::select("USUBJID", "AVAL") + dplyr::select(all_of(c("USUBJID", "AVAL"))) anl <- dplyr::left_join(adsl, advs, by = "USUBJID") %>% df_explicit_na() - result <- suppressWarnings(make_table_02_gtsum( + result <- make_table_02( anl, - vars = c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY", "AVAL") - ) %>% gt::extract_body()) + vars = c("SEX", "AGE", "RACE", "ETHNIC", "COUNTRY", "AVAL") + ) res <- expect_silent(result) - expect_snapshot(res) + expect_snapshot(result$tbl |> as.data.frame()) }) test_that("Table 02 generation (gtsum) works with some NA values", { @@ -159,8 +35,8 @@ test_that("Table 02 generation (gtsum) works with some NA values", { adsl <- adsl %>% df_explicit_na() - result <- suppressWarnings(make_table_02_gtsum(adsl, vars = "SEX") %>% gt::extract_body()) + result <- suppressWarnings(make_table_02(adsl, vars = "SEX")) res <- expect_silent(result) - expect_snapshot(res) + expect_snapshot(result$tbl |> as.data.frame()) }) From 1f4da0855915e06bbae6e7860769ce354f985fb5 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 11 Nov 2024 17:11:05 +0000 Subject: [PATCH 05/21] [skip style] [skip vbump] Restyle files --- tests/testthat/test-fda-table_02.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/testthat/test-fda-table_02.R b/tests/testthat/test-fda-table_02.R index b370b164..38e1a96d 100644 --- a/tests/testthat/test-fda-table_02.R +++ b/tests/testthat/test-fda-table_02.R @@ -7,7 +7,7 @@ test_that("Table 02 generation works with default values", { result <- make_table_02(adsl) expect_snapshot(result$tbl |> as.data.frame()) - }) +}) test_that("Table 02 generation works with custom values", { options(pillar.print_max = 50, width = 200) From 8d0c7af59da5c2bb2a58f8301f897ccac3835598 Mon Sep 17 00:00:00 2001 From: "27856297+dependabot-preview[bot]@users.noreply.github.com" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 11 Nov 2024 17:11:29 +0000 Subject: [PATCH 06/21] [skip roxygen] [skip vbump] Roxygen Man Pages Auto Update --- man/make_table_02.Rd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/man/make_table_02.Rd b/man/make_table_02.Rd index d08458b8..ac84b7cf 100644 --- a/man/make_table_02.Rd +++ b/man/make_table_02.Rd @@ -9,7 +9,7 @@ make_table_02( show_colcounts = TRUE, arm_var = "ARM", saffl_var = "SAFFL", - vars = c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY"), + vars = c("SEX", "AGE", "RACE", "ETHNIC", "COUNTRY"), lbl_vars = formatters::var_labels(data, fill = TRUE)[vars], lbl_overall = "Total Population", na_rm = FALSE, @@ -36,7 +36,7 @@ the given value as the column label.} } \value{ \itemize{ -\item \code{make_table_02} returns a list containing a gtsummary table object. +\item \code{make_table_02} returns a list containing a \code{gtsummary} table object. The intermediary \code{ARD} object can also be returned with \code{return_ard} set to \code{TRUE}. } } From 45de7466d7b8427d6bf0095efb547ad844a1d0c3 Mon Sep 17 00:00:00 2001 From: ayogasekaram Date: Mon, 11 Nov 2024 18:18:06 +0000 Subject: [PATCH 07/21] update argument convention. --- R/argument_convention.R | 3 +++ R/fda-table_02.R | 15 +++++++-------- man/argument_convention.Rd | 6 ++++++ man/make_table_02.Rd | 17 ++++++++++------- quarto/table-templates/template-table_02.qmd | 4 ++-- 5 files changed, 28 insertions(+), 17 deletions(-) diff --git a/R/argument_convention.R b/R/argument_convention.R index 9bc5120b..c89f5c42 100644 --- a/R/argument_convention.R +++ b/R/argument_convention.R @@ -38,6 +38,8 @@ #' @param annotations (named `list` of `character`)\cr list of annotations to add to the table. Valid #' annotation types are `title`, `subtitles`, `main_footer`, and `prov_footer`. Each name-value pair should #' use the annotation type as name and the desired string as value. +#' @param ard (`cards::card`)\cr an ARD. +#' @param denominator (`data.frame`)\cr alternative dataset (typically ADSL) used only to calculate denominator counts. #' @param df (`data.frame`)\cr dataset required to build table. #' @param eosdy_var (`character`)\cr variable denoting last recorded (relative) study day. #' @param fmqsc_var (`character`)\cr FMQ scope variable to use in table. @@ -54,6 +56,7 @@ #' in the table. Labels should be ordered according to the order of variables in `vars`. #' @param na_level (`character`)\cr string to represent missing values. #' @param na_rm (`flag`)\cr whether `NA` levels should be removed from the table. +#' @param return_ard (`flag`)\cr whether an ARD should be returned. Defaults to `TRUE`. #' @param risk_diff (named `list`)\cr list of settings to apply to add one or more risk difference columns to the table. #' Defaults to `NULL` (no risk difference column added). See [tern::add_riskdiff()] for more details. List should #' contain the following elements: diff --git a/R/fda-table_02.R b/R/fda-table_02.R index a4774342..53682db7 100644 --- a/R/fda-table_02.R +++ b/R/fda-table_02.R @@ -1,7 +1,7 @@ #' FDA Table 2: Baseline Demographic and Clinical Characteristics, Safety Population, Pooled Analyses #' #' @details -#' * `data` must contain the variables specified by `vars`. +#' * `df` must contain the variables specified by `vars`. #' * `return_ard` set to `TRUE` or `FALSE`; whether the intermediate ARD object should be returned. #' #' @inheritParams argument_convention @@ -26,26 +26,25 @@ NULL #' AGE >= 75 ~ ">=75" #' ))) #' -#' tbl <- make_table_02(data = adsl) +#' tbl <- make_table_02(df = adsl) #' tbl #' #' @export -make_table_02 <- function(data, +make_table_02 <- function(df, show_colcounts = TRUE, arm_var = "ARM", saffl_var = "SAFFL", vars = c("SEX", "AGE", "RACE", "ETHNIC", "COUNTRY"), - lbl_vars = formatters::var_labels(data, fill = TRUE)[vars], + lbl_vars = formatters::var_labels(df, fill = TRUE)[vars], lbl_overall = "Total Population", na_rm = FALSE, - ..., return_ard = TRUE) { # check data viability - checkmate::assert_subset(c(vars, arm_var, saffl_var), names(data)) - assert_flag_variables(data, saffl_var) + checkmate::assert_subset(c(vars, arm_var, saffl_var), names(df)) + assert_flag_variables(df, saffl_var) - df <- data %>% + df <- df %>% filter(.data[[saffl_var]] == "Y") %>% select(all_of(c(vars, arm_var))) diff --git a/man/argument_convention.Rd b/man/argument_convention.Rd index ae652ace..7601b5d8 100644 --- a/man/argument_convention.Rd +++ b/man/argument_convention.Rd @@ -41,6 +41,10 @@ that statistic. See \code{\link[formatters:list_formats]{formatters::list_valid_ annotation types are \code{title}, \code{subtitles}, \code{main_footer}, and \code{prov_footer}. Each name-value pair should use the annotation type as name and the desired string as value.} +\item{ard}{(\code{cards::card})\cr an ARD.} + +\item{denominator}{(\code{data.frame})\cr alternative dataset (typically ADSL) used only to calculate denominator counts.} + \item{df}{(\code{data.frame})\cr dataset required to build table.} \item{eosdy_var}{(\code{character})\cr variable denoting last recorded (relative) study day.} @@ -70,6 +74,8 @@ in the table. Labels should be ordered according to the order of variables in \c \item{na_rm}{(\code{flag})\cr whether \code{NA} levels should be removed from the table.} +\item{return_ard}{(\code{flag})\cr whether an ARD should be returned. Defaults to \code{TRUE}.} + \item{risk_diff}{(named \code{list})\cr list of settings to apply to add one or more risk difference columns to the table. Defaults to \code{NULL} (no risk difference column added). See \code{\link[tern:add_riskdiff]{tern::add_riskdiff()}} for more details. List should contain the following elements: diff --git a/man/make_table_02.Rd b/man/make_table_02.Rd index d08458b8..6266fe54 100644 --- a/man/make_table_02.Rd +++ b/man/make_table_02.Rd @@ -5,19 +5,20 @@ \title{FDA Table 2: Baseline Demographic and Clinical Characteristics, Safety Population, Pooled Analyses} \usage{ make_table_02( - data, + df, show_colcounts = TRUE, arm_var = "ARM", saffl_var = "SAFFL", - vars = c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY"), - lbl_vars = formatters::var_labels(data, fill = TRUE)[vars], + vars = c("SEX", "AGE", "RACE", "ETHNIC", "COUNTRY"), + lbl_vars = formatters::var_labels(df, fill = TRUE)[vars], lbl_overall = "Total Population", na_rm = FALSE, - ..., return_ard = TRUE ) } \arguments{ +\item{df}{(\code{data.frame})\cr dataset required to build table.} + \item{show_colcounts}{(\code{flag})\cr Whether column counts should be printed. Boolean.} \item{arm_var}{(\code{character})\cr Name of the treatment arm variable used to split table into columns.} @@ -33,10 +34,12 @@ in the table. Labels should be ordered according to the order of variables in \c the given value as the column label.} \item{na_rm}{(\code{flag})\cr whether \code{NA} levels should be removed from the table.} + +\item{return_ard}{(\code{flag})\cr whether an ARD should be returned. Defaults to \code{TRUE}.} } \value{ \itemize{ -\item \code{make_table_02} returns a list containing a gtsummary table object. +\item \code{make_table_02} returns a list containing a \code{gtsummary} table object. The intermediary \code{ARD} object can also be returned with \code{return_ard} set to \code{TRUE}. } } @@ -45,7 +48,7 @@ FDA Table 2: Baseline Demographic and Clinical Characteristics, Safety Populatio } \details{ \itemize{ -\item \code{data} must contain the variables specified by \code{vars}. +\item \code{df} must contain the variables specified by \code{vars}. \item \code{return_ard} set to \code{TRUE} or \code{FALSE}; whether the intermediate ARD object should be returned. } } @@ -65,7 +68,7 @@ adsl <- random.cdisc.data::cadsl \%>\% AGE >= 75 ~ ">=75" ))) -tbl <- make_table_02(data = adsl) +tbl <- make_table_02(df = adsl) tbl } diff --git a/quarto/table-templates/template-table_02.qmd b/quarto/table-templates/template-table_02.qmd index ea757af3..369c00a1 100644 --- a/quarto/table-templates/template-table_02.qmd +++ b/quarto/table-templates/template-table_02.qmd @@ -36,7 +36,7 @@ anl <- left_join(adsl, advs, by = "USUBJID") # Output Table make_table_02( - data = anl, + df = anl, vars = c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY", "AVAL"), lbl_vars = c( "Sex", "Age, years", "Age Group, years", "Race", "Ethnicity", @@ -94,7 +94,7 @@ make_table_02( Required variables: -- **`data`**: `SAFFL` and the variables specified by `vars` and `arm_var`. +- **`df`**: `SAFFL` and the variables specified by `vars` and `arm_var`. - **`alt_counts_df`** (if specified and `tplyr_raw = FALSE`): `SAFFL`, `USUBJID`, and the variable specified by `arm_var`. | **Argument** | **Description** | **Default** | From 68aedaddc5ced99e9d85ef7fe776cb200c83f9a5 Mon Sep 17 00:00:00 2001 From: ayogasekaram Date: Mon, 11 Nov 2024 18:48:28 +0000 Subject: [PATCH 08/21] update for docs check --- quarto/getting_started.qmd | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/quarto/getting_started.qmd b/quarto/getting_started.qmd index 96b9dbaa..a7294d49 100644 --- a/quarto/getting_started.qmd +++ b/quarto/getting_started.qmd @@ -118,16 +118,8 @@ tbl <- make_table_02( vars = c("SEX", "AGE", "RACE", "COUNTRY", "AVAL"), lbl_vars = c("Sex", "Age, years", "Race", "Country of Participation", "Baseline Temperature (C)"), lbl_overall = "Total\nPopulation", - na_rm = TRUE, - annotations = list( - title = "Table 2. Baseline Demographic and Clinical Characteristics Safety Population, Pooled Analyses", - main_footer = "Source: [include Applicant source, datasets and/or software tools used].", - prov_footer = paste( - "Abbreviations: N, number of patients in treatment arm;", - "n, number of patients with given characteristic; SD, standard deviation" - ) + na_rm = TRUE ) -) tbl ``` From d3798a2b2e0b9d7c0a8e2fb04e13fd03f6e843a7 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 11 Nov 2024 18:50:25 +0000 Subject: [PATCH 09/21] [skip style] [skip vbump] Restyle files --- quarto/getting_started.qmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quarto/getting_started.qmd b/quarto/getting_started.qmd index a7294d49..7986ca83 100644 --- a/quarto/getting_started.qmd +++ b/quarto/getting_started.qmd @@ -119,7 +119,7 @@ tbl <- make_table_02( lbl_vars = c("Sex", "Age, years", "Race", "Country of Participation", "Baseline Temperature (C)"), lbl_overall = "Total\nPopulation", na_rm = TRUE - ) +) tbl ``` From b0cec5d57d5da8ab99c6148ce09d35dc8ff4fe36 Mon Sep 17 00:00:00 2001 From: ayogasekaram Date: Thu, 19 Dec 2024 20:39:03 +0000 Subject: [PATCH 10/21] reintroduce rtables function --- R/fda-table_02.R | 41 +++++++ quarto/table-templates/template-table_02.qmd | 11 +- tests/testthat/_snaps/fda-table_02.md | 106 ++++++++++++++++++- tests/testthat/test-fda-table_02.R | 50 ++++++++- 4 files changed, 204 insertions(+), 4 deletions(-) diff --git a/R/fda-table_02.R b/R/fda-table_02.R index 53682db7..67099523 100644 --- a/R/fda-table_02.R +++ b/R/fda-table_02.R @@ -79,3 +79,44 @@ make_table_02 <- function(df, res <- list(tbl = tbl) } } + +#' @rdname make_table_02 +#' @export +make_table_02_rtables <- function(df, + alt_counts_df = NULL, + show_colcounts = TRUE, + arm_var = "ARM", + saffl_var = "SAFFL", + vars = c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY"), + lbl_vars = formatters::var_labels(df, fill = TRUE)[vars], + lbl_overall = "Total Population", + na_rm = FALSE, + prune_0 = TRUE, + annotations = NULL) { + assert_subset(c(vars, arm_var, saffl_var), names(df)) + assert_flag_variables(df, saffl_var) + + df <- df %>% + filter(.data[[saffl_var]] == "Y") %>% + df_explicit_na() + + alt_counts_df <- alt_counts_df_preproc(alt_counts_df, id_var, arm_var, saffl_var) + + lyt <- basic_table_annot(show_colcounts, annotations) %>% + split_cols_by_arm(arm_var, lbl_overall) %>% + analyze_vars( + vars = vars, + var_labels = lbl_vars, + show_labels = "visible", + .stats = c("mean_sd", "median_range", "count_fraction"), + .formats = NULL, + na.rm = na_rm + ) %>% + append_topleft("Characteristic") + + tbl <- build_table(lyt, df = df, alt_counts_df = alt_counts_df) + if (prune_0) tbl <- prune_table(tbl) + + tbl +} + diff --git a/quarto/table-templates/template-table_02.qmd b/quarto/table-templates/template-table_02.qmd index 369c00a1..7789b64d 100644 --- a/quarto/table-templates/template-table_02.qmd +++ b/quarto/table-templates/template-table_02.qmd @@ -9,9 +9,11 @@ format: html ![](../assets/images/screenshots/table_02.png){fig-align="center"} -## rtables Table +## gtsummary Table -```{r tbl, message=FALSE, warning=FALSE} +
+ gtsummary Table Setup +```{r tbl2, eval=FALSE, echo=TRUE} # Load Libraries & Data library(cardinal) library(dplyr) @@ -44,6 +46,11 @@ make_table_02( ) ) ``` +
+ +```{r tbl2, message=FALSE, warning=FALSE, eval=TRUE} +``` + ## Table diff --git a/tests/testthat/_snaps/fda-table_02.md b/tests/testthat/_snaps/fda-table_02.md index 2a8a53fb..51507a2a 100644 --- a/tests/testthat/_snaps/fda-table_02.md +++ b/tests/testthat/_snaps/fda-table_02.md @@ -77,7 +77,7 @@ 33 Mean (SD) 36.7 (1.0) 36.6 (1.1) 36.5 (1.0) 36.6 (1.0) 34 Median (min - max) 36.7 (34.0 - 39.3) 36.6 (33.6 - 38.9) 36.5 (34.2 - 38.9) 36.6 (33.6 - 39.3) -# Table 02 generation (gtsum) works with some NA values +# Table 02 generation works with some NA values Code as.data.frame(result$tbl) @@ -88,3 +88,107 @@ 3 M 50 (37%) 48 (36%) 54 (41%) 152 (38%) 4 16 (12%) 18 (13%) 16 (12%) 50 (13%) +# Table 02 generation (rtables) works with default values + + Code + res + Output + A: Drug X B: Placebo C: Combination Total Population + Characteristic (N=134) (N=134) (N=132) (N=400) + ——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————— + Sex + F 79 (59%) 82 (61.2%) 70 (53%) 231 (57.8%) + M 55 (41%) 52 (38.8%) 62 (47%) 169 (42.2%) + Age + Mean (SD) 33.8 (6.6) 35.4 (7.9) 35.4 (7.7) 34.9 (7.4) + Median (Min - Max) 33.0 (21.0 - 50.0) 35.0 (21.0 - 62.0) 35.0 (20.0 - 69.0) 34.0 (20.0 - 69.0) + Age Group + >=17 to <65 134 (100%) 134 (100%) 131 (99.2%) 399 (99.8%) + >=65 0 0 1 (0.8%) 1 (0.2%) + Race + ASIAN 68 (50.7%) 67 (50%) 73 (55.3%) 208 (52%) + BLACK OR AFRICAN AMERICAN 31 (23.1%) 28 (20.9%) 32 (24.2%) 91 (22.8%) + WHITE 27 (20.1%) 26 (19.4%) 21 (15.9%) 74 (18.5%) + AMERICAN INDIAN OR ALASKA NATIVE 8 (6%) 11 (8.2%) 6 (4.5%) 25 (6.2%) + MULTIPLE 0 1 (0.7%) 0 1 (0.2%) + NATIVE HAWAIIAN OR OTHER PACIFIC ISLANDER 0 1 (0.7%) 0 1 (0.2%) + Ethnicity + HISPANIC OR LATINO 15 (11.2%) 18 (13.4%) 15 (11.4%) 48 (12%) + NOT HISPANIC OR LATINO 104 (77.6%) 103 (76.9%) 101 (76.5%) 308 (77%) + NOT REPORTED 6 (4.5%) 10 (7.5%) 11 (8.3%) 27 (6.8%) + UNKNOWN 9 (6.7%) 3 (2.2%) 5 (3.8%) 17 (4.2%) + Country + CHN 74 (55.2%) 81 (60.4%) 64 (48.5%) 219 (54.8%) + USA 10 (7.5%) 13 (9.7%) 17 (12.9%) 40 (10%) + BRA 13 (9.7%) 7 (5.2%) 10 (7.6%) 30 (7.5%) + PAK 12 (9%) 9 (6.7%) 10 (7.6%) 31 (7.8%) + NGA 8 (6%) 7 (5.2%) 11 (8.3%) 26 (6.5%) + RUS 5 (3.7%) 8 (6%) 6 (4.5%) 19 (4.8%) + JPN 5 (3.7%) 4 (3%) 9 (6.8%) 18 (4.5%) + GBR 4 (3%) 3 (2.2%) 2 (1.5%) 9 (2.2%) + CAN 3 (2.2%) 2 (1.5%) 3 (2.3%) 8 (2%) + +# Table 02 generation (rtables) works with custom values + + Code + res + Output + Table 2. Baseline Demographic and Clinical Characteristics Safety Population, Pooled Analyses + + ——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————— + A: Drug X B: Placebo C: Combination Total Population + Characteristic (N=134) (N=134) (N=132) (N=400) + ——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————— + Sex + F 79 (59%) 82 (61.2%) 70 (53%) 231 (57.8%) + M 55 (41%) 52 (38.8%) 62 (47%) 169 (42.2%) + Age, years + Mean (SD) 33.8 (6.6) 35.4 (7.9) 35.4 (7.7) 34.9 (7.4) + Median (Min - Max) 33.0 (21.0 - 50.0) 35.0 (21.0 - 62.0) 35.0 (20.0 - 69.0) 34.0 (20.0 - 69.0) + Age Group, years + >=17 to <65 134 (100%) 134 (100%) 131 (99.2%) 399 (99.8%) + >=65 0 0 1 (0.8%) 1 (0.2%) + Race + ASIAN 68 (50.7%) 67 (50%) 73 (55.3%) 208 (52%) + BLACK OR AFRICAN AMERICAN 31 (23.1%) 28 (20.9%) 32 (24.2%) 91 (22.8%) + WHITE 27 (20.1%) 26 (19.4%) 21 (15.9%) 74 (18.5%) + AMERICAN INDIAN OR ALASKA NATIVE 8 (6%) 11 (8.2%) 6 (4.5%) 25 (6.2%) + MULTIPLE 0 1 (0.7%) 0 1 (0.2%) + NATIVE HAWAIIAN OR OTHER PACIFIC ISLANDER 0 1 (0.7%) 0 1 (0.2%) + Ethnicity + HISPANIC OR LATINO 15 (11.2%) 18 (13.4%) 15 (11.4%) 48 (12%) + NOT HISPANIC OR LATINO 104 (77.6%) 103 (76.9%) 101 (76.5%) 308 (77%) + NOT REPORTED 6 (4.5%) 10 (7.5%) 11 (8.3%) 27 (6.8%) + UNKNOWN 9 (6.7%) 3 (2.2%) 5 (3.8%) 17 (4.2%) + Country of Participation + CHN 74 (55.2%) 81 (60.4%) 64 (48.5%) 219 (54.8%) + USA 10 (7.5%) 13 (9.7%) 17 (12.9%) 40 (10%) + BRA 13 (9.7%) 7 (5.2%) 10 (7.6%) 30 (7.5%) + PAK 12 (9%) 9 (6.7%) 10 (7.6%) 31 (7.8%) + NGA 8 (6%) 7 (5.2%) 11 (8.3%) 26 (6.5%) + RUS 5 (3.7%) 8 (6%) 6 (4.5%) 19 (4.8%) + JPN 5 (3.7%) 4 (3%) 9 (6.8%) 18 (4.5%) + GBR 4 (3%) 3 (2.2%) 2 (1.5%) 9 (2.2%) + CAN 3 (2.2%) 2 (1.5%) 3 (2.3%) 8 (2%) + Baseline Temperature (C) + Mean (SD) 36.7 (1.0) 36.6 (1.1) 36.5 (1.0) 36.6 (1.0) + Median (Min - Max) 36.7 (34.0 - 39.3) 36.6 (33.6 - 38.9) 36.5 (34.2 - 38.9) 36.6 (33.6 - 39.3) + ——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————— + + Source: [include Applicant source, datasets and/or software tools used]. + + Abbreviations: N, number of patients in treatment arm; n, number of patients with given characteristic; SD, standard deviation + +# Table 02 generation (rtables) works with some NA values + + Code + res + Output + A: Drug X B: Placebo C: Combination Total Population + Characteristic (N=134) (N=134) (N=132) (N=400) + ———————————————————————————————————————————————————————————————————————————— + Sex + F 68 (50.7%) 68 (50.7%) 62 (47%) 198 (49.5%) + M 50 (37.3%) 48 (35.8%) 54 (40.9%) 152 (38%) + 16 (11.9%) 18 (13.4%) 16 (12.1%) 50 (12.5%) + diff --git a/tests/testthat/test-fda-table_02.R b/tests/testthat/test-fda-table_02.R index 38e1a96d..41e3f50e 100644 --- a/tests/testthat/test-fda-table_02.R +++ b/tests/testthat/test-fda-table_02.R @@ -27,7 +27,7 @@ test_that("Table 02 generation works with custom values", { expect_snapshot(result$tbl |> as.data.frame()) }) -test_that("Table 02 generation (gtsum) works with some NA values", { +test_that("Table 02 generation works with some NA values", { options(pillar.print_max = 50, width = 200) set.seed(1) @@ -40,3 +40,51 @@ test_that("Table 02 generation (gtsum) works with some NA values", { res <- expect_silent(result) expect_snapshot(result$tbl |> as.data.frame()) }) + +test_that("Table 02 generation (rtables) works with default values", { + result <- make_table_02_rtables(adsl) + + res <- expect_silent(result) + expect_snapshot(res) +}) + +test_that("Table 02 generation (rtables) works with custom values", { + advs <- advs_raw %>% + dplyr::filter(AVISIT == "BASELINE", VSTESTCD == "TEMP") %>% + dplyr::select("USUBJID", "AVAL") + + anl <- dplyr::left_join(adsl, advs, by = "USUBJID") %>% df_explicit_na() + + result <- make_table_02_rtables( + anl, + vars = c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY", "AVAL"), + lbl_vars = c( + "Sex", "Age, years", "Age Group, years", "Race", "Ethnicity", + "Country of Participation", "Baseline Temperature (C)" + ), + na_rm = TRUE, + annotations = list( + title = "Table 2. Baseline Demographic and Clinical Characteristics Safety Population, Pooled Analyses", + main_footer = "Source: [include Applicant source, datasets and/or software tools used].", + prov_footer = paste( + "Abbreviations: N, number of patients in treatment arm;", + "n, number of patients with given characteristic; SD, standard deviation" + ) + ) + ) + + res <- expect_silent(result) + expect_snapshot(res) +}) + +test_that("Table 02 generation (rtables) works with some NA values", { + set.seed(1) + adsl[sample(seq_len(nrow(adsl)), 50), "SEX"] <- NA + + adsl <- adsl %>% df_explicit_na() + + result <- make_table_02_rtables(adsl, vars = "SEX", lbl_vars = "Sex") + + res <- expect_silent(result) + expect_snapshot(res) +}) From c9d1c442cb6f7fb110e1ace2f4800cf3b4f8d8ec Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 7 Feb 2025 16:52:37 +0000 Subject: [PATCH 11/21] [skip style] [skip vbump] Restyle files --- R/fda-table_02.R | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/R/fda-table_02.R b/R/fda-table_02.R index 67099523..bb4374f5 100644 --- a/R/fda-table_02.R +++ b/R/fda-table_02.R @@ -83,16 +83,16 @@ make_table_02 <- function(df, #' @rdname make_table_02 #' @export make_table_02_rtables <- function(df, - alt_counts_df = NULL, - show_colcounts = TRUE, - arm_var = "ARM", - saffl_var = "SAFFL", - vars = c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY"), - lbl_vars = formatters::var_labels(df, fill = TRUE)[vars], - lbl_overall = "Total Population", - na_rm = FALSE, - prune_0 = TRUE, - annotations = NULL) { + alt_counts_df = NULL, + show_colcounts = TRUE, + arm_var = "ARM", + saffl_var = "SAFFL", + vars = c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY"), + lbl_vars = formatters::var_labels(df, fill = TRUE)[vars], + lbl_overall = "Total Population", + na_rm = FALSE, + prune_0 = TRUE, + annotations = NULL) { assert_subset(c(vars, arm_var, saffl_var), names(df)) assert_flag_variables(df, saffl_var) @@ -119,4 +119,3 @@ make_table_02_rtables <- function(df, tbl } - From d6fcfc05813a4daadbc0d1dbf578985e481847fb Mon Sep 17 00:00:00 2001 From: "27856297+dependabot-preview[bot]@users.noreply.github.com" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 7 Feb 2025 16:53:01 +0000 Subject: [PATCH 12/21] [skip roxygen] [skip vbump] Roxygen Man Pages Auto Update --- man/make_table_02.Rd | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/man/make_table_02.Rd b/man/make_table_02.Rd index 6266fe54..8dc1d0f9 100644 --- a/man/make_table_02.Rd +++ b/man/make_table_02.Rd @@ -2,6 +2,7 @@ % Please edit documentation in R/fda-table_02.R \name{make_table_02} \alias{make_table_02} +\alias{make_table_02_rtables} \title{FDA Table 2: Baseline Demographic and Clinical Characteristics, Safety Population, Pooled Analyses} \usage{ make_table_02( @@ -15,6 +16,20 @@ make_table_02( na_rm = FALSE, return_ard = TRUE ) + +make_table_02_rtables( + df, + alt_counts_df = NULL, + show_colcounts = TRUE, + arm_var = "ARM", + saffl_var = "SAFFL", + vars = c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY"), + lbl_vars = formatters::var_labels(df, fill = TRUE)[vars], + lbl_overall = "Total Population", + na_rm = FALSE, + prune_0 = TRUE, + annotations = NULL +) } \arguments{ \item{df}{(\code{data.frame})\cr dataset required to build table.} @@ -36,6 +51,14 @@ the given value as the column label.} \item{na_rm}{(\code{flag})\cr whether \code{NA} levels should be removed from the table.} \item{return_ard}{(\code{flag})\cr whether an ARD should be returned. Defaults to \code{TRUE}.} + +\item{alt_counts_df}{(\code{character})\cr alternative dataset (typically ADSL) used only to calculate column counts.} + +\item{prune_0}{(\code{flag})\cr Whether all-zero rows should be removed from the table. Boolean.} + +\item{annotations}{(named \code{list} of \code{character})\cr list of annotations to add to the table. Valid +annotation types are \code{title}, \code{subtitles}, \code{main_footer}, and \code{prov_footer}. Each name-value pair should +use the annotation type as name and the desired string as value.} } \value{ \itemize{ From 1886e6c13763a43b5771e01e6a720bdce23fa8f7 Mon Sep 17 00:00:00 2001 From: ayogasekaram Date: Mon, 10 Feb 2025 15:28:06 +0000 Subject: [PATCH 13/21] finalize table 2 changes with ARD --- NAMESPACE | 1 + R/fda-table_02.R | 80 +++++++--- man/make_table_02.Rd | 74 +++++++-- quarto/table-templates/template-table_02.qmd | 150 ++++++++++++++----- 4 files changed, 229 insertions(+), 76 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index dd8ebd6e..548e1838 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -7,6 +7,7 @@ export(make_fig_02) export(make_fig_03) export(make_fig_14) export(make_table_02) +export(make_table_02_rtables) export(make_table_03) export(make_table_04) export(make_table_05) diff --git a/R/fda-table_02.R b/R/fda-table_02.R index 67099523..cb3203b5 100644 --- a/R/fda-table_02.R +++ b/R/fda-table_02.R @@ -1,19 +1,20 @@ #' FDA Table 2: Baseline Demographic and Clinical Characteristics, Safety Population, Pooled Analyses #' #' @details -#' * `df` must contain the variables specified by `vars`. -#' * `return_ard` set to `TRUE` or `FALSE`; whether the intermediate ARD object should be returned. +#' * `df` must contain the variables specified by `arm_var`, `saffl_var`, and variables specified by the `vars` argument. +#' * `vars` must be a character vector specifying the variables to evaluate. +#' * `return_ard` set to `TRUE` or `FALSE`; whether the intermediate ARD +#' object should be returned. +#' * Flag variables (i.e. `XXXFL`) are expected to have two levels: `"Y"` (true) and `"N"` (false). Missing values in +#' flag variables are treated as `"N"`. #' +#' @inheritParams tbl_make_table_02 #' @inheritParams argument_convention #' -#' @name make_table_02 -NULL - -#' @describeIn make_table_02 Create FDA table 2 using an ARD. +#' @return A `gtsummary` table and, if `return_ard = TRUE`, an ARD. +#' If `return_ard = TRUE`, they will be returned as a list with named elements `table` and `ard`. #' -#' @return -#' * `make_table_02` returns a list containing a `gtsummary` table object. -#' The intermediary `ARD` object can also be returned with `return_ard` set to `TRUE`. +#' @seealso [`tbl_make_table_02`] #' #' @examples #' library(dplyr) @@ -30,25 +31,29 @@ NULL #' tbl #' #' @export - make_table_02 <- function(df, - show_colcounts = TRUE, + denominator = NULL, + return_ard = TRUE, arm_var = "ARM", saffl_var = "SAFFL", - vars = c("SEX", "AGE", "RACE", "ETHNIC", "COUNTRY"), - lbl_vars = formatters::var_labels(df, fill = TRUE)[vars], - lbl_overall = "Total Population", - na_rm = FALSE, - return_ard = TRUE) { + vars = c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY")) { # check data viability - checkmate::assert_subset(c(vars, arm_var, saffl_var), names(df)) + assert_subset(c(arm_var, saffl_var, vars), names(df)) assert_flag_variables(df, saffl_var) + # Data preprocessing df <- df %>% filter(.data[[saffl_var]] == "Y") %>% - select(all_of(c(vars, arm_var))) + select(all_of(c(vars, arm_var, id_var))) - if (!na_rm) df <- df %>% df_explicit_na() + if (any(is.na(df))) { + df <- df %>% df_explicit_na() + } + + # create a table using gtsummary + df %>% + gtsummary::tbl_summary( + by = arm_var) tbl <- df %>% gtsummary::tbl_summary( @@ -61,13 +66,11 @@ make_table_02 <- function(df, ), all_categorical() ~ "{n} ({p}%)" ), - digits = all_continuous() ~ 1, - missing = ifelse(na_rm, "no", "ifany"), - label = as.list(lbl_vars) %>% setNames(vars) - ) %>% + digits = all_continuous() ~ 2, + missing = "no") %>% gtsummary::bold_labels() %>% gtsummary::modify_header(all_stat_cols() ~ "**{level}** \nN = {n}") %>% - gtsummary::add_overall(last = TRUE, col_label = paste0("**", lbl_overall, "** \nN = {n}")) %>% + gtsummary::add_overall(last = TRUE, col_label = paste0("**", "Total Population", "** \nN = {n}")) %>% gtsummary::add_stat_label(label = all_continuous2() ~ c("Mean (SD)", "Median (min - max)")) %>% gtsummary::modify_footnote(everything() ~ NA) %>% gtsummary::modify_column_alignment(columns = all_stat_cols(), align = "right") @@ -80,6 +83,35 @@ make_table_02 <- function(df, } } +#' Engine-Specific Functions: Table 2 +#' +#' The table engine used by each engine-specific function is identified by its suffix. +#' +#' @inheritParams argument_convention +#' +#' @details +#' * Columns are split by arm. Overall population column is excluded by default (see `lbl_overall` argument). +#' * All-zero rows are not removed by default (see `prune_0` argument). +#' +#' @return +#' * `make_table_02_rtables()` returns an `rtable` object. +#' +#' @seealso [make_table_02()] +#' +#' @examples +#' adsl <- random.cdisc.data::cadsl +#' +#' +#' # rtables table ---------------- +#' adsl <- random.cdisc.data::cadsl %>% +#' mutate(AGEGR1 = as.factor(case_when( +#' AGE >= 17 & AGE < 65 ~ ">=17 to <65", +#' AGE >= 65 ~ ">=65", +#' AGE >= 65 & AGE < 75 ~ ">=65 to <75", +#' AGE >= 75 ~ ">=75" +#' ))) +#' tbl_rtables <- cardinal:::make_table_05_rtables(df = adsl) +#' tbl_rtables #' @rdname make_table_02 #' @export make_table_02_rtables <- function(df, diff --git a/man/make_table_02.Rd b/man/make_table_02.Rd index 6266fe54..b9ac6442 100644 --- a/man/make_table_02.Rd +++ b/man/make_table_02.Rd @@ -2,24 +2,38 @@ % Please edit documentation in R/fda-table_02.R \name{make_table_02} \alias{make_table_02} +\alias{make_table_02_rtables} \title{FDA Table 2: Baseline Demographic and Clinical Characteristics, Safety Population, Pooled Analyses} \usage{ make_table_02( df, + denominator = NULL, + return_ard = TRUE, + arm_var = "ARM", + saffl_var = "SAFFL", + vars = c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY") +) + +make_table_02_rtables( + df, + alt_counts_df = NULL, show_colcounts = TRUE, arm_var = "ARM", saffl_var = "SAFFL", - vars = c("SEX", "AGE", "RACE", "ETHNIC", "COUNTRY"), + vars = c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY"), lbl_vars = formatters::var_labels(df, fill = TRUE)[vars], lbl_overall = "Total Population", na_rm = FALSE, - return_ard = TRUE + prune_0 = TRUE, + annotations = NULL ) } \arguments{ \item{df}{(\code{data.frame})\cr dataset required to build table.} -\item{show_colcounts}{(\code{flag})\cr Whether column counts should be printed. Boolean.} +\item{denominator}{(\code{data.frame})\cr alternative dataset (typically ADSL) used only to calculate denominator counts.} + +\item{return_ard}{(\code{flag})\cr whether an ARD should be returned. Defaults to \code{TRUE}.} \item{arm_var}{(\code{character})\cr Name of the treatment arm variable used to split table into columns.} @@ -27,6 +41,10 @@ make_table_02( \item{vars}{(\code{vector} of \code{character})\cr Variables from \code{df} to include in the table.} +\item{alt_counts_df}{(\code{character})\cr alternative dataset (typically ADSL) used only to calculate column counts.} + +\item{show_colcounts}{(\code{flag})\cr Whether column counts should be printed. Boolean.} + \item{lbl_vars}{(\code{vector} of \code{character})\cr labels corresponding to variables in \code{vars} to print in the table. Labels should be ordered according to the order of variables in \code{vars}.} @@ -35,28 +53,38 @@ the given value as the column label.} \item{na_rm}{(\code{flag})\cr whether \code{NA} levels should be removed from the table.} -\item{return_ard}{(\code{flag})\cr whether an ARD should be returned. Defaults to \code{TRUE}.} +\item{prune_0}{(\code{flag})\cr Whether all-zero rows should be removed from the table. Boolean.} + +\item{annotations}{(named \code{list} of \code{character})\cr list of annotations to add to the table. Valid +annotation types are \code{title}, \code{subtitles}, \code{main_footer}, and \code{prov_footer}. Each name-value pair should +use the annotation type as name and the desired string as value.} } \value{ +A \code{gtsummary} table and, if \code{return_ard = TRUE}, an ARD. +If \code{return_ard = TRUE}, they will be returned as a list with named elements \code{table} and \code{ard}. + \itemize{ -\item \code{make_table_02} returns a list containing a \code{gtsummary} table object. -The intermediary \code{ARD} object can also be returned with \code{return_ard} set to \code{TRUE}. +\item \code{make_table_02_rtables()} returns an \code{rtable} object. } } \description{ -FDA Table 2: Baseline Demographic and Clinical Characteristics, Safety Population, Pooled Analyses +The table engine used by each engine-specific function is identified by its suffix. } \details{ \itemize{ -\item \code{df} must contain the variables specified by \code{vars}. -\item \code{return_ard} set to \code{TRUE} or \code{FALSE}; whether the intermediate ARD object should be returned. -} +\item \code{df} must contain the variables specified by \code{arm_var}, \code{saffl_var}, and variables specified by the \code{vars} argument. +\item \code{vars} must be a character vector specifying the variables to evaluate. +\item \code{return_ard} set to \code{TRUE} or \code{FALSE}; whether the intermediate ARD +object should be returned. +\item Flag variables (i.e. \code{XXXFL}) are expected to have two levels: \code{"Y"} (true) and \code{"N"} (false). Missing values in +flag variables are treated as \code{"N"}. } -\section{Functions}{ -\itemize{ -\item \code{make_table_02()}: Create FDA table 2 using an ARD. -}} +\itemize{ +\item Columns are split by arm. Overall population column is excluded by default (see \code{lbl_overall} argument). +\item All-zero rows are not removed by default (see \code{prune_0} argument). +} +} \examples{ library(dplyr) @@ -71,4 +99,22 @@ adsl <- random.cdisc.data::cadsl \%>\% tbl <- make_table_02(df = adsl) tbl +adsl <- random.cdisc.data::cadsl + + +# rtables table ---------------- +adsl <- random.cdisc.data::cadsl \%>\% + mutate(AGEGR1 = as.factor(case_when( + AGE >= 17 & AGE < 65 ~ ">=17 to <65", + AGE >= 65 ~ ">=65", + AGE >= 65 & AGE < 75 ~ ">=65 to <75", + AGE >= 75 ~ ">=75" + ))) +tbl_rtables <- cardinal:::make_table_05_rtables(df = adsl) +tbl_rtables +} +\seealso{ +\code{\link{tbl_make_table_02}} + +\code{\link[=make_table_02]{make_table_02()}} } diff --git a/quarto/table-templates/template-table_02.qmd b/quarto/table-templates/template-table_02.qmd index 7789b64d..f739b817 100644 --- a/quarto/table-templates/template-table_02.qmd +++ b/quarto/table-templates/template-table_02.qmd @@ -12,14 +12,15 @@ format: html ## gtsummary Table
- gtsummary Table Setup + +gtsummary Table Setup + ```{r tbl2, eval=FALSE, echo=TRUE} # Load Libraries & Data library(cardinal) library(dplyr) adsl <- random.cdisc.data::cadsl -advs <- random.cdisc.data::cadvs # Pre-Processing - Add any variables needed in your table to df adsl <- adsl %>% @@ -30,31 +31,95 @@ adsl <- adsl %>% AGE >= 75 ~ ">=75" ))) -advs <- advs %>% - filter(AVISIT == "BASELINE", VSTESTCD == "TEMP") %>% - select("USUBJID", "AVAL") - -anl <- left_join(adsl, advs, by = "USUBJID") # Output Table make_table_02( - df = anl, + df = adsl, vars = c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY", "AVAL"), - lbl_vars = c( - "Sex", "Age, years", "Age Group, years", "Race", "Ethnicity", - "Country of Participation", "Baseline Temperature (C)" - ) + return_ard = FALSE ) ``` +
```{r tbl2, message=FALSE, warning=FALSE, eval=TRUE} ``` +
+ +Function Details + +### `make_table_02()` + +------------------------------------------------------------------------ + +Required variables: + +- **`df`**: The variables specified by `vars`, `arm_var`, and `saffl_var`. +- **`denominator`** (if specified): `USUBJID` and the variables specified by `arm_var` and `saffl_var`. + +| | | | +|----|----|----| +| **Argument** | **Description** | **Default** | +| `df` | (`data.frame`) Dataset (typically ADSL) required to build table. | *No default* | +| `return_ard` | (`flag`) Whether an ARD should be returned. | `TRUE` | +| `denominator` | (`character`) Alternative dataset used only to calculate column counts. | `NULL` | +| `arm_var` | (`character`) Arm variable used to split table into columns. | `"ARM"` | +| `saffl_var` | (`character`) Flag variable used to indicate inclusion in safety population. | `"SAFFL"` | +| `id_var` | (`character`) Identifier variable used to count the participants within each flag. | `"USUBJID"` | + +Source code for this function is available [here](https://github.com/pharmaverse/cardinal/blob/main/R/fda-table_02.R). + +
+ +## ARD + +
+ +ARD Setup + +```{r tbl1, echo=TRUE, message=FALSE, warning=FALSE, results='hide'} +# Load Libraries & Data +library(cardinal) + +library(dplyr) + +adsl <- random.cdisc.data::cadsl + +# Pre-Processing - Add any variables needed in your table to df +adsl <- adsl %>% + mutate(AGEGR1 = as.factor(case_when( + AGE >= 17 & AGE < 65 ~ ">=17 to <65", + AGE >= 65 ~ ">=65", + AGE >= 65 & AGE < 75 ~ ">=65 to <75", + AGE >= 75 ~ ">=75" + ))) + +# Create Table & ARD +result <- make_table_02( + df = adsl, + vars = c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY", "AVAL") +) + +# Output ARD +result$ard +``` + +
-## Table +```{r tbl1-print, echo=FALSE} +options(width = 9999) +print(result$ard, columns = "all", n = Inf) +``` + +## rtables Table + +
+ +rtables Table Setup -```{r tbl_gtsummary, message=FALSE, warning=FALSE} +```{r tbl3, eval=FALSE, echo=TRUE} +# Load Libraries & Data # Load Libraries & Data library(cardinal) library(dplyr) @@ -65,10 +130,10 @@ advs <- random.cdisc.data::cadvs # Pre-Processing - Add any variables needed in your table to df adsl <- adsl %>% mutate(AGEGR1 = as.factor(case_when( - AGE >= 17 & AGE < 65 ~ "≥17 to <65", - AGE >= 65 ~ "≥65", - AGE >= 65 & AGE < 75 ~ "≥65 to <75", - AGE >= 75 ~ "≥75" + AGE >= 17 & AGE < 65 ~ ">=17 to <65", + AGE >= 65 ~ ">=65", + AGE >= 65 & AGE < 75 ~ ">=65 to <75", + AGE >= 75 ~ ">=75" ))) advs <- advs %>% @@ -82,38 +147,47 @@ make_table_02( df = anl, vars = c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY", "AVAL"), lbl_vars = c( - "Sex", "Age, years", "Age Group years", "Race", "Ethnicity", + "Sex", "Age, years", "Age Group, years", "Race", "Ethnicity", "Country of Participation", "Baseline Temperature (C)" ) ) ``` -## gtsummary Table Setup +
-```{r tbl_gtsummary, eval=FALSE, echo=TRUE} +```{r tbl3, message=FALSE, warning=FALSE, eval=TRUE} ``` -## Function Details: `make_table_02` +
+ +Function Details -### `make_table_02()` +### `make_table_02_rtables()` ------------------------------------------------------------------------ Required variables: -- **`df`**: `SAFFL` and the variables specified by `vars` and `arm_var`. -- **`alt_counts_df`** (if specified and `tplyr_raw = FALSE`): `SAFFL`, `USUBJID`, and the variable specified by `arm_var`. - -| **Argument** | **Description** | **Default** | -|:-----------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------| -| `df` | (`data.frame`) Dataset (typically ADSL) required to build table. | *No default* | -| `alt_counts_df` | (`character`) Alternative dataset used only to calculate column counts. | `NULL` | -| `show_colcounts` | (`flag`) Whether column counts should be printed. | `TRUE` | -| `arm_var` | (`character`) Arm variable used to split table into columns. | `"ARM"` | -| `saffl_var` | (`character`) Flag variable used to indicate inclusion in safety population. | `"SAFFL"` | -| `vars` | (`character`) Variables from `df` to include in the table. | `c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY")` | -| `lbl_vars` | (`character`) Labels corresponding to variables in `vars` to print in the table. Labels should be ordered according to the order of variables in `vars`. | `formatters::var_labels(df, fill = TRUE)[vars]` | -| `lbl_overall` | (`character`) If specified, an overall column will be added to the table with the given value as the column label. | `"Total Population"` | - -Source code for this function is available [here](https://github.com/pharmaverse/cardinal/blob/main/R/fda-table_02.R#L34). +- **`df`**: The variables specified by `vars`, `arm_var`, and `saffl_var`. +- **`alt_counts_df`** (if specified): `USUBJID` and the variables specified by `arm_var` and `saffl_var`. + +| **Argument** | **Description** | **Default** | +|:---|:---|:---| +| `df` | (`data.frame`) Dataset (typically ADSL) required to build table. | *No default* | +| `alt_counts_df` | (`character`) Alternative dataset used only to calculate column counts. | `NULL` | +| `show_colcounts` | (`flag`) Whether column counts should be printed. | `TRUE` | +| `arm_var` | (`character`) Arm variable used to split table into columns. | `"ARM"` | +| `saffl_var` | (`character`) Flag variable used to indicate inclusion in safety population. | `"SAFFL"` | +| `vars` | (`character`) Variables from `df` to include in the table. | `c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY")` | +| `lbl_vars` | (`character`) Labels corresponding to variables in `vars` to print in the table. Labels should be ordered according to the order of variables in `vars`. | `formatters::var_labels(df, fill = TRUE)[vars]` | +| `lbl_overall` | (`character`) If specified, an overall column will be added to the table with the given value as the column label. | `"Total Population"` | +| `.stats` | (`character`) Statistics to include in the table. Includes statistics for all variable types (only the statistics that are valid for a given variable's type will be printed). See [`tern::analyze_vars()`](https://insightsengineering.github.io/tern/main/reference/analyze_variables.html#value) for options. | `c("mean_sd", "median_range", "count_fraction")` | +| `.formats` | (named `list` of `character`) List of formats corresponding to each value in `.stats`. Each name is a value in `.stats` and the corresponding value is the format that should be applied to that statistic. See [`formatters::list_valid_format_labels()`](https://insightsengineering.github.io/formatters/main/reference/list_valid_format_labels.html#ref-examples) for a list of valid formats. | `NULL` | +| `prune_0` | (`flag`) Whether all-zero rows should be removed from the table. | `TRUE` | +| `na_rm` | (`flag`) Whether `NA` levels should be removed from the table. | `FALSE` | +| `annotations` | (named `list` of `character`) List of annotations to add to the table. Valid annotation types are `title`, `subtitles`, `main_footer`, and `prov_footer.` Each name-value pair should use the annotation type as name and the desired string as value. | `NULL` | + +Source code for this function is available [here](https://github.com/pharmaverse/cardinal/blob/main/R/fda-table_02.R#L117). + +
::: From 9d9a0557053071d1072de8984164e05866ef03a3 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 10 Feb 2025 17:23:56 +0000 Subject: [PATCH 14/21] [skip style] [skip vbump] Restyle files --- R/fda-table_02.R | 6 ++++-- tests/testthat/test-fda-table_02.R | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/R/fda-table_02.R b/R/fda-table_02.R index da9f99e5..a43c16f5 100644 --- a/R/fda-table_02.R +++ b/R/fda-table_02.R @@ -53,7 +53,8 @@ make_table_02 <- function(df, # create a table using gtsummary df %>% gtsummary::tbl_summary( - by = arm_var) + by = arm_var + ) tbl <- df %>% gtsummary::tbl_summary( @@ -67,7 +68,8 @@ make_table_02 <- function(df, all_categorical() ~ "{n} ({p}%)" ), digits = all_continuous() ~ 2, - missing = "no") %>% + missing = "no" + ) %>% gtsummary::bold_labels() %>% gtsummary::modify_header(all_stat_cols() ~ "**{level}** \nN = {n}") %>% gtsummary::add_overall(last = TRUE, col_label = paste0("**", "Total Population", "** \nN = {n}")) %>% diff --git a/tests/testthat/test-fda-table_02.R b/tests/testthat/test-fda-table_02.R index 9d13d757..dcda8a01 100644 --- a/tests/testthat/test-fda-table_02.R +++ b/tests/testthat/test-fda-table_02.R @@ -1,11 +1,11 @@ adsl <- adsl_raw %>% filter(SAFFL == "Y") %>% - mutate(AGEGR1 = as.factor(case_when( + mutate(AGEGR1 = as.factor(case_when( AGE >= 17 & AGE < 65 ~ ">=17 to <65", AGE >= 65 ~ ">=65", AGE >= 65 & AGE < 75 ~ ">=65 to <75", AGE >= 75 ~ ">=75" - ))) %>% + ))) %>% df_explicit_na() test_that("Table 02 generation works with default values", { From 25bc93ff61b199562eeda7b59be12c9482e3a18f Mon Sep 17 00:00:00 2001 From: ayogasekaram Date: Wed, 12 Feb 2025 21:52:19 +0000 Subject: [PATCH 15/21] address comments from PR review --- R/fda-table_02.R | 12 ++++-------- man/make_table_02.Rd | 10 ++-------- quarto/getting_started.qmd | 17 ++++++++--------- quarto/table-templates/template-table_02.qmd | 12 ++++++------ 4 files changed, 20 insertions(+), 31 deletions(-) diff --git a/R/fda-table_02.R b/R/fda-table_02.R index a43c16f5..3e5ac559 100644 --- a/R/fda-table_02.R +++ b/R/fda-table_02.R @@ -8,13 +8,13 @@ #' * Flag variables (i.e. `XXXFL`) are expected to have two levels: `"Y"` (true) and `"N"` (false). Missing values in #' flag variables are treated as `"N"`. #' -#' @inheritParams tbl_make_table_02 +#' @inheritParams make_table_02 #' @inheritParams argument_convention #' #' @return A `gtsummary` table and, if `return_ard = TRUE`, an ARD. #' If `return_ard = TRUE`, they will be returned as a list with named elements `table` and `ard`. #' -#' @seealso [`tbl_make_table_02`] +#' @seealso [`make_table_02`] #' #' @examples #' library(dplyr) @@ -32,7 +32,6 @@ #' #' @export make_table_02 <- function(df, - denominator = NULL, return_ard = TRUE, arm_var = "ARM", saffl_var = "SAFFL", @@ -112,12 +111,11 @@ make_table_02 <- function(df, #' AGE >= 65 & AGE < 75 ~ ">=65 to <75", #' AGE >= 75 ~ ">=75" #' ))) -#' tbl_rtables <- cardinal:::make_table_05_rtables(df = adsl) +#' tbl_rtables <- make_table_02_rtables(df = adsl) #' tbl_rtables #' @rdname make_table_02 #' @export make_table_02_rtables <- function(df, - alt_counts_df = NULL, show_colcounts = TRUE, arm_var = "ARM", saffl_var = "SAFFL", @@ -134,8 +132,6 @@ make_table_02_rtables <- function(df, filter(.data[[saffl_var]] == "Y") %>% df_explicit_na() - alt_counts_df <- alt_counts_df_preproc(alt_counts_df, id_var, arm_var, saffl_var) - lyt <- basic_table_annot(show_colcounts, annotations) %>% split_cols_by_arm(arm_var, lbl_overall) %>% analyze_vars( @@ -148,7 +144,7 @@ make_table_02_rtables <- function(df, ) %>% append_topleft("Characteristic") - tbl <- build_table(lyt, df = df, alt_counts_df = alt_counts_df) + tbl <- build_table(lyt, df = df) if (prune_0) tbl <- prune_table(tbl) tbl diff --git a/man/make_table_02.Rd b/man/make_table_02.Rd index b9ac6442..2ff8de72 100644 --- a/man/make_table_02.Rd +++ b/man/make_table_02.Rd @@ -7,7 +7,6 @@ \usage{ make_table_02( df, - denominator = NULL, return_ard = TRUE, arm_var = "ARM", saffl_var = "SAFFL", @@ -16,7 +15,6 @@ make_table_02( make_table_02_rtables( df, - alt_counts_df = NULL, show_colcounts = TRUE, arm_var = "ARM", saffl_var = "SAFFL", @@ -31,8 +29,6 @@ make_table_02_rtables( \arguments{ \item{df}{(\code{data.frame})\cr dataset required to build table.} -\item{denominator}{(\code{data.frame})\cr alternative dataset (typically ADSL) used only to calculate denominator counts.} - \item{return_ard}{(\code{flag})\cr whether an ARD should be returned. Defaults to \code{TRUE}.} \item{arm_var}{(\code{character})\cr Name of the treatment arm variable used to split table into columns.} @@ -41,8 +37,6 @@ make_table_02_rtables( \item{vars}{(\code{vector} of \code{character})\cr Variables from \code{df} to include in the table.} -\item{alt_counts_df}{(\code{character})\cr alternative dataset (typically ADSL) used only to calculate column counts.} - \item{show_colcounts}{(\code{flag})\cr Whether column counts should be printed. Boolean.} \item{lbl_vars}{(\code{vector} of \code{character})\cr labels corresponding to variables in \code{vars} to print @@ -110,11 +104,11 @@ adsl <- random.cdisc.data::cadsl \%>\% AGE >= 65 & AGE < 75 ~ ">=65 to <75", AGE >= 75 ~ ">=75" ))) -tbl_rtables <- cardinal:::make_table_05_rtables(df = adsl) +tbl_rtables <- make_table_02_rtables(df = adsl) tbl_rtables } \seealso{ -\code{\link{tbl_make_table_02}} +\code{\link{make_table_02}} \code{\link[=make_table_02]{make_table_02()}} } diff --git a/quarto/getting_started.qmd b/quarto/getting_started.qmd index 7986ca83..c80b1815 100644 --- a/quarto/getting_started.qmd +++ b/quarto/getting_started.qmd @@ -17,6 +17,9 @@ The `cardinal` package requires several packages available on CRAN. To use the `cardinal` package, ensure you have these necessary package dependencies installed by running the following code: ```{r, echo=TRUE, eval=FALSE} +if (!require("gtsummary")) install.packages("gtsummary") +if (!require("cards")) install.packages("cards") +if (!require("cardx")) install.packages("cardx") if (!require("formatters")) install.packages("formatters") if (!require("rtables")) install.packages("rtables") if (!require("rlistings")) install.packages("rlistings") @@ -63,7 +66,7 @@ Each template provided is associated with a function available within the `cardi ![](./assets/images/getting-started/gs-pan3.png){fig-align="center" width="90%"} -- **Function Details**: This tab includes details on the table-generating function used for this template. Table functions use the naming convention `make_table_XX()` where `XX` is the table number taken from the FDA Standard Safety Table and Figures document (preceded by a 0 if the number is a single digit). Any required variables for the input datasets are listed along with a description of all function arguments. This information is mirrored by the function's help page accessible within R (i.e. `?make_table_XX`). +- **Function Details**: This tab includes details on the table-generating function used for this template. Table functions use the naming convention `make_table_XX()` where `XX` is the table number taken from the FDA Standard Safety Table and Figures document (preceded by a 0 if the number is a single digit). Any required variables for the input datasets are listed along with a description of all function arguments. This information is mirrored by the function's help page accessible within R (i.e. `?make_table_XX`). By default, all table generating functions use the {gtsummary} package - though we do support rtables functionality. To specify the use of which table engine is being used, engine specific functions can be called (`make_table_02_rtables`, for example). ![](./assets/images/getting-started/gs-pan4.png){fig-align="center" width="90%"} @@ -90,8 +93,7 @@ adsl <- random.cdisc.data::cadsl %>% AGE >= 65 ~ ">=65", AGE >= 65 & AGE < 75 ~ ">=65 to <75", AGE >= 75 ~ ">=75" - )) %>% formatters::with_label("Age Group, years")) %>% - formatters::var_relabel(AGE = "Age, years") + ))) # Create table tbl <- make_table_02(df = adsl) @@ -115,18 +117,15 @@ anl <- left_join(adsl, advs, by = "USUBJID") %>% tern::df_explicit_na() tbl <- make_table_02( df = anl, - vars = c("SEX", "AGE", "RACE", "COUNTRY", "AVAL"), - lbl_vars = c("Sex", "Age, years", "Race", "Country of Participation", "Baseline Temperature (C)"), - lbl_overall = "Total\nPopulation", - na_rm = TRUE + vars = c("SEX", "AGE", "RACE", "COUNTRY", "AVAL") ) -tbl +tbl$tbl ``` Note that the `prune_0` argument can be set to specify whether all-zero rows should be included in a table. For example, see that the demographics table below includes rows for `OTHER` and `UNKNOWN` for which all values are zero, whereas these two rows were excluded from the previous tables (`prune_0` defaults to `TRUE` in `make_table_02()`). ```{r, echo=TRUE} -make_table_02(df = anl, vars = "RACE", prune_0 = FALSE) +make_table_02_rtables(df = anl, vars = "RACE", prune_0 = FALSE) ``` ### Feature Requests diff --git a/quarto/table-templates/template-table_02.qmd b/quarto/table-templates/template-table_02.qmd index f739b817..3899c6d3 100644 --- a/quarto/table-templates/template-table_02.qmd +++ b/quarto/table-templates/template-table_02.qmd @@ -35,7 +35,7 @@ adsl <- adsl %>% # Output Table make_table_02( df = adsl, - vars = c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY", "AVAL"), + vars = c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY"), return_ard = FALSE ) ``` @@ -59,7 +59,7 @@ Required variables: - **`denominator`** (if specified): `USUBJID` and the variables specified by `arm_var` and `saffl_var`. | | | | -|----|----|----| +|------------------------|------------------------|------------------------| | **Argument** | **Description** | **Default** | | `df` | (`data.frame`) Dataset (typically ADSL) required to build table. | *No default* | | `return_ard` | (`flag`) Whether an ARD should be returned. | `TRUE` | @@ -98,7 +98,7 @@ adsl <- adsl %>% # Create Table & ARD result <- make_table_02( df = adsl, - vars = c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY", "AVAL") + vars = c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY") ) # Output ARD @@ -109,7 +109,7 @@ result$ard ```{r tbl1-print, echo=FALSE} options(width = 9999) -print(result$ard, columns = "all", n = Inf) +print(result$ard, columns = "all") ``` ## rtables Table @@ -143,7 +143,7 @@ advs <- advs %>% anl <- left_join(adsl, advs, by = "USUBJID") # Output Table -make_table_02( +make_table_02_rtables( df = anl, vars = c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY", "AVAL"), lbl_vars = c( @@ -172,7 +172,7 @@ Required variables: - **`alt_counts_df`** (if specified): `USUBJID` and the variables specified by `arm_var` and `saffl_var`. | **Argument** | **Description** | **Default** | -|:---|:---|:---| +|:-----------------------|:-----------------------|:-----------------------| | `df` | (`data.frame`) Dataset (typically ADSL) required to build table. | *No default* | | `alt_counts_df` | (`character`) Alternative dataset used only to calculate column counts. | `NULL` | | `show_colcounts` | (`flag`) Whether column counts should be printed. | `TRUE` | From a1df7d0bab36e5784d90598f005626a3b6ddc4aa Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 12 Feb 2025 22:24:11 +0000 Subject: [PATCH 16/21] [skip style] [skip vbump] Restyle files --- quarto/getting_started.qmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quarto/getting_started.qmd b/quarto/getting_started.qmd index c80b1815..8ef2c53b 100644 --- a/quarto/getting_started.qmd +++ b/quarto/getting_started.qmd @@ -93,7 +93,7 @@ adsl <- random.cdisc.data::cadsl %>% AGE >= 65 ~ ">=65", AGE >= 65 & AGE < 75 ~ ">=65 to <75", AGE >= 75 ~ ">=75" - ))) + ))) # Create table tbl <- make_table_02(df = adsl) From 8551308c1c1c8c42cb85b49e1b875e7de1f28df7 Mon Sep 17 00:00:00 2001 From: ayogasekaram Date: Thu, 20 Feb 2025 21:56:33 +0000 Subject: [PATCH 17/21] add variable label, remove unused arguments --- R/fda-table_02.R | 4 ++-- quarto/table-templates/template-table_02.qmd | 6 +----- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/R/fda-table_02.R b/R/fda-table_02.R index 3e5ac559..818a241f 100644 --- a/R/fda-table_02.R +++ b/R/fda-table_02.R @@ -78,9 +78,9 @@ make_table_02 <- function(df, if (return_ard) { ard <- gtsummary::gather_ard(tbl) - res <- list(tbl = tbl, ard = ard) + return(list(table = tbl, ard = ard)) } else { - res <- list(tbl = tbl) + return(tbl) } } diff --git a/quarto/table-templates/template-table_02.qmd b/quarto/table-templates/template-table_02.qmd index 3899c6d3..d5f21d75 100644 --- a/quarto/table-templates/template-table_02.qmd +++ b/quarto/table-templates/template-table_02.qmd @@ -30,7 +30,7 @@ adsl <- adsl %>% AGE >= 65 & AGE < 75 ~ ">=65 to <75", AGE >= 75 ~ ">=75" ))) - +attr(adsl$AGEGR1, "label") <- "Age Group" # Output Table make_table_02( @@ -63,7 +63,6 @@ Required variables: | **Argument** | **Description** | **Default** | | `df` | (`data.frame`) Dataset (typically ADSL) required to build table. | *No default* | | `return_ard` | (`flag`) Whether an ARD should be returned. | `TRUE` | -| `denominator` | (`character`) Alternative dataset used only to calculate column counts. | `NULL` | | `arm_var` | (`character`) Arm variable used to split table into columns. | `"ARM"` | | `saffl_var` | (`character`) Flag variable used to indicate inclusion in safety population. | `"SAFFL"` | | `id_var` | (`character`) Identifier variable used to count the participants within each flag. | `"USUBJID"` | @@ -174,15 +173,12 @@ Required variables: | **Argument** | **Description** | **Default** | |:-----------------------|:-----------------------|:-----------------------| | `df` | (`data.frame`) Dataset (typically ADSL) required to build table. | *No default* | -| `alt_counts_df` | (`character`) Alternative dataset used only to calculate column counts. | `NULL` | | `show_colcounts` | (`flag`) Whether column counts should be printed. | `TRUE` | | `arm_var` | (`character`) Arm variable used to split table into columns. | `"ARM"` | | `saffl_var` | (`character`) Flag variable used to indicate inclusion in safety population. | `"SAFFL"` | | `vars` | (`character`) Variables from `df` to include in the table. | `c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY")` | | `lbl_vars` | (`character`) Labels corresponding to variables in `vars` to print in the table. Labels should be ordered according to the order of variables in `vars`. | `formatters::var_labels(df, fill = TRUE)[vars]` | | `lbl_overall` | (`character`) If specified, an overall column will be added to the table with the given value as the column label. | `"Total Population"` | -| `.stats` | (`character`) Statistics to include in the table. Includes statistics for all variable types (only the statistics that are valid for a given variable's type will be printed). See [`tern::analyze_vars()`](https://insightsengineering.github.io/tern/main/reference/analyze_variables.html#value) for options. | `c("mean_sd", "median_range", "count_fraction")` | -| `.formats` | (named `list` of `character`) List of formats corresponding to each value in `.stats`. Each name is a value in `.stats` and the corresponding value is the format that should be applied to that statistic. See [`formatters::list_valid_format_labels()`](https://insightsengineering.github.io/formatters/main/reference/list_valid_format_labels.html#ref-examples) for a list of valid formats. | `NULL` | | `prune_0` | (`flag`) Whether all-zero rows should be removed from the table. | `TRUE` | | `na_rm` | (`flag`) Whether `NA` levels should be removed from the table. | `FALSE` | | `annotations` | (named `list` of `character`) List of annotations to add to the table. Valid annotation types are `title`, `subtitles`, `main_footer`, and `prov_footer.` Each name-value pair should use the annotation type as name and the desired string as value. | `NULL` | From bb22d90d983aa775e3cda4d3689fb4967f1843dc Mon Sep 17 00:00:00 2001 From: ayogasekaram Date: Mon, 24 Feb 2025 17:08:22 +0000 Subject: [PATCH 18/21] fix lintr --- R/fda-table_02.R | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/R/fda-table_02.R b/R/fda-table_02.R index 818a241f..19ccdff2 100644 --- a/R/fda-table_02.R +++ b/R/fda-table_02.R @@ -1,7 +1,8 @@ #' FDA Table 2: Baseline Demographic and Clinical Characteristics, Safety Population, Pooled Analyses #' #' @details -#' * `df` must contain the variables specified by `arm_var`, `saffl_var`, and variables specified by the `vars` argument. +#' * `df` must contain the variables specified by `arm_var`, `saffl_var`, and +#' variables specified by the `vars` argument. #' * `vars` must be a character vector specifying the variables to evaluate. #' * `return_ard` set to `TRUE` or `FALSE`; whether the intermediate ARD #' object should be returned. From d332d11bec7d3652bdb46dc3d66317dfc1b42ece Mon Sep 17 00:00:00 2001 From: "27856297+dependabot-preview[bot]@users.noreply.github.com" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 24 Feb 2025 17:10:35 +0000 Subject: [PATCH 19/21] [skip roxygen] [skip vbump] Roxygen Man Pages Auto Update --- man/make_table_02.Rd | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/man/make_table_02.Rd b/man/make_table_02.Rd index 2ff8de72..7d9aa1bf 100644 --- a/man/make_table_02.Rd +++ b/man/make_table_02.Rd @@ -66,7 +66,8 @@ The table engine used by each engine-specific function is identified by its suff } \details{ \itemize{ -\item \code{df} must contain the variables specified by \code{arm_var}, \code{saffl_var}, and variables specified by the \code{vars} argument. +\item \code{df} must contain the variables specified by \code{arm_var}, \code{saffl_var}, and +variables specified by the \code{vars} argument. \item \code{vars} must be a character vector specifying the variables to evaluate. \item \code{return_ard} set to \code{TRUE} or \code{FALSE}; whether the intermediate ARD object should be returned. From 346b160c17b0fac69865921e6a7e0e0316fd24e4 Mon Sep 17 00:00:00 2001 From: ayogasekaram Date: Wed, 26 Feb 2025 21:29:42 +0000 Subject: [PATCH 20/21] adding baseline temp variable to table examples. --- quarto/table-templates/template-table_02.qmd | 24 ++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/quarto/table-templates/template-table_02.qmd b/quarto/table-templates/template-table_02.qmd index d5f21d75..f01f4b61 100644 --- a/quarto/table-templates/template-table_02.qmd +++ b/quarto/table-templates/template-table_02.qmd @@ -21,6 +21,7 @@ library(cardinal) library(dplyr) adsl <- random.cdisc.data::cadsl +advs <- random.cdisc.data::cadvs # Pre-Processing - Add any variables needed in your table to df adsl <- adsl %>% @@ -32,10 +33,17 @@ adsl <- adsl %>% ))) attr(adsl$AGEGR1, "label") <- "Age Group" +advs <- advs %>% + filter(AVISIT == "BASELINE", VSTESTCD == "TEMP") %>% + select("USUBJID", "AVAL") + +anl <- left_join(adsl, advs, by = "USUBJID") +attr(anl$AVAL, "label") <- "Baseline Temperature (C)" + # Output Table make_table_02( - df = adsl, - vars = c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY"), + df = anl, + vars = c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY", "AVAL"), return_ard = FALSE ) ``` @@ -84,6 +92,7 @@ library(cardinal) library(dplyr) adsl <- random.cdisc.data::cadsl +advs <- random.cdisc.data::cadvs # Pre-Processing - Add any variables needed in your table to df adsl <- adsl %>% @@ -94,10 +103,17 @@ adsl <- adsl %>% AGE >= 75 ~ ">=75" ))) +advs <- advs %>% + filter(AVISIT == "BASELINE", VSTESTCD == "TEMP") %>% + select("USUBJID", "AVAL") + +anl <- left_join(adsl, advs, by = "USUBJID") +attr(anl$AVAL, "label") <- "Baseline Temperature (C)" + # Create Table & ARD result <- make_table_02( - df = adsl, - vars = c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY") + df = anl, + vars = c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY", "AVAL") ) # Output ARD From ea542fa17c41d0cf125b84cf93ba47a083f67b3f Mon Sep 17 00:00:00 2001 From: ayogasekaram Date: Tue, 4 Mar 2025 08:23:43 +0000 Subject: [PATCH 21/21] assess checks passing --- tests/testthat/test-fda-table_02.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/testthat/test-fda-table_02.R b/tests/testthat/test-fda-table_02.R index dcda8a01..3962b3da 100644 --- a/tests/testthat/test-fda-table_02.R +++ b/tests/testthat/test-fda-table_02.R @@ -6,7 +6,7 @@ adsl <- adsl_raw %>% AGE >= 65 & AGE < 75 ~ ">=65 to <75", AGE >= 75 ~ ">=75" ))) %>% - df_explicit_na() + tern::df_explicit_na() test_that("Table 02 generation works with default values", { options(pillar.print_max = 50, width = 200)