diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 8aa3f577..8436c233 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -68,7 +68,7 @@ jobs: - name: Upload Docs ⬆️ if: github.event_name != 'push' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: site path: ./_site diff --git a/NAMESPACE b/NAMESPACE index dfff5c37..548e1838 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -7,8 +7,7 @@ export(make_fig_02) export(make_fig_03) export(make_fig_14) export(make_table_02) -export(make_table_02_gtsum) -export(make_table_02_tplyr) +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 e9ce5cdb..19ccdff2 100644 --- a/R/fda-table_02.R +++ b/R/fda-table_02.R @@ -1,24 +1,21 @@ #' 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`. -#' * If specified, `alt_counts_df` must contain the variables specified by `arm_var`, `id_var`, and `saffl_var`. +#' * `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"`. -#' * 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 make_table_02 #' @inheritParams argument_convention #' -#' @name make_table_02 -NULL - -#' @describeIn make_table_02 Create FDA table 2 using functions from `rtables` and `tern`. +#' @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 an `rtable` object. +#' @seealso [`make_table_02`] #' #' @examples #' library(dplyr) @@ -29,274 +26,127 @@ 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(df = adsl) #' tbl #' #' @export make_table_02 <- function(df, - alt_counts_df = NULL, - show_colcounts = TRUE, + return_ard = 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)) + vars = c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY")) { + # check data viability + 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") %>% - 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 -#' -#' @export -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() + select(all_of(c(vars, arm_var))) - if (na_rm) { - na_ind <- tbl[, 2] != "" - tbl <- tbl[na_ind, ] + if (any(is.na(df))) { + df <- df %>% df_explicit_na() } - 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 + # create a table using gtsummary + df %>% + gtsummary::tbl_summary( + by = arm_var + ) - 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")) + tbl <- df %>% + gtsummary::tbl_summary( + by = arm_var, + type = all_continuous() ~ "continuous2", + statistic = list( + all_continuous() ~ c( + "{mean} ({sd})", + "{median} ({min} - {max})" ), - 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")) - ) + all_categorical() ~ "{n} ({p}%)" ), - col_plan = col_plan(-starts_with("ord")), - big_n = big_n_tbl + digits = all_continuous() ~ 2, + missing = "no" ) %>% - print_to_gt(tbl) + gtsummary::bold_labels() %>% + gtsummary::modify_header(all_stat_cols() ~ "**{level}** \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") + + if (return_ard) { + ard <- gtsummary::gather_ard(tbl) + return(list(table = tbl, ard = ard)) + } else { + return(tbl) } - tbl } -#' @describeIn make_table_02 Create FDA table 2 using functions from `gtsummary`. +#' 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_gtsum` returns a `tbl_summary` object. +#' * `make_table_02_rtables()` returns an `rtable` object. +#' +#' @seealso [make_table_02()] #' #' @examples -#' tbl <- make_table_02_gtsum(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 <- make_table_02_rtables(df = adsl) +#' tbl_rtables +#' @rdname make_table_02 #' @export -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) { +make_table_02_rtables <- 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, + 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") %>% - select(all_of(c(vars, arm_var))) - - if (!na_rm) df <- df %>% df_explicit_na() + df_explicit_na() - tbl <- df %>% - tbl_summary( - by = arm_var, - type = all_continuous() ~ "continuous2", - statistic = list( - all_continuous() ~ c( - "{mean} ({sd})", - "{median} ({min} - {max})" - ), - all_categorical() ~ "{n} ({p}%)" - ), - digits = all_continuous() ~ 1, - missing = ifelse(na_rm, "no", "ifany"), - label = as.list(lbl_vars) %>% setNames(vars) + 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 ) %>% - gtsummary::bold_labels() %>% - modify_header(all_stat_cols() ~ "**{level}** \nN = {n}") %>% - 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_column_alignment(columns = all_stat_cols(), align = "right") + append_topleft("Characteristic") - gtsummary::with_gtsummary_theme( - x = gtsummary::theme_gtsummary_compact(), - expr = as_gt(tbl) - ) + 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 dc34b673..7d9aa1bf 100644 --- a/man/make_table_02.Rd +++ b/man/make_table_02.Rd @@ -2,27 +2,19 @@ % 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} +\alias{make_table_02_rtables} \title{FDA Table 2: Baseline Demographic and Clinical Characteristics, Safety Population, Pooled Analyses} \usage{ make_table_02( df, - alt_counts_df = NULL, - show_colcounts = TRUE, + return_ard = 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 + vars = c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY") ) -make_table_02_tplyr( +make_table_02_rtables( df, - alt_counts_df = NULL, show_colcounts = TRUE, arm_var = "ARM", saffl_var = "SAFFL", @@ -31,27 +23,13 @@ make_table_02_tplyr( 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 + annotations = NULL ) } \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{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.} @@ -59,6 +37,8 @@ make_table_02_gtsum( \item{vars}{(\code{vector} of \code{character})\cr Variables from \code{df} to include in the table.} +\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}.} @@ -72,52 +52,32 @@ the given value as the column label.} \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 \code{rtable} object. -} - -\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}. -} +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_gtsum} returns a \code{tbl_summary} object. +\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}, \code{arm_var}, and \code{saffl_var}. -\item If specified, \code{alt_counts_df} must contain the variables specified by \code{arm_var}, \code{id_var}, and \code{saffl_var}. +\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"}. -\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). -} } -\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}. -}} -\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}. +\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{ @@ -129,16 +89,27 @@ 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(df = adsl) tbl -tbl <- make_table_02_tplyr(df = adsl) -tbl +adsl <- random.cdisc.data::cadsl -tbl <- make_table_02_gtsum(df = adsl) -tbl +# 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 <- make_table_02_rtables(df = adsl) +tbl_rtables +} +\seealso{ +\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 96b9dbaa..8ef2c53b 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,26 +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, - 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" - ) - ) + 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 9de0066b..f01f4b61 100644 --- a/quarto/table-templates/template-table_02.qmd +++ b/quarto/table-templates/template-table_02.qmd @@ -9,9 +9,13 @@ 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) @@ -27,30 +31,31 @@ adsl <- adsl %>% AGE >= 65 & AGE < 75 ~ ">=65 to <75", AGE >= 75 ~ ">=75" ))) +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 = 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)" - ) + return_ard = FALSE ) ``` -## rtables Table Setup +
-```{r tbl, eval=FALSE, echo=TRUE} +```{r tbl2, message=FALSE, warning=FALSE, eval=TRUE} ``` -## Function Details: `make_table_02` +
+ +Function Details ### `make_table_02()` @@ -59,31 +64,31 @@ 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`. +- **`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` | +| `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"` | -| **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} +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 @@ -103,54 +108,33 @@ advs <- advs %>% select("USUBJID", "AVAL") anl <- left_join(adsl, advs, by = "USUBJID") +attr(anl$AVAL, "label") <- "Baseline Temperature (C)" -# Output Table -make_table_02_tplyr( +# Create Table & ARD +result <- 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)" - ) + vars = c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY", "AVAL") ) -``` -## Tplyr Table Setup - -```{r tbl_tplyr, eval=FALSE, echo=TRUE} +# Output ARD +result$ard ``` -## Function Details: `make_table_02_tplyr` - -### `make_table_02_tplyr()` +
------------------------------------------------------------------------- +```{r tbl1-print, echo=FALSE} +options(width = 9999) +print(result$ard, columns = "all") +``` -Required variables: +## rtables Table -- **`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 +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) @@ -161,10 +145,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 %>% @@ -174,42 +158,48 @@ advs <- advs %>% anl <- left_join(adsl, advs, by = "USUBJID") # Output Table -make_table_02_gtsum( +make_table_02_rtables( 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_gtsum` +
+ +Function Details -### `make_table_02_gtsum()` +### `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#L257). +- **`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* | +| `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`, `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). + +
::: diff --git a/tests/testthat/_snaps/fda-table_02.md b/tests/testthat/_snaps/fda-table_02.md index a23f2b1e..06c368d3 100644 --- a/tests/testthat/_snaps/fda-table_02.md +++ b/tests/testthat/_snaps/fda-table_02.md @@ -1,5 +1,146 @@ # Table 02 generation works with default values + Code + as.data.frame(res$tbl) + Output + **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.77 (6.55) 35.43 (7.90) 35.43 (7.72) 34.88 (7.44) + 6 Median (min - max) 33.00 (21.00 - 50.00) 35.00 (21.00 - 62.00) 35.00 (20.00 - 69.00) 34.00 (20.00 - 69.00) + 7 __AGEGR1, n (%)__ + 8 >=17 to <65 134 (100%) 134 (100%) 131 (99%) 399 (100%) + 9 >=65 0 (0%) 0 (0%) 1 (0.8%) 1 (0.3%) + 10 __Race, n (%)__ + 11 ASIAN 68 (51%) 67 (50%) 73 (55%) 208 (52%) + 12 BLACK OR AFRICAN AMERICAN 31 (23%) 28 (21%) 32 (24%) 91 (23%) + 13 WHITE 27 (20%) 26 (19%) 21 (16%) 74 (19%) + 14 AMERICAN INDIAN OR ALASKA NATIVE 8 (6.0%) 11 (8.2%) 6 (4.5%) 25 (6.3%) + 15 MULTIPLE 0 (0%) 1 (0.7%) 0 (0%) 1 (0.3%) + 16 NATIVE HAWAIIAN OR OTHER PACIFIC ISLANDER 0 (0%) 1 (0.7%) 0 (0%) 1 (0.3%) + 17 OTHER 0 (0%) 0 (0%) 0 (0%) 0 (0%) + 18 UNKNOWN 0 (0%) 0 (0%) 0 (0%) 0 (0%) + 19 __Ethnicity, n (%)__ + 20 HISPANIC OR LATINO 15 (11%) 18 (13%) 15 (11%) 48 (12%) + 21 NOT HISPANIC OR LATINO 104 (78%) 103 (77%) 101 (77%) 308 (77%) + 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.3%) + 24 __Country, n (%)__ + 25 CHN 74 (55%) 81 (60%) 64 (48%) 219 (55%) + 26 USA 10 (7.5%) 13 (9.7%) 17 (13%) 40 (10%) + 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.3%) + 33 CAN 3 (2.2%) 2 (1.5%) 3 (2.3%) 8 (2.0%) + 34 CHE 0 (0%) 0 (0%) 0 (0%) 0 (0%) + +--- + + Code + res$ard + Output + $tbl_summary + Message + {cards} data frame: 369 x 12 + Output + group1 group1_level variable variable_level stat_name stat_label stat + 1 ARM A: Drug X SEX F n n 79 + 2 ARM A: Drug X SEX F N N 134 + 3 ARM A: Drug X SEX F p % 0.59 + 4 ARM B: Place… SEX F n n 82 + 5 ARM B: Place… SEX F N N 134 + 6 ARM B: Place… SEX F p % 0.612 + 7 ARM C: Combi… SEX F n n 70 + 8 ARM C: Combi… SEX F N N 132 + 9 ARM C: Combi… SEX F p % 0.53 + 10 ARM A: Drug X SEX M n n 55 + Message + i 359 more rows + i Use `print(n = ...)` to see more rows + i 5 more variables: context, fmt_fn, warning, error, gts_column + Output + + $add_overall + Message + {cards} data frame: 131 x 10 + Output + variable variable_level context stat_name stat_label stat + 1 SEX F categori… n n 231 + 2 SEX F categori… N N 400 + 3 SEX F categori… p % 0.578 + 4 SEX M categori… n n 169 + 5 SEX M categori… N N 400 + 6 SEX M categori… p % 0.423 + 7 AGEGR1 >=17 to … categori… n n 399 + 8 AGEGR1 >=17 to … categori… N N 400 + 9 AGEGR1 >=17 to … categori… p % 0.998 + 10 AGEGR1 >=65 categori… n n 1 + Message + i 121 more rows + i Use `print(n = ...)` to see more rows + i 4 more variables: fmt_fn, warning, error, gts_column + Output + + +# Table 02 generation works with custom values + + Code + as.data.frame(result$tbl) + Output + **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.77 (6.55) 35.43 (7.90) 35.43 (7.72) 34.88 (7.44) + 6 Median (min - max) 33.00 (21.00 - 50.00) 35.00 (21.00 - 62.00) 35.00 (20.00 - 69.00) 34.00 (20.00 - 69.00) + 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.66 (1.02) 36.63 (1.07) 36.48 (1.00) 36.59 (1.03) + 34 Median (min - max) 36.67 (33.97 - 39.28) 36.63 (33.59 - 38.92) 36.49 (34.21 - 38.95) 36.60 (33.59 - 39.28) + +# Table 02 generation works with some NA values + + Code + as.data.frame(result$tbl) + Output + **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%) + +# Table 02 generation (rtables) works with default values + Code res Output @@ -12,7 +153,7 @@ 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 + AGEGR1 >=17 to <65 134 (100%) 134 (100%) 131 (99.2%) 399 (99.8%) >=65 0 0 1 (0.8%) 1 (0.2%) Race @@ -38,7 +179,7 @@ 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 works with custom values +# Table 02 generation (rtables) works with custom values Code res @@ -89,7 +230,7 @@ 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 +# Table 02 generation (rtables) works with some NA values Code res @@ -98,270 +239,6 @@ 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) - -# Table 02 generation (gtsum) works with some NA values - - Code - res - 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%) + F 68 (57.6%) 68 (58.6%) 62 (53.4%) 198 (56.6%) + M 50 (42.4%) 48 (41.4%) 54 (46.6%) 152 (43.4%) diff --git a/tests/testthat/test-fda-table_02.R b/tests/testthat/test-fda-table_02.R index 56bf742b..3962b3da 100644 --- a/tests/testthat/test-fda-table_02.R +++ b/tests/testthat/test-fda-table_02.R @@ -1,113 +1,48 @@ adsl <- adsl_raw %>% filter(SAFFL == "Y") %>% - df_explicit_na() + 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" + ))) %>% + tern::df_explicit_na() test_that("Table 02 generation works with default values", { - result <- make_table_02(adsl) + options(pillar.print_max = 50, width = 200) + result <- make_table_02(adsl) res <- expect_silent(result) - expect_snapshot(res) + expect_snapshot(res$tbl |> as.data.frame()) + expect_snapshot(res$ard) + + # no ARD + result2 <- make_table_05(adsl, return_ard = FALSE) + res2 <- expect_silent(result2) + + # tables the same + expect_identical(res$tbl, res2) }) 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 <- make_table_02( 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" - ) - ) + 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 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(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 <- 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) @@ -115,51 +50,55 @@ test_that("Table 02 generation (tplyr) works with some NA values", { adsl <- adsl %>% df_explicit_na() - result <- withr::with_options( - opts_partial_match_old, - make_table_02_tplyr(adsl, vars = "SEX", lbl_vars = "Sex") - ) + result <- suppressWarnings(make_table_02(adsl, vars = "SEX")) - res <- expect_silent(result[["_data"]]) - expect_snapshot(res) + res <- expect_silent(result) + expect_snapshot(result$tbl |> as.data.frame()) }) -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()) +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 (gtsum) works with custom values", { - options(pillar.print_max = 50, width = 200) - +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 <- suppressWarnings(make_table_02_gtsum( + result <- make_table_02_rtables( anl, - vars = c("SEX", "AGE", "AGEGR1", "RACE", "ETHNIC", "COUNTRY", "AVAL") - ) %>% gt::extract_body()) + 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 (gtsum) works with some NA values", { - options(pillar.print_max = 50, width = 200) - +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 <- suppressWarnings(make_table_02_gtsum(adsl, vars = "SEX") %>% gt::extract_body()) + result <- make_table_02_rtables(adsl, vars = "SEX", lbl_vars = "Sex") res <- expect_silent(result) expect_snapshot(res)