diff --git a/DESCRIPTION b/DESCRIPTION index 0f18853b1..680c0d024 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -43,7 +43,7 @@ Imports: data.table, dplyr, gsDesign, - gt, + lt, methods, mvtnorm, npsurvSS (>= 1.1.0), @@ -67,5 +67,7 @@ VignetteBuilder: knitr LinkingTo: Rcpp +Remotes: + yihui/lt Roxygen: list(markdown = TRUE) -RoxygenNote: 7.3.3 +Config/roxygen2/version: 8.0.0 diff --git a/NAMESPACE b/NAMESPACE index 3c12c9f04..cfc36dc9d 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,8 +1,7 @@ # Generated by roxygen2: do not edit by hand -S3method(as_gt,fixed_design_summary) -S3method(as_gt,gs_design_summary) -S3method(as_gt,simtrial_gs_wlr) +S3method(as_lt,fixed_design_summary) +S3method(as_lt,gs_design_summary) S3method(as_rtf,fixed_design_summary) S3method(as_rtf,gs_design_summary) S3method(print,fixed_design) @@ -14,6 +13,7 @@ S3method(to_integer,gs_design) export(ahr) export(ahr_blinded) export(as_gt) +export(as_lt) export(as_rtf) export(define_enroll_rate) export(define_fail_rate) diff --git a/R/as_gt.R b/R/as_gt.R index c7a2b8bb0..09916e0db 100644 --- a/R/as_gt.R +++ b/R/as_gt.R @@ -16,256 +16,22 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -#' Convert summary table of a fixed or group sequential design object to a gt object +#' Deprecated: superseded by [as_lt()] #' -#' @param x A summary object of a fixed or group sequential design. -#' @param ... Additional arguments (not used). -#' -#' @return A `gt_tbl` object. -#' -#' @export -as_gt <- function(x, ...) { - UseMethod("as_gt", x) -} - -#' @rdname as_gt -#' -#' @export -#' -#' @examples -#' # Fixed design examples ---- -#' -#' # Enrollment rate -#' enroll_rate <- define_enroll_rate( -#' duration = 18, -#' rate = 20 -#' ) -#' -#' # Failure rates -#' fail_rate <- define_fail_rate( -#' duration = c(4, 100), -#' fail_rate = log(2) / 12, -#' dropout_rate = .001, -#' hr = c(1, .6) -#' ) -#' -#' # Study duration in months -#' study_duration <- 36 +#' `as_gt()` is deprecated; use [as_lt()] instead. It now calls [as_lt()]. #' -#' # Experimental / Control randomization ratio -#' ratio <- 1 -#' -#' # 1-sided Type I error -#' alpha <- 0.025 +#' @param x A summary object of a fixed or group sequential design. +#' @param ... Additional arguments passed to [as_lt()]. #' -#' # Type II error (1 - power) -#' beta <- 0.1 +#' @return An `lt_tbl` object. #' -#' # Example 1 ---- -#' fixed_design_ahr( -#' alpha = alpha, power = 1 - beta, -#' enroll_rate = enroll_rate, fail_rate = fail_rate, -#' study_duration = study_duration, ratio = ratio -#' ) |> -#' summary() |> -#' as_gt() -#' -#' # Example 2 ---- -#' fixed_design_fh( -#' alpha = alpha, power = 1 - beta, -#' enroll_rate = enroll_rate, fail_rate = fail_rate, -#' study_duration = study_duration, ratio = ratio -#' ) |> -#' summary() |> -#' as_gt() -as_gt.fixed_design_summary <- function(x, title = NULL, footnote = NULL, ...) { - if (is.null(title)) title <- attr(x, "title") - if (is.null(footnote)) footnote <- attr(x, "footnote") - - ans <- gt::gt(x) |> - gt::tab_header(title = title) - - if (!isFALSE(footnote)) { - ans <- ans |> - gt::tab_footnote( - footnote = footnote, - locations = gt::cells_title(group = "title") - ) - } - - return(ans) -} - -#' @rdname as_gt -#' -#' @param title A string to specify the title of the gt table. -#' @param subtitle A string to specify the subtitle of the gt table. -#' @param colname_spanner A string to specify the spanner of the gt table. -#' @param colname_spannersub A vector of strings to specify the spanner details -#' of the gt table. -#' @param footnote A list containing `content`, `location`, and `attr`. -#' `content` is a vector of string to specify the footnote text; `location` is -#' a vector of string to specify the locations to put the superscript of the -#' footnote index; `attr` is a vector of string to specify the attributes of -#' the footnotes, for example, `c("colname", "title", "subtitle", "analysis", -#' "spanner")`; users can use the functions in the `gt` package to customize -#' the table. To disable footnotes, use `footnote = FALSE`. -#' @param display_bound A vector of strings specifying the label of the bounds. -#' The default is `c("Efficacy", "Futility")`. -#' @param display_columns A vector of strings specifying the variables to be -#' displayed in the summary table. -#' @param display_inf_bound Logical, whether to display the +/-inf bound. +#' @seealso [as_lt()] #' #' @export -#' -#' @examples -#' \donttest{ -#' # Group sequential design examples --- -#' -#' # Example 1 ---- -#' # The default output -#' -#' gs_design_ahr() |> -#' summary() |> -#' as_gt() -#' -#' gs_power_ahr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) |> -#' summary() |> -#' as_gt() -#' -#' gs_design_wlr() |> -#' summary() |> -#' as_gt() -#' -#' gs_power_wlr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) |> -#' summary() |> -#' as_gt() -#' -#' gs_power_combo() |> -#' summary() |> -#' as_gt() -#' -#' gs_design_rd() |> -#' summary() |> -#' as_gt() -#' -#' gs_power_rd() |> -#' summary() |> -#' as_gt() -#' -#' # Example 2 ---- -#' # Usage of title = ..., subtitle = ... -#' # to edit the title/subtitle -#' gs_power_wlr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) |> -#' summary() |> -#' as_gt( -#' title = "Bound Summary", -#' subtitle = "from gs_power_wlr" -#' ) -#' -#' # Example 3 ---- -#' # Usage of colname_spanner = ..., colname_spannersub = ... -#' # to edit the spanner and its sub-spanner -#' gs_power_wlr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) |> -#' summary() |> -#' as_gt( -#' colname_spanner = "Cumulative probability to cross boundaries", -#' colname_spannersub = c("under H1", "under H0") -#' ) -#' -#' # Example 4 ---- -#' # Usage of footnote = ... -#' # to edit the footnote -#' gs_power_wlr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) |> -#' summary() |> -#' as_gt( -#' footnote = list( -#' content = c( -#' "approximate weighted hazard ratio to cross bound.", -#' "wAHR is the weighted AHR.", -#' "the crossing probability.", -#' "this table is generated by gs_power_wlr." -#' ), -#' location = c("~wHR at bound", NA, NA, NA), -#' attr = c("colname", "analysis", "spanner", "title") -#' ) -#' ) -#' -#' # Example 5 ---- -#' # Usage of display_bound = ... -#' # to either show efficacy bound or futility bound, or both(default) -#' gs_power_wlr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) |> -#' summary() |> -#' as_gt(display_bound = "Efficacy") -#' -#' # Example 6 ---- -#' # Usage of display_columns = ... -#' # to select the columns to display in the summary table -#' gs_power_wlr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) |> -#' summary() |> -#' as_gt(display_columns = c("Analysis", "Bound", "Nominal p", "Z", "Probability")) -#' } -as_gt.gs_design_summary <- function( - x, - title = NULL, - subtitle = NULL, - colname_spanner = "Cumulative boundary crossing probability", - colname_spannersub = c("Alternate hypothesis", "Null hypothesis"), - footnote = NULL, - display_bound = c("Efficacy", "Futility"), - display_columns = NULL, - display_inf_bound = FALSE, - ...) { - - x_old <- x - parts <- gsd_parts( - x, title, subtitle, colname_spannersub, footnote, - display_bound, display_columns, display_inf_bound - ) - - x <- parts$x |> - group_by(Analysis) |> - gt::gt() |> - gt::tab_spanner( - columns = all_of(colname_spannersub), - label = colname_spanner - ) |> - gt::tab_header(title = parts$title, subtitle = parts$subtitle) - - # Add footnotes ---- - add_footnote <- !isFALSE(footnote) - footnote <- parts$footnote - for (i in seq_along(footnote$content)) { - att <- footnote$attr[i] - loc <- if (att == "colname") { - # footnotes are added on the colnames - gt::cells_column_labels(columns = footnote$location[i]) - } else if (att %in% c("title", "subtitle")) { - # on the title/subtitle - gt::cells_title(group = att) - } else if (att == "analysis") { - # on the analysis summary row, which is a grouping variable, i.e., Analysis - gt::cells_row_groups(groups = dplyr::starts_with("Analysis")) - } else if (att == "spanner") { - # on the column spanner - gt::cells_column_spanners(spanners = colname_spanner) - } - if (!is.null(loc)) - x <- gt::tab_footnote(x, footnote = footnote$content[i], locations = loc) - } - - # add footnote for non-binding design - footnote_nb <- if (add_footnote) gsd_footnote_nb(x_old, parts$alpha) - if (!is.null(footnote_nb)) x <- gt::tab_footnote( - x, - footnote = footnote_nb, - locations = gt::cells_body( - columns = colname_spannersub[2], - rows = gsd_footnote_row(parts$x, display_bound[1]) - ) - ) - - return(x) +as_gt <- function(x, ...) { + .Deprecated("as_lt", package = "gsDesign2", + msg = "as_gt() is deprecated; please use as_lt() instead.") + as_lt(x, ...) } # get different default columns to display @@ -349,7 +115,7 @@ gsd_footnote_row <- function(x, bound) { i & x$Bound == bound } -# a list of information for `as_[gt|rtf].gs_design()` methods: the transformed +# a list of information for `as_[lt|rtf].gs_design()` methods: the transformed # data, title, and footnote, etc. gsd_parts <- function( x, title, subtitle, spannersub, footnote, bound, columns, inf_bound, @@ -388,12 +154,3 @@ gsd_parts <- function( alpha = max(filter(x, Bound == bound[1])[["Null hypothesis"]]) ) } - -# Only purpose of the method below is to fix S3 redirection when gsDesign2 is -# loaded after simtrial, which masks the as_gt() generic from simtrial - -#' @export -as_gt.simtrial_gs_wlr <- function(x, ...) { - f <- getFromNamespace("as_gt.simtrial_gs_wlr", "simtrial") - f(x, ...) -} diff --git a/R/as_lt.R b/R/as_lt.R new file mode 100644 index 000000000..ce28e4df3 --- /dev/null +++ b/R/as_lt.R @@ -0,0 +1,260 @@ +# Copyright (c) 2025 Merck & Co., Inc., Rahway, NJ, USA and its affiliates. +# All rights reserved. +# +# This file is part of the gsDesign2 program. +# +# gsDesign2 is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +#' Convert summary table of a fixed or group sequential design object to an lt table +#' +#' @param x A summary object of a fixed or group sequential design. +#' @param ... Additional arguments (not used). +#' +#' @return An `lt_tbl` object. +#' +#' @export +as_lt <- function(x, ...) { + UseMethod("as_lt", x) +} + +#' @rdname as_lt +#' +#' @export +#' +#' @examples +#' # Fixed design examples ---- +#' +#' # Enrollment rate +#' enroll_rate <- define_enroll_rate( +#' duration = 18, +#' rate = 20 +#' ) +#' +#' # Failure rates +#' fail_rate <- define_fail_rate( +#' duration = c(4, 100), +#' fail_rate = log(2) / 12, +#' dropout_rate = .001, +#' hr = c(1, .6) +#' ) +#' +#' # Study duration in months +#' study_duration <- 36 +#' +#' # Experimental / Control randomization ratio +#' ratio <- 1 +#' +#' # 1-sided Type I error +#' alpha <- 0.025 +#' +#' # Type II error (1 - power) +#' beta <- 0.1 +#' +#' # Example 1 ---- +#' fixed_design_ahr( +#' alpha = alpha, power = 1 - beta, +#' enroll_rate = enroll_rate, fail_rate = fail_rate, +#' study_duration = study_duration, ratio = ratio +#' ) |> +#' summary() |> +#' as_lt() +#' +#' # Example 2 ---- +#' fixed_design_fh( +#' alpha = alpha, power = 1 - beta, +#' enroll_rate = enroll_rate, fail_rate = fail_rate, +#' study_duration = study_duration, ratio = ratio +#' ) |> +#' summary() |> +#' as_lt() +as_lt.fixed_design_summary <- function(x, title = NULL, footnote = NULL, ...) { + if (is.null(title)) title <- attr(x, "title") + if (is.null(footnote)) footnote <- attr(x, "footnote") + + ans <- lt::lt(as.data.frame(x)) |> + lt::lt_header(title = title) + + if (!isFALSE(footnote)) { + ans <- ans |> + lt::lt_footnote(text = footnote, where = "title") + } + + ans +} + +#' @rdname as_lt +#' +#' @param title A string to specify the title of the table. +#' @param subtitle A string to specify the subtitle of the table. +#' @param colname_spanner A string to specify the spanner of the table. +#' @param colname_spannersub A vector of strings to specify the spanner details +#' of the table. +#' @param footnote A list containing `content`, `location`, and `attr`. +#' `content` is a vector of string to specify the footnote text; `location` is +#' a vector of string to specify the locations to put the superscript of the +#' footnote index; `attr` is a vector of string to specify the attributes of +#' the footnotes, for example, `c("colname", "title", "subtitle", "analysis", +#' "spanner")`. To disable footnotes, use `footnote = FALSE`. +#' @param display_bound A vector of strings specifying the label of the bounds. +#' The default is `c("Efficacy", "Futility")`. +#' @param display_columns A vector of strings specifying the variables to be +#' displayed in the summary table. +#' @param display_inf_bound Logical, whether to display the +/-inf bound. +#' +#' @export +#' +#' @examples +#' \donttest{ +#' # Group sequential design examples --- +#' +#' # Example 1 ---- +#' # The default output +#' +#' gs_design_ahr() |> +#' summary() |> +#' as_lt() +#' +#' gs_power_ahr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) |> +#' summary() |> +#' as_lt() +#' +#' gs_design_wlr() |> +#' summary() |> +#' as_lt() +#' +#' gs_power_wlr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) |> +#' summary() |> +#' as_lt() +#' +#' gs_power_combo() |> +#' summary() |> +#' as_lt() +#' +#' gs_design_rd() |> +#' summary() |> +#' as_lt() +#' +#' gs_power_rd() |> +#' summary() |> +#' as_lt() +#' +#' # Example 2 ---- +#' # Usage of title = ..., subtitle = ... +#' # to edit the title/subtitle +#' gs_power_wlr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) |> +#' summary() |> +#' as_lt( +#' title = "Bound Summary", +#' subtitle = "from gs_power_wlr" +#' ) +#' +#' # Example 3 ---- +#' # Usage of colname_spanner = ..., colname_spannersub = ... +#' # to edit the spanner and its sub-spanner +#' gs_power_wlr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) |> +#' summary() |> +#' as_lt( +#' colname_spanner = "Cumulative probability to cross boundaries", +#' colname_spannersub = c("under H1", "under H0") +#' ) +#' +#' # Example 4 ---- +#' # Usage of footnote = ... +#' # to edit the footnote +#' gs_power_wlr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) |> +#' summary() |> +#' as_lt( +#' footnote = list( +#' content = c( +#' "approximate weighted hazard ratio to cross bound.", +#' "wAHR is the weighted AHR.", +#' "the crossing probability.", +#' "this table is generated by gs_power_wlr." +#' ), +#' location = c("~wHR at bound", NA, NA, NA), +#' attr = c("colname", "analysis", "spanner", "title") +#' ) +#' ) +#' +#' # Example 5 ---- +#' # Usage of display_bound = ... +#' # to either show efficacy bound or futility bound, or both(default) +#' gs_power_wlr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) |> +#' summary() |> +#' as_lt(display_bound = "Efficacy") +#' +#' # Example 6 ---- +#' # Usage of display_columns = ... +#' # to select the columns to display in the summary table +#' gs_power_wlr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) |> +#' summary() |> +#' as_lt(display_columns = c("Analysis", "Bound", "Nominal p", "Z", "Probability")) +#' } +as_lt.gs_design_summary <- function( + x, + title = NULL, + subtitle = NULL, + colname_spanner = "Cumulative boundary crossing probability", + colname_spannersub = c("Alternate hypothesis", "Null hypothesis"), + footnote = NULL, + display_bound = c("Efficacy", "Futility"), + display_columns = NULL, + display_inf_bound = FALSE, + ...) { + + x_old <- x + parts <- gsd_parts( + x, title, subtitle, colname_spannersub, footnote, + display_bound, display_columns, display_inf_bound + ) + + ans <- lt::lt(as.data.frame(parts$x)) |> lt::lt_group(~ Analysis) |> + lt::lt_spanner( + label = colname_spanner, + columns = colname_spannersub + ) |> + lt::lt_header(title = parts$title, subtitle = parts$subtitle) + + # Add footnotes + add_footnote <- !isFALSE(footnote) + footnote <- parts$footnote + for (i in seq_along(footnote$content)) { + att <- footnote$attr[i] + if (att == "colname") { + ans <- lt::lt_footnote(ans, text = footnote$content[i], + where = "column", columns = footnote$location[i]) + } else if (att == "title") { + ans <- lt::lt_footnote(ans, text = footnote$content[i], where = "title") + } else if (att == "subtitle") { + ans <- lt::lt_footnote(ans, text = footnote$content[i], where = "subtitle") + } else if (att == "analysis") { + ans <- lt::lt_footnote(ans, text = footnote$content[i], + where = "group", columns = "Analysis", + match = "starts_with") + } else if (att == "spanner") { + ans <- lt::lt_footnote(ans, text = footnote$content[i], + where = "spanner", columns = colname_spanner) + } + } + + # Add footnote for non-binding design + footnote_nb <- if (add_footnote) gsd_footnote_nb(x_old, parts$alpha) + if (!is.null(footnote_nb)) { + rows <- which(gsd_footnote_row(parts$x, display_bound[1])) + ans <- lt::lt_footnote(ans, text = footnote_nb, where = "body", + columns = colname_spannersub[2], rows = rows) + } + + ans +} diff --git a/R/globals.R b/R/globals.R index 3adf300d0..112eef4a0 100644 --- a/R/globals.R +++ b/R/globals.R @@ -25,7 +25,7 @@ utils::globalVariables( c("stratum", "rate", "hr", "treatment", "time", "info0", "info"), # From `ahr_blinded()` c("status"), - # From `as_gt.gs_design()` + # From `as_lt.gs_design()` c("Bound", "Alternate hypothesis", "Null hypothesis", "Analysis"), # From `expected_accrual()` c("stratum", "rate", "duration"), diff --git a/R/summary.R b/R/summary.R index 821944c9d..50965eddc 100644 --- a/R/summary.R +++ b/R/summary.R @@ -82,7 +82,7 @@ summary.fixed_design <- function(object, ...) { # capitalize names ans <- cap_names(ans) - # Propagate attributes for as_gt()/as_rtf() tables + # Propagate attributes for as_lt()/as_rtf() tables attr(ans, "title") <- attr(object, "title") attr(ans, "footnote") <- attr(object, "footnote") diff --git a/R/utility_tidy_tbl.R b/R/utility_tidy_tbl.R index 423b1682f..f49bd001a 100644 --- a/R/utility_tidy_tbl.R +++ b/R/utility_tidy_tbl.R @@ -37,7 +37,7 @@ #' #' @examples #' library(tidyr) -#' library(gt) +#' library(lt) #' a <- data.frame(Index = 1:2, a1 = c(1.1234, 5.9876), a2 = c("text 1", "text 2"), a3 = c(3.12, 4.98)) #' b <- data.frame( #' Index = c(1, 2, 2), @@ -46,17 +46,16 @@ #' b3 = (10:8) / 3 #' ) #' table_ab(a, b, byvar = "Index", decimals = c(0, 2, 0, 1), aname = "Index") |> -#' group_by(Index) |> -#' gt() |> -#' fmt_number(b3, decimals = 2) |> -#' tab_header(title = "Grouped data table") |> -#' tab_footnote( +#' lt() |> lt_group(~ Index) |> +#' lt_format("b3", decimals = 2) |> +#' lt_header(title = "Grouped data table") |> +#' lt_footnote( #' "The table a variables have been concatenated into a text string, rounded appropriately.", -#' cells_row_groups(groups = 1) +#' where = "group", columns = "1" #' ) |> -#' tab_footnote( +#' lt_footnote( #' "Note that footnotes cannot be made for individual variables in the row groups generated using table a.", -#' cells_row_groups(groups = 2) +#' where = "group", columns = "2" #' ) table_ab <- function(table_a, table_b, byvar, decimals = 1, aname = names(table_a)[1]) { anames <- names(table_a) diff --git a/README.Rmd b/README.Rmd index 8b6693bb9..bddd0b81a 100644 --- a/README.Rmd +++ b/README.Rmd @@ -96,13 +96,11 @@ rows and strata as needed can be specified to approximate whatever patterns you wish. ```{r, eval = FALSE} -fail_rate |> gt::gt() +fail_rate |> lt() ``` -```{r, echo = FALSE, eval = getRversion() >= "4.1"} -fail_rate |> - gt::gt() |> - gt::as_raw_html(inline_css = FALSE) +```{r, echo = FALSE} +knitr::kable(fail_rate) ``` ### Step 2: derive a fixed design with no interim analyses @@ -126,13 +124,11 @@ fd <- fixed_design_ahr( The input enrollment rates have now been scaled to achieve power: ```{r, eval = FALSE} -fd$enroll_rate |> gt::gt() +fd$enroll_rate |> lt() ``` -```{r, echo = FALSE, eval = getRversion() >= "4.1"} -fd$enroll_rate |> - gt::gt() |> - gt::as_raw_html(inline_css = FALSE) +```{r, echo = FALSE} +knitr::kable(fd$enroll_rate) ``` The failure and dropout rates remain unchanged from what was input. @@ -149,14 +145,11 @@ The summary is obtained below. The columns are: ```{r, eval = FALSE} fd |> summary() |> - as_gt() + as_lt() ``` -```{r, echo = FALSE, eval = getRversion() >= "4.1"} -fd |> - summary() |> - as_gt() |> - gt::as_raw_html(inline_css = FALSE) +```{r, echo = FALSE} +knitr::kable(fd |> summary()) ``` ### Step 3: group sequential design @@ -200,8 +193,7 @@ gsd <- gs_design_ahr( ``` Now we summarize the derived design. The summary table is further described -in the vignette [summarize group sequential designs in gt -tables](https://merck.github.io/gsDesign2/articles/story-summarize-designs.html). +in the vignette [summarize group sequential designs](https://merck.github.io/gsDesign2/articles/story-summarize-designs.html). Note that the design trend in favor of experimental treatment is very minor at 8 months due to the delayed effect assumption used (see AHR at analysis 1 in table). The design trend at 16 months is somewhat @@ -213,12 +205,9 @@ provocative for what might be considered. ```{r, eval = FALSE} gsd |> summary() |> - as_gt() + as_lt() ``` -```{r, echo = FALSE, eval = getRversion() >= "4.1"} -gsd |> - summary() |> - as_gt() |> - gt::as_raw_html(inline_css = FALSE) +```{r, echo = FALSE} +knitr::kable(gsd |> summary()) ``` diff --git a/_pkgdown.yml b/_pkgdown.yml index 732aad044..39cf53238 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -93,9 +93,10 @@ reference: - summary.fixed_design - summary.gs_design - text_summary + - as_lt + - as_lt.fixed_design_summary + - as_lt.gs_design_summary - as_gt - - as_gt.fixed_design_summary - - as_gt.gs_design_summary - as_rtf - as_rtf.fixed_design_summary - as_rtf.gs_design_summary diff --git a/inst/achieved_vignettes/style.Rmd b/inst/achieved_vignettes/style.Rmd index 7954e8d6a..6cccdc6f6 100644 --- a/inst/achieved_vignettes/style.Rmd +++ b/inst/achieved_vignettes/style.Rmd @@ -64,10 +64,10 @@ connect the method name and class name. ```r # Good -as_gt.gsDesign <- function(...) {} +as_lt.gsDesign <- function(...) {} # Bad -as.gt.gsDesign <- function(...) {} +as.lt.gsDesign <- function(...) {} ``` ## Object-oriented API diff --git a/man/as_gt.Rd b/man/as_gt.Rd index 4912d73de..b8d9341ce 100644 --- a/man/as_gt.Rd +++ b/man/as_gt.Rd @@ -2,192 +2,21 @@ % Please edit documentation in R/as_gt.R \name{as_gt} \alias{as_gt} -\alias{as_gt.fixed_design_summary} -\alias{as_gt.gs_design_summary} -\title{Convert summary table of a fixed or group sequential design object to a gt object} +\title{Deprecated: superseded by \code{\link[=as_lt]{as_lt()}}} \usage{ as_gt(x, ...) - -\method{as_gt}{fixed_design_summary}(x, title = NULL, footnote = NULL, ...) - -\method{as_gt}{gs_design_summary}( - x, - title = NULL, - subtitle = NULL, - colname_spanner = "Cumulative boundary crossing probability", - colname_spannersub = c("Alternate hypothesis", "Null hypothesis"), - footnote = NULL, - display_bound = c("Efficacy", "Futility"), - display_columns = NULL, - display_inf_bound = FALSE, - ... -) } \arguments{ \item{x}{A summary object of a fixed or group sequential design.} -\item{...}{Additional arguments (not used).} - -\item{title}{A string to specify the title of the gt table.} - -\item{footnote}{A list containing \code{content}, \code{location}, and \code{attr}. -\code{content} is a vector of string to specify the footnote text; \code{location} is -a vector of string to specify the locations to put the superscript of the -footnote index; \code{attr} is a vector of string to specify the attributes of -the footnotes, for example, \code{c("colname", "title", "subtitle", "analysis", "spanner")}; users can use the functions in the \code{gt} package to customize -the table. To disable footnotes, use \code{footnote = FALSE}.} - -\item{subtitle}{A string to specify the subtitle of the gt table.} - -\item{colname_spanner}{A string to specify the spanner of the gt table.} - -\item{colname_spannersub}{A vector of strings to specify the spanner details -of the gt table.} - -\item{display_bound}{A vector of strings specifying the label of the bounds. -The default is \code{c("Efficacy", "Futility")}.} - -\item{display_columns}{A vector of strings specifying the variables to be -displayed in the summary table.} - -\item{display_inf_bound}{Logical, whether to display the +/-inf bound.} +\item{...}{Additional arguments passed to \code{\link[=as_lt]{as_lt()}}.} } \value{ -A \code{gt_tbl} object. +An \code{lt_tbl} object. } \description{ -Convert summary table of a fixed or group sequential design object to a gt object -} -\examples{ -# Fixed design examples ---- - -# Enrollment rate -enroll_rate <- define_enroll_rate( - duration = 18, - rate = 20 -) - -# Failure rates -fail_rate <- define_fail_rate( - duration = c(4, 100), - fail_rate = log(2) / 12, - dropout_rate = .001, - hr = c(1, .6) -) - -# Study duration in months -study_duration <- 36 - -# Experimental / Control randomization ratio -ratio <- 1 - -# 1-sided Type I error -alpha <- 0.025 - -# Type II error (1 - power) -beta <- 0.1 - -# Example 1 ---- -fixed_design_ahr( - alpha = alpha, power = 1 - beta, - enroll_rate = enroll_rate, fail_rate = fail_rate, - study_duration = study_duration, ratio = ratio -) |> - summary() |> - as_gt() - -# Example 2 ---- -fixed_design_fh( - alpha = alpha, power = 1 - beta, - enroll_rate = enroll_rate, fail_rate = fail_rate, - study_duration = study_duration, ratio = ratio -) |> - summary() |> - as_gt() -\donttest{ -# Group sequential design examples --- - -# Example 1 ---- -# The default output - -gs_design_ahr() |> - summary() |> - as_gt() - -gs_power_ahr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) |> - summary() |> - as_gt() - -gs_design_wlr() |> - summary() |> - as_gt() - -gs_power_wlr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) |> - summary() |> - as_gt() - -gs_power_combo() |> - summary() |> - as_gt() - -gs_design_rd() |> - summary() |> - as_gt() - -gs_power_rd() |> - summary() |> - as_gt() - -# Example 2 ---- -# Usage of title = ..., subtitle = ... -# to edit the title/subtitle -gs_power_wlr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) |> - summary() |> - as_gt( - title = "Bound Summary", - subtitle = "from gs_power_wlr" - ) - -# Example 3 ---- -# Usage of colname_spanner = ..., colname_spannersub = ... -# to edit the spanner and its sub-spanner -gs_power_wlr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) |> - summary() |> - as_gt( - colname_spanner = "Cumulative probability to cross boundaries", - colname_spannersub = c("under H1", "under H0") - ) - -# Example 4 ---- -# Usage of footnote = ... -# to edit the footnote -gs_power_wlr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) |> - summary() |> - as_gt( - footnote = list( - content = c( - "approximate weighted hazard ratio to cross bound.", - "wAHR is the weighted AHR.", - "the crossing probability.", - "this table is generated by gs_power_wlr." - ), - location = c("~wHR at bound", NA, NA, NA), - attr = c("colname", "analysis", "spanner", "title") - ) - ) - -# Example 5 ---- -# Usage of display_bound = ... -# to either show efficacy bound or futility bound, or both(default) -gs_power_wlr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) |> - summary() |> - as_gt(display_bound = "Efficacy") - -# Example 6 ---- -# Usage of display_columns = ... -# to select the columns to display in the summary table -gs_power_wlr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) |> - summary() |> - as_gt(display_columns = c("Analysis", "Bound", "Nominal p", "Z", "Probability")) +\code{as_gt()} is deprecated; use \code{\link[=as_lt]{as_lt()}} instead. It now calls \code{\link[=as_lt]{as_lt()}}. } +\seealso{ +\code{\link[=as_lt]{as_lt()}} } diff --git a/man/as_lt.Rd b/man/as_lt.Rd new file mode 100644 index 000000000..8ee52e666 --- /dev/null +++ b/man/as_lt.Rd @@ -0,0 +1,192 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/as_lt.R +\name{as_lt} +\alias{as_lt} +\alias{as_lt.fixed_design_summary} +\alias{as_lt.gs_design_summary} +\title{Convert summary table of a fixed or group sequential design object to an lt table} +\usage{ +as_lt(x, ...) + +\method{as_lt}{fixed_design_summary}(x, title = NULL, footnote = NULL, ...) + +\method{as_lt}{gs_design_summary}( + x, + title = NULL, + subtitle = NULL, + colname_spanner = "Cumulative boundary crossing probability", + colname_spannersub = c("Alternate hypothesis", "Null hypothesis"), + footnote = NULL, + display_bound = c("Efficacy", "Futility"), + display_columns = NULL, + display_inf_bound = FALSE, + ... +) +} +\arguments{ +\item{x}{A summary object of a fixed or group sequential design.} + +\item{...}{Additional arguments (not used).} + +\item{title}{A string to specify the title of the table.} + +\item{footnote}{A list containing \code{content}, \code{location}, and \code{attr}. +\code{content} is a vector of string to specify the footnote text; \code{location} is +a vector of string to specify the locations to put the superscript of the +footnote index; \code{attr} is a vector of string to specify the attributes of +the footnotes, for example, \code{c("colname", "title", "subtitle", "analysis", "spanner")}. To disable footnotes, use \code{footnote = FALSE}.} + +\item{subtitle}{A string to specify the subtitle of the table.} + +\item{colname_spanner}{A string to specify the spanner of the table.} + +\item{colname_spannersub}{A vector of strings to specify the spanner details +of the table.} + +\item{display_bound}{A vector of strings specifying the label of the bounds. +The default is \code{c("Efficacy", "Futility")}.} + +\item{display_columns}{A vector of strings specifying the variables to be +displayed in the summary table.} + +\item{display_inf_bound}{Logical, whether to display the +/-inf bound.} +} +\value{ +An \code{lt_tbl} object. +} +\description{ +Convert summary table of a fixed or group sequential design object to an lt table +} +\examples{ +# Fixed design examples ---- + +# Enrollment rate +enroll_rate <- define_enroll_rate( + duration = 18, + rate = 20 +) + +# Failure rates +fail_rate <- define_fail_rate( + duration = c(4, 100), + fail_rate = log(2) / 12, + dropout_rate = .001, + hr = c(1, .6) +) + +# Study duration in months +study_duration <- 36 + +# Experimental / Control randomization ratio +ratio <- 1 + +# 1-sided Type I error +alpha <- 0.025 + +# Type II error (1 - power) +beta <- 0.1 + +# Example 1 ---- +fixed_design_ahr( + alpha = alpha, power = 1 - beta, + enroll_rate = enroll_rate, fail_rate = fail_rate, + study_duration = study_duration, ratio = ratio +) |> + summary() |> + as_lt() + +# Example 2 ---- +fixed_design_fh( + alpha = alpha, power = 1 - beta, + enroll_rate = enroll_rate, fail_rate = fail_rate, + study_duration = study_duration, ratio = ratio +) |> + summary() |> + as_lt() +\donttest{ +# Group sequential design examples --- + +# Example 1 ---- +# The default output + +gs_design_ahr() |> + summary() |> + as_lt() + +gs_power_ahr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) |> + summary() |> + as_lt() + +gs_design_wlr() |> + summary() |> + as_lt() + +gs_power_wlr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) |> + summary() |> + as_lt() + +gs_power_combo() |> + summary() |> + as_lt() + +gs_design_rd() |> + summary() |> + as_lt() + +gs_power_rd() |> + summary() |> + as_lt() + +# Example 2 ---- +# Usage of title = ..., subtitle = ... +# to edit the title/subtitle +gs_power_wlr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) |> + summary() |> + as_lt( + title = "Bound Summary", + subtitle = "from gs_power_wlr" + ) + +# Example 3 ---- +# Usage of colname_spanner = ..., colname_spannersub = ... +# to edit the spanner and its sub-spanner +gs_power_wlr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) |> + summary() |> + as_lt( + colname_spanner = "Cumulative probability to cross boundaries", + colname_spannersub = c("under H1", "under H0") + ) + +# Example 4 ---- +# Usage of footnote = ... +# to edit the footnote +gs_power_wlr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) |> + summary() |> + as_lt( + footnote = list( + content = c( + "approximate weighted hazard ratio to cross bound.", + "wAHR is the weighted AHR.", + "the crossing probability.", + "this table is generated by gs_power_wlr." + ), + location = c("~wHR at bound", NA, NA, NA), + attr = c("colname", "analysis", "spanner", "title") + ) + ) + +# Example 5 ---- +# Usage of display_bound = ... +# to either show efficacy bound or futility bound, or both(default) +gs_power_wlr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) |> + summary() |> + as_lt(display_bound = "Efficacy") + +# Example 6 ---- +# Usage of display_columns = ... +# to select the columns to display in the summary table +gs_power_wlr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) |> + summary() |> + as_lt(display_columns = c("Analysis", "Bound", "Nominal p", "Z", "Probability")) +} +} diff --git a/man/gsDesign2-package.Rd b/man/gsDesign2-package.Rd index c31fdc74c..e5a286eeb 100644 --- a/man/gsDesign2-package.Rd +++ b/man/gsDesign2-package.Rd @@ -24,6 +24,7 @@ Useful links: Authors: \itemize{ + \item Yujie Zhao \email{yujie.zhao@merck.com} \item Keaven Anderson \email{keaven_anderson@merck.com} \item Yilong Zhang \email{elong0527@gmail.com} \item John Blischak \email{jdblischak@gmail.com} diff --git a/tests/testit/helper.R b/tests/testit/helper.R index f1c33dd55..662884c23 100644 --- a/tests/testit/helper.R +++ b/tests/testit/helper.R @@ -1,5 +1,3 @@ -gt_to_latex <- function(data) cat(as.character(gt::as_latex(data))) - test_event <- function(enroll_rate, fail_rate, td = 15) { enroll_rate_1 <- enroll_rate enroll_rate_1$rate <- enroll_rate$rate / 2 diff --git a/tests/testit/test-developer-as_gt.R b/tests/testit/test-developer-as_gt.R deleted file mode 100644 index 1c3ef5773..000000000 --- a/tests/testit/test-developer-as_gt.R +++ /dev/null @@ -1,22 +0,0 @@ -assert("footnote=FALSE removes footnote", { - - # fixed design - x <- fixed_design_ahr( - enroll_rate = define_enroll_rate(duration = 18, rate = 1), - fail_rate = define_fail_rate(duration = 18, fail_rate = 0.1, dropout_rate = 0.001) - ) - y <- summary(x) - z1 <- as_gt(y) - (nrow(z1$`_footnotes`) %==% 1L) - z2 <- as_gt(y, footnote = FALSE) - (nrow(z2$`_footnotes`) %==% 0L) - - # gs design - x <- gs_design_ahr() - y <- summary(x) - z1 <- as_gt(y) - (nrow(z1$`_footnotes`) %==% 2L) - z2 <- as_gt(y, footnote = FALSE) - (nrow(z2$`_footnotes`) %==% 0L) - -}) diff --git a/tests/testit/test-developer-as_lt.R b/tests/testit/test-developer-as_lt.R new file mode 100644 index 000000000..718283a9e --- /dev/null +++ b/tests/testit/test-developer-as_lt.R @@ -0,0 +1,26 @@ +count_footnotes <- function(x) { + length(x$footnotes) +} + +assert("as_lt: footnote=FALSE removes footnote", { + + # fixed design + x <- fixed_design_ahr( + enroll_rate = define_enroll_rate(duration = 18, rate = 1), + fail_rate = define_fail_rate(duration = 18, fail_rate = 0.1, dropout_rate = 0.001) + ) + y <- summary(x) + z1 <- as_lt(y) + (count_footnotes(z1) %==% 1L) + z2 <- as_lt(y, footnote = FALSE) + (count_footnotes(z2) %==% 0L) + + # gs design + x <- gs_design_ahr() + y <- summary(x) + z1 <- as_lt(y) + (count_footnotes(z1) %==% 2L) + z2 <- as_lt(y, footnote = FALSE) + (count_footnotes(z2) %==% 0L) + +}) diff --git a/tests/testit/test-independent-gs_update_ahr.R b/tests/testit/test-independent-gs_update_ahr.R index a060958f5..c1d7b4cbd 100644 --- a/tests/testit/test-independent-gs_update_ahr.R +++ b/tests/testit/test-independent-gs_update_ahr.R @@ -1,5 +1,4 @@ library(gsDesign2) -library(gt) library(dplyr) library(simtrial) library(testit) diff --git a/tests/testit/test-independent_as_gt.md b/tests/testit/test-independent_as_gt.md deleted file mode 100644 index c47fb1e89..000000000 --- a/tests/testit/test-independent_as_gt.md +++ /dev/null @@ -1,693 +0,0 @@ -## `fixed_design()` summary `as_gt()` - -```r -enroll_rate <- define_enroll_rate(duration = 18, rate = 20) - fail_rate <- define_fail_rate( - duration = c(4, 100), - fail_rate = log(2) / 12, - dropout_rate = .001, hr = c(1, .6) - ) - - output <- fixed_design_ahr( - alpha = 0.025, - power = 1 - 0.1, - enroll_rate = enroll_rate, - fail_rate = fail_rate, - study_duration = 36, - ratio = 1 - ) |> - summary() |> - as_gt() -gt_to_latex(output) -``` - -``` -\begin{table}[t] -\caption*{ -{\fontsize{20}{25}\selectfont Fixed Design under AHR Method\textsuperscript{\textit{1}}\fontsize{12}{15}\selectfont } -} -\fontsize{12.0pt}{14.0pt}\selectfont -\begin{tabular*}{\linewidth}{@{\extracolsep{\fill}}lrrrrrrr} -\toprule -Design & N & Events & Time & AHR & Bound & alpha & Power \\ -\midrule\addlinespace[2.5pt] -Average hazard ratio & 463.078 & 324.7077 & 36 & 0.697102 & 1.959964 & 0.025 & 0.9 \\ -\bottomrule -\end{tabular*} -\begin{minipage}{\linewidth} -\vspace{.05em} -\textsuperscript{\textit{1}}Power computed with average hazard ratio method.\\ -\end{minipage} -\end{table} -``` - -## `fixed_design()` summary `as_gt()` with custom title and footnote - -```r -enroll_rate <- define_enroll_rate(duration = 18, rate = 20) - fail_rate <- define_fail_rate( - duration = c(4, 100), - fail_rate = log(2) / 12, - dropout_rate = .001, hr = c(1, .6) - ) - - output <- fixed_design_ahr( - alpha = 0.025, - power = 1 - 0.1, - enroll_rate = enroll_rate, - fail_rate = fail_rate, - study_duration = 36, - ratio = 1 - ) |> - summary() |> - as_gt(title = "Custom Title", footnote = "Custom footnote.") -gt_to_latex(output) -``` - -``` -\begin{table}[t] -\caption*{ -{\fontsize{20}{25}\selectfont Custom Title\textsuperscript{\textit{1}}\fontsize{12}{15}\selectfont } -} -\fontsize{12.0pt}{14.0pt}\selectfont -\begin{tabular*}{\linewidth}{@{\extracolsep{\fill}}lrrrrrrr} -\toprule -Design & N & Events & Time & AHR & Bound & alpha & Power \\ -\midrule\addlinespace[2.5pt] -Average hazard ratio & 463.078 & 324.7077 & 36 & 0.697102 & 1.959964 & 0.025 & 0.9 \\ -\bottomrule -\end{tabular*} -\begin{minipage}{\linewidth} -\vspace{.05em} -\textsuperscript{\textit{1}}Custom footnote.\\ -\end{minipage} -\end{table} -``` - -## `fixed_design_fh()` summary `as_gt()` - -```r -enroll_rate <- define_enroll_rate( - duration = 18, - rate = 20 - ) - fail_rate <- define_fail_rate( - duration = c(4, 100), - fail_rate = log(2) / 12, - dropout_rate = .001, - hr = c(1, .6) - ) - - output <- fixed_design_fh( - alpha = 0.025, - power = 1 - 0.1, - enroll_rate = enroll_rate, - fail_rate = fail_rate, - study_duration = 36, - ratio = 1 - ) |> - summary() |> - as_gt() -gt_to_latex(output) -``` - -``` -\begin{table}[t] -\caption*{ -{\fontsize{20}{25}\selectfont Fixed Design under Fleming-Harrington Method\textsuperscript{\textit{1}}\fontsize{12}{15}\selectfont } -} -\fontsize{12.0pt}{14.0pt}\selectfont -\begin{tabular*}{\linewidth}{@{\extracolsep{\fill}}lrrrrrrr} -\toprule -Design & N & Events & Time & AHR & Bound & alpha & Power \\ -\midrule\addlinespace[2.5pt] -Fleming-Harrington FH(0, 0) (logrank) & 458.3509 & 321.3931 & 36 & 0.6969049 & 1.959964 & 0.025 & 0.9 \\ -\bottomrule -\end{tabular*} -\begin{minipage}{\linewidth} -\vspace{.05em} -\textsuperscript{\textit{1}}Power for Fleming-Harrington test FH(0, 0) (logrank) using method of Yung and Liu.\\ -\end{minipage} -\end{table} -``` - -## `gs_design_ahr()` summary `as_gt()` - -```r -output <- gs_design_ahr() |> - summary() |> - as_gt() -gt_to_latex(output) -``` - -``` -\begin{table}[t] -\caption*{ -{\fontsize{20}{25}\selectfont Bound summary for AHR design\fontsize{12}{15}\selectfont } \\ -{\fontsize{14}{17}\selectfont AHR approximations of \textasciitilde{}HR at bound\fontsize{12}{15}\selectfont } -} -\fontsize{12.0pt}{14.0pt}\selectfont -\begin{tabular*}{\linewidth}{@{\extracolsep{\fill}}lrrrrr} -\toprule - & & & & \multicolumn{2}{c}{{Cumulative boundary crossing probability}} \\ -\cmidrule(lr){5-6} -Bound & Z & Nominal p\textsuperscript{\textit{1}} & \textasciitilde{}HR at bound\textsuperscript{\textit{2}} & Alternate hypothesis & Null hypothesis \\ -\midrule\addlinespace[2.5pt] -\multicolumn{6}{l}{Analysis: 1 Time: 36 N: 476 Events: 291.9 AHR: 0.68 Information fraction: 1} \\[2.5pt] -\midrule\addlinespace[2.5pt] -Efficacy & 1.96 & 0.025 & 0.795 & 0.9 & 0.025 \\ -\bottomrule -\end{tabular*} -\begin{minipage}{\linewidth} -\vspace{.05em} -\textsuperscript{\textit{1}}One-sided p-value for experimental vs control treatment. Value < 0.5 favors experimental, > 0.5 favors control.\\ -\textsuperscript{\textit{2}}Approximate hazard ratio to cross bound.\\ -\end{minipage} -\end{table} -``` - -## `gs_power_ahr()` summary `as_gt()` - -```r -output <- gs_power_ahr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) |> - summary() |> - as_gt() -gt_to_latex(output) -``` - -``` -\begin{table}[t] -\caption*{ -{\fontsize{20}{25}\selectfont Bound summary for AHR design\fontsize{12}{15}\selectfont } \\ -{\fontsize{14}{17}\selectfont AHR approximations of \textasciitilde{}HR at bound\fontsize{12}{15}\selectfont } -} -\fontsize{12.0pt}{14.0pt}\selectfont -\begin{tabular*}{\linewidth}{@{\extracolsep{\fill}}lrrrrr} -\toprule - & & & & \multicolumn{2}{c}{{Cumulative boundary crossing probability}} \\ -\cmidrule(lr){5-6} -Bound & Z & Nominal p\textsuperscript{\textit{1}} & \textasciitilde{}HR at bound\textsuperscript{\textit{2}} & Alternate hypothesis & Null hypothesis \\ -\midrule\addlinespace[2.5pt] -\multicolumn{6}{l}{Analysis: 1 Time: 14.9 N: 108 Events: 30 AHR: 0.79 Information fraction: 0.6} \\[2.5pt] -\midrule\addlinespace[2.5pt] -Futility & -1.17 & 0.8792 & 1.5336 & 0.0349 & 0.1208 \\ -Efficacy & 2.67 & 0.0038 & 0.3774 & 0.0231 & 0.0038 \\ -\midrule\addlinespace[2.5pt] -\multicolumn{6}{l}{Analysis: 2 Time: 19.2 N: 108 Events: 40 AHR: 0.74 Information fraction: 0.8} \\[2.5pt] -\midrule\addlinespace[2.5pt] -Futility & -0.66 & 0.7462 & 1.2331 & 0.0668 & 0.2655 \\ -Efficacy & 2.29 & 0.0110 & 0.4849 & 0.0897 & 0.0122 \\ -\midrule\addlinespace[2.5pt] -\multicolumn{6}{l}{Analysis: 3 Time: 24.5 N: 108 Events: 50 AHR: 0.71 Information fraction: 1} \\[2.5pt] -\midrule\addlinespace[2.5pt] -Futility & -0.23 & 0.5897 & 1.0662 & 0.1008 & 0.4303 \\ -Efficacy & 2.03 & 0.0211 & 0.5631 & 0.2070 & 0.0250 \\ -\bottomrule -\end{tabular*} -\begin{minipage}{\linewidth} -\vspace{.05em} -\textsuperscript{\textit{1}}One-sided p-value for experimental vs control treatment. Value < 0.5 favors experimental, > 0.5 favors control.\\ -\textsuperscript{\textit{2}}Approximate hazard ratio to cross bound.\\ -\end{minipage} -\end{table} -``` - -## `gs_design_wlr()` summary `as_gt()` - -```r -output <- gs_design_wlr() |> - summary() |> - as_gt() -gt_to_latex(output) -``` - -``` -\begin{table}[t] -\caption*{ -{\fontsize{20}{25}\selectfont Bound summary for WLR design\fontsize{12}{15}\selectfont } \\ -{\fontsize{14}{17}\selectfont WLR approximation of \textasciitilde{}wHR at bound\fontsize{12}{15}\selectfont } -} -\fontsize{12.0pt}{14.0pt}\selectfont -\begin{tabular*}{\linewidth}{@{\extracolsep{\fill}}lrrrrr} -\toprule - & & & & \multicolumn{2}{c}{{Cumulative boundary crossing probability}} \\ -\cmidrule(lr){5-6} -Bound & Z & Nominal p\textsuperscript{\textit{1}} & \textasciitilde{}wHR at bound\textsuperscript{\textit{2}} & Alternate hypothesis & Null hypothesis \\ -\midrule\addlinespace[2.5pt] -\multicolumn{6}{l}{Analysis: 1 Time: 36 N: 471.1 Events: 289 AHR: 0.68 Information fraction: 1\textsuperscript{\textit{3}}} \\[2.5pt] -\midrule\addlinespace[2.5pt] -Efficacy & 1.96 & 0.025 & 0.7941 & 0.9 & 0.025 \\ -\bottomrule -\end{tabular*} -\begin{minipage}{\linewidth} -\vspace{.05em} -\textsuperscript{\textit{1}}One-sided p-value for experimental vs control treatment. Value < 0.5 favors experimental, > 0.5 favors control.\\ -\textsuperscript{\textit{2}}Approximate hazard ratio to cross bound.\\ -\textsuperscript{\textit{3}}wAHR is the weighted AHR.\\ -\end{minipage} -\end{table} -``` - -## `gs_power_wlr()` summary `as_gt()` - -```r -output <- gs_power_wlr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) |> - summary() |> - as_gt( - footnote = list( - content = c( - "approximate weighted hazard ratio to cross bound.", - "wAHR is the weighted AHR.", - "the crossing probability.", - "this table is generated by gs_power_wlr." - ), - location = c("~wHR at bound", NA, NA, NA), - attr = c("colname", "analysis", "spanner", "title") - ) - ) -gt_to_latex(output) -``` - -``` -\begin{table}[t] -\caption*{ -{\fontsize{20}{25}\selectfont Bound summary for WLR design\textsuperscript{\textit{1}}\fontsize{12}{15}\selectfont } \\ -{\fontsize{14}{17}\selectfont WLR approximation of \textasciitilde{}wHR at bound\fontsize{12}{15}\selectfont } -} -\fontsize{12.0pt}{14.0pt}\selectfont -\begin{tabular*}{\linewidth}{@{\extracolsep{\fill}}lrrrrr} -\toprule - & & & & \multicolumn{2}{c}{{Cumulative boundary crossing probability}}\textsuperscript{\textit{2}} \\ -\cmidrule(lr){5-6} -Bound & Z & Nominal p & \textasciitilde{}wHR at bound\textsuperscript{\textit{3}} & Alternate hypothesis & Null hypothesis \\ -\midrule\addlinespace[2.5pt] -\multicolumn{6}{l}{Analysis: 1 Time: 14.9 N: 108 Events: 30 AHR: 0.79 Information fraction: 0.6\textsuperscript{\textit{4}}} \\[2.5pt] -\midrule\addlinespace[2.5pt] -Futility & -1.17 & 0.8798 & 1.5353 & 0.0341 & 0.1202 \\ -Efficacy & 2.68 & 0.0037 & 0.3765 & 0.0217 & 0.0037 \\ -\midrule\addlinespace[2.5pt] -\multicolumn{6}{l}{Analysis: 2 Time: 19.2 N: 108 Events: 40 AHR: 0.75 Information fraction: 0.8\textsuperscript{\textit{4}}} \\[2.5pt] -\midrule\addlinespace[2.5pt] -Futility & -0.66 & 0.7452 & 1.2319 & 0.0664 & 0.2664 \\ -Efficacy & 2.29 & 0.0110 & 0.4846 & 0.0886 & 0.0121 \\ -\midrule\addlinespace[2.5pt] -\multicolumn{6}{l}{Analysis: 3 Time: 24.5 N: 108 Events: 50 AHR: 0.71 Information fraction: 1\textsuperscript{\textit{4}}} \\[2.5pt] -\midrule\addlinespace[2.5pt] -Futility & -0.22 & 0.5881 & 1.0650 & 0.1002 & 0.4319 \\ -Efficacy & 2.03 & 0.0212 & 0.5631 & 0.2071 & 0.0250 \\ -\bottomrule -\end{tabular*} -\begin{minipage}{\linewidth} -\vspace{.05em} -\textsuperscript{\textit{1}}this table is generated by gs\_power\_wlr.\\ -\textsuperscript{\textit{2}}the crossing probability.\\ -\textsuperscript{\textit{3}}approximate weighted hazard ratio to cross bound.\\ -\textsuperscript{\textit{4}}wAHR is the weighted AHR.\\ -\end{minipage} -\end{table} -``` - -## `gs_power_combo()` summary `as_gt()` - -```r -with_seed <- function(seed, code) { - code <- substitute(code) - original_seed <- .Random.seed - on.exit(.Random.seed <<- original_seed) - set.seed(seed) - eval.parent(code) - } - - # See - output <- with_seed( - 42, - { - gs_power_combo() |> - summary() |> - as_gt() - } - ) -gt_to_latex(output) -``` - -``` -\begin{table}[t] -\caption*{ -{\fontsize{20}{25}\selectfont Bound summary for MaxCombo design\fontsize{12}{15}\selectfont } \\ -{\fontsize{14}{17}\selectfont MaxCombo approximation\fontsize{12}{15}\selectfont } -} -\fontsize{12.0pt}{14.0pt}\selectfont -\begin{tabular*}{\linewidth}{@{\extracolsep{\fill}}lrrrr} -\toprule - & & & \multicolumn{2}{c}{{Cumulative boundary crossing probability}} \\ -\cmidrule(lr){4-5} -Bound & Z & Nominal p\textsuperscript{\textit{1}} & Alternate hypothesis & Null hypothesis \\ -\midrule\addlinespace[2.5pt] -\multicolumn{5}{l}{Analysis: 1 Time: 12 N: 500 Events: 107.4 AHR: 0.84 Event fraction: 0.32\textsuperscript{\textit{2}}} \\[2.5pt] -\midrule\addlinespace[2.5pt] -Futility & -1 & 0.8413 & 0.0293 & 0.0000 \\ -Efficacy & 3 & 0.0013 & 0.0175 & 0.0013 \\ -\midrule\addlinespace[2.5pt] -\multicolumn{5}{l}{Analysis: 2 Time: 24 N: 500 Events: 246.3 AHR: 0.72 Event fraction: 0.74\textsuperscript{\textit{2}}} \\[2.5pt] -\midrule\addlinespace[2.5pt] -Futility & 0 & 0.5000 & 0.0314 & 0.0000 \\ -Efficacy & 2 & 0.0228 & 0.7261 & 0.0233 \\ -\midrule\addlinespace[2.5pt] -\multicolumn{5}{l}{Analysis: 3 Time: 36 N: 500 Events: 331.3 AHR: 0.68 Event fraction: 1\textsuperscript{\textit{2}}} \\[2.5pt] -\midrule\addlinespace[2.5pt] -Futility & 1 & 0.1587 & 0.0326 & 0.0000 \\ -Efficacy & 1 & 0.1587 & 0.9674 & 0.1956 \\ -\bottomrule -\end{tabular*} -\begin{minipage}{\linewidth} -\vspace{.05em} -\textsuperscript{\textit{1}}One-sided p-value for experimental vs control treatment. Value < 0.5 favors experimental, > 0.5 favors control.\\ -\textsuperscript{\textit{2}}EF is event fraction. AHR is under regular weighted log rank test.\\ -\end{minipage} -\end{table} -``` - -## `gs_design_rd()` summary `as_gt()` - -```r -output <- gs_design_rd() |> - summary() |> - as_gt() -gt_to_latex(output) -``` - -``` -\begin{table}[t] -\caption*{ -{\fontsize{20}{25}\selectfont Bound summary of Binary Endpoint\fontsize{12}{15}\selectfont } \\ -{\fontsize{14}{17}\selectfont measured by risk difference\fontsize{12}{15}\selectfont } -} -\fontsize{12.0pt}{14.0pt}\selectfont -\begin{tabular*}{\linewidth}{@{\extracolsep{\fill}}lrrrrr} -\toprule - & & & & \multicolumn{2}{c}{{Cumulative boundary crossing probability}} \\ -\cmidrule(lr){5-6} -Bound & Z & Nominal p\textsuperscript{\textit{1}} & \textasciitilde{}Risk difference at bound & Alternate hypothesis & Null hypothesis \\ -\midrule\addlinespace[2.5pt] -\multicolumn{6}{l}{Analysis: 1 N: 2423.1 Risk difference: 0.05 Information fraction: 1} \\[2.5pt] -\midrule\addlinespace[2.5pt] -Efficacy & 1.96 & 0.025 & 0.0302 & 0.9 & 0.025 \\ -\bottomrule -\end{tabular*} -\begin{minipage}{\linewidth} -\vspace{.05em} -\textsuperscript{\textit{1}}One-sided p-value for experimental vs control treatment. Value < 0.5 favors experimental, > 0.5 favors control.\\ -\end{minipage} -\end{table} -``` - -## `gs_power_rd()` summary `as_gt()` - -```r -output <- gs_power_rd() |> - summary() |> - as_gt() -gt_to_latex(output) -``` - -``` -\begin{table}[t] -\caption*{ -{\fontsize{20}{25}\selectfont Bound summary of Binary Endpoint\fontsize{12}{15}\selectfont } \\ -{\fontsize{14}{17}\selectfont measured by risk difference\fontsize{12}{15}\selectfont } -} -\fontsize{12.0pt}{14.0pt}\selectfont -\begin{tabular*}{\linewidth}{@{\extracolsep{\fill}}lrrrrr} -\toprule - & & & & \multicolumn{2}{c}{{Cumulative boundary crossing probability}} \\ -\cmidrule(lr){5-6} -Bound & Z & Nominal p\textsuperscript{\textit{1}} & \textasciitilde{}Risk difference at bound & Alternate hypothesis & Null hypothesis \\ -\midrule\addlinespace[2.5pt] -\multicolumn{6}{l}{Analysis: 1 N: 40 Risk difference: 0.05 Information fraction: 0.67} \\[2.5pt] -\midrule\addlinespace[2.5pt] -Futility & -1.28 & 0.9000 & -0.1537 & 0.0444 & 0.1000 \\ -Efficacy & 3.71 & 0.0001 & 0.4448 & 0.0005 & 0.0001 \\ -\midrule\addlinespace[2.5pt] -\multicolumn{6}{l}{Analysis: 2 N: 50 Risk difference: 0.05 Information fraction: 0.83} \\[2.5pt] -\midrule\addlinespace[2.5pt] -Efficacy & 2.51 & 0.0060 & 0.2693 & 0.0204 & 0.0060 \\ -\midrule\addlinespace[2.5pt] -\multicolumn{6}{l}{Analysis: 3 N: 60 Risk difference: 0.05 Information fraction: 1} \\[2.5pt] -\midrule\addlinespace[2.5pt] -Efficacy & 1.99 & 0.0231 & 0.1951 & 0.0705 & \textsuperscript{\textit{2}}0.0238 \\ -\bottomrule -\end{tabular*} -\begin{minipage}{\linewidth} -\vspace{.05em} -\textsuperscript{\textit{1}}One-sided p-value for experimental vs control treatment. Value < 0.5 favors experimental, > 0.5 favors control.\\ -\textsuperscript{\textit{2}}Cumulative alpha for final analysis (0.0238) is less than the full alpha (0.025) when the futility bound is non-binding. The smaller value subtracts the probability of crossing a futility bound before crossing an efficacy bound at a later analysis (0.025 - 0.0012 = 0.0238) under the null hypothesis.\\ -\end{minipage} -\end{table} -``` - -## `gs_power_wlr()` summary `as_gt()` with custom title and subtitle - -```r -output <- gs_power_wlr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) |> - summary() |> - as_gt(title = "Bound Summary", subtitle = "from gs_power_wlr") -gt_to_latex(output) -``` - -``` -\begin{table}[t] -\caption*{ -{\fontsize{20}{25}\selectfont Bound Summary\fontsize{12}{15}\selectfont } \\ -{\fontsize{14}{17}\selectfont from gs\_power\_wlr\fontsize{12}{15}\selectfont } -} -\fontsize{12.0pt}{14.0pt}\selectfont -\begin{tabular*}{\linewidth}{@{\extracolsep{\fill}}lrrrrr} -\toprule - & & & & \multicolumn{2}{c}{{Cumulative boundary crossing probability}} \\ -\cmidrule(lr){5-6} -Bound & Z & Nominal p\textsuperscript{\textit{1}} & \textasciitilde{}wHR at bound\textsuperscript{\textit{2}} & Alternate hypothesis & Null hypothesis \\ -\midrule\addlinespace[2.5pt] -\multicolumn{6}{l}{Analysis: 1 Time: 14.9 N: 108 Events: 30 AHR: 0.79 Information fraction: 0.6\textsuperscript{\textit{3}}} \\[2.5pt] -\midrule\addlinespace[2.5pt] -Futility & -1.17 & 0.8798 & 1.5353 & 0.0341 & 0.1202 \\ -Efficacy & 2.68 & 0.0037 & 0.3765 & 0.0217 & 0.0037 \\ -\midrule\addlinespace[2.5pt] -\multicolumn{6}{l}{Analysis: 2 Time: 19.2 N: 108 Events: 40 AHR: 0.75 Information fraction: 0.8\textsuperscript{\textit{3}}} \\[2.5pt] -\midrule\addlinespace[2.5pt] -Futility & -0.66 & 0.7452 & 1.2319 & 0.0664 & 0.2664 \\ -Efficacy & 2.29 & 0.0110 & 0.4846 & 0.0886 & 0.0121 \\ -\midrule\addlinespace[2.5pt] -\multicolumn{6}{l}{Analysis: 3 Time: 24.5 N: 108 Events: 50 AHR: 0.71 Information fraction: 1\textsuperscript{\textit{3}}} \\[2.5pt] -\midrule\addlinespace[2.5pt] -Futility & -0.22 & 0.5881 & 1.0650 & 0.1002 & 0.4319 \\ -Efficacy & 2.03 & 0.0212 & 0.5631 & 0.2071 & 0.0250 \\ -\bottomrule -\end{tabular*} -\begin{minipage}{\linewidth} -\vspace{.05em} -\textsuperscript{\textit{1}}One-sided p-value for experimental vs control treatment. Value < 0.5 favors experimental, > 0.5 favors control.\\ -\textsuperscript{\textit{2}}Approximate hazard ratio to cross bound.\\ -\textsuperscript{\textit{3}}wAHR is the weighted AHR.\\ -\end{minipage} -\end{table} -``` - -## `gs_power_wlr()` summary `as_gt()` with colname_spanner and colname_spannersub - -```r -output <- gs_power_wlr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) |> - summary() |> - as_gt( - colname_spanner = "Cumulative probability to cross boundaries", - colname_spannersub = c("under H1", "under H0") - ) -gt_to_latex(output) -``` - -``` -\begin{table}[t] -\caption*{ -{\fontsize{20}{25}\selectfont Bound summary for WLR design\fontsize{12}{15}\selectfont } \\ -{\fontsize{14}{17}\selectfont WLR approximation of \textasciitilde{}wHR at bound\fontsize{12}{15}\selectfont } -} -\fontsize{12.0pt}{14.0pt}\selectfont -\begin{tabular*}{\linewidth}{@{\extracolsep{\fill}}lrrrrr} -\toprule - & & & & \multicolumn{2}{c}{{Cumulative probability to cross boundaries}} \\ -\cmidrule(lr){5-6} -Bound & Z & Nominal p\textsuperscript{\textit{1}} & \textasciitilde{}wHR at bound\textsuperscript{\textit{2}} & under H1 & under H0 \\ -\midrule\addlinespace[2.5pt] -\multicolumn{6}{l}{Analysis: 1 Time: 14.9 N: 108 Events: 30 AHR: 0.79 Information fraction: 0.6\textsuperscript{\textit{3}}} \\[2.5pt] -\midrule\addlinespace[2.5pt] -Futility & -1.17 & 0.8798 & 1.5353 & 0.0341 & 0.1202 \\ -Efficacy & 2.68 & 0.0037 & 0.3765 & 0.0217 & 0.0037 \\ -\midrule\addlinespace[2.5pt] -\multicolumn{6}{l}{Analysis: 2 Time: 19.2 N: 108 Events: 40 AHR: 0.75 Information fraction: 0.8\textsuperscript{\textit{3}}} \\[2.5pt] -\midrule\addlinespace[2.5pt] -Futility & -0.66 & 0.7452 & 1.2319 & 0.0664 & 0.2664 \\ -Efficacy & 2.29 & 0.0110 & 0.4846 & 0.0886 & 0.0121 \\ -\midrule\addlinespace[2.5pt] -\multicolumn{6}{l}{Analysis: 3 Time: 24.5 N: 108 Events: 50 AHR: 0.71 Information fraction: 1\textsuperscript{\textit{3}}} \\[2.5pt] -\midrule\addlinespace[2.5pt] -Futility & -0.22 & 0.5881 & 1.0650 & 0.1002 & 0.4319 \\ -Efficacy & 2.03 & 0.0212 & 0.5631 & 0.2071 & 0.0250 \\ -\bottomrule -\end{tabular*} -\begin{minipage}{\linewidth} -\vspace{.05em} -\textsuperscript{\textit{1}}One-sided p-value for experimental vs control treatment. Value < 0.5 favors experimental, > 0.5 favors control.\\ -\textsuperscript{\textit{2}}Approximate hazard ratio to cross bound.\\ -\textsuperscript{\textit{3}}wAHR is the weighted AHR.\\ -\end{minipage} -\end{table} -``` - -## `gs_power_wlr()` summary `as_gt()` with custom footnotes - -```r -output <- gs_power_wlr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) |> - summary() |> - as_gt( - footnote = list( - content = c( - "approximate weighted hazard ratio to cross bound.", - "wAHR is the weighted AHR.", - "the crossing probability.", - "this table is generated by gs_power_wlr." - ), - location = c("~wHR at bound", NA, NA, NA), - attr = c("colname", "analysis", "spanner", "title") - ) - ) -gt_to_latex(output) -``` - -``` -\begin{table}[t] -\caption*{ -{\fontsize{20}{25}\selectfont Bound summary for WLR design\textsuperscript{\textit{1}}\fontsize{12}{15}\selectfont } \\ -{\fontsize{14}{17}\selectfont WLR approximation of \textasciitilde{}wHR at bound\fontsize{12}{15}\selectfont } -} -\fontsize{12.0pt}{14.0pt}\selectfont -\begin{tabular*}{\linewidth}{@{\extracolsep{\fill}}lrrrrr} -\toprule - & & & & \multicolumn{2}{c}{{Cumulative boundary crossing probability}}\textsuperscript{\textit{2}} \\ -\cmidrule(lr){5-6} -Bound & Z & Nominal p & \textasciitilde{}wHR at bound\textsuperscript{\textit{3}} & Alternate hypothesis & Null hypothesis \\ -\midrule\addlinespace[2.5pt] -\multicolumn{6}{l}{Analysis: 1 Time: 14.9 N: 108 Events: 30 AHR: 0.79 Information fraction: 0.6\textsuperscript{\textit{4}}} \\[2.5pt] -\midrule\addlinespace[2.5pt] -Futility & -1.17 & 0.8798 & 1.5353 & 0.0341 & 0.1202 \\ -Efficacy & 2.68 & 0.0037 & 0.3765 & 0.0217 & 0.0037 \\ -\midrule\addlinespace[2.5pt] -\multicolumn{6}{l}{Analysis: 2 Time: 19.2 N: 108 Events: 40 AHR: 0.75 Information fraction: 0.8\textsuperscript{\textit{4}}} \\[2.5pt] -\midrule\addlinespace[2.5pt] -Futility & -0.66 & 0.7452 & 1.2319 & 0.0664 & 0.2664 \\ -Efficacy & 2.29 & 0.0110 & 0.4846 & 0.0886 & 0.0121 \\ -\midrule\addlinespace[2.5pt] -\multicolumn{6}{l}{Analysis: 3 Time: 24.5 N: 108 Events: 50 AHR: 0.71 Information fraction: 1\textsuperscript{\textit{4}}} \\[2.5pt] -\midrule\addlinespace[2.5pt] -Futility & -0.22 & 0.5881 & 1.0650 & 0.1002 & 0.4319 \\ -Efficacy & 2.03 & 0.0212 & 0.5631 & 0.2071 & 0.0250 \\ -\bottomrule -\end{tabular*} -\begin{minipage}{\linewidth} -\vspace{.05em} -\textsuperscript{\textit{1}}this table is generated by gs\_power\_wlr.\\ -\textsuperscript{\textit{2}}the crossing probability.\\ -\textsuperscript{\textit{3}}approximate weighted hazard ratio to cross bound.\\ -\textsuperscript{\textit{4}}wAHR is the weighted AHR.\\ -\end{minipage} -\end{table} -``` - -## `gs_power_wlr()` summary `as_gt()` with display_bound - -```r -output <- gs_power_wlr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) |> - summary() |> - as_gt(display_bound = "Efficacy") -gt_to_latex(output) -``` - -``` -\begin{table}[t] -\caption*{ -{\fontsize{20}{25}\selectfont Bound summary for WLR design\fontsize{12}{15}\selectfont } \\ -{\fontsize{14}{17}\selectfont WLR approximation of \textasciitilde{}wHR at bound\fontsize{12}{15}\selectfont } -} -\fontsize{12.0pt}{14.0pt}\selectfont -\begin{tabular*}{\linewidth}{@{\extracolsep{\fill}}lrrrrr} -\toprule - & & & & \multicolumn{2}{c}{{Cumulative boundary crossing probability}} \\ -\cmidrule(lr){5-6} -Bound & Z & Nominal p\textsuperscript{\textit{1}} & \textasciitilde{}wHR at bound\textsuperscript{\textit{2}} & Alternate hypothesis & Null hypothesis \\ -\midrule\addlinespace[2.5pt] -\multicolumn{6}{l}{Analysis: 1 Time: 14.9 N: 108 Events: 30 AHR: 0.79 Information fraction: 0.6\textsuperscript{\textit{3}}} \\[2.5pt] -\midrule\addlinespace[2.5pt] -Efficacy & 2.68 & 0.0037 & 0.3765 & 0.0217 & 0.0037 \\ -\midrule\addlinespace[2.5pt] -\multicolumn{6}{l}{Analysis: 2 Time: 19.2 N: 108 Events: 40 AHR: 0.75 Information fraction: 0.8\textsuperscript{\textit{3}}} \\[2.5pt] -\midrule\addlinespace[2.5pt] -Efficacy & 2.29 & 0.0110 & 0.4846 & 0.0886 & 0.0121 \\ -\midrule\addlinespace[2.5pt] -\multicolumn{6}{l}{Analysis: 3 Time: 24.5 N: 108 Events: 50 AHR: 0.71 Information fraction: 1\textsuperscript{\textit{3}}} \\[2.5pt] -\midrule\addlinespace[2.5pt] -Efficacy & 2.03 & 0.0212 & 0.5631 & 0.2071 & 0.0250 \\ -\bottomrule -\end{tabular*} -\begin{minipage}{\linewidth} -\vspace{.05em} -\textsuperscript{\textit{1}}One-sided p-value for experimental vs control treatment. Value < 0.5 favors experimental, > 0.5 favors control.\\ -\textsuperscript{\textit{2}}Approximate hazard ratio to cross bound.\\ -\textsuperscript{\textit{3}}wAHR is the weighted AHR.\\ -\end{minipage} -\end{table} -``` - -## `gs_power_wlr()` summary `as_gt()` with display_columns - -```r -output <- gs_power_wlr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) |> - summary() |> - as_gt(display_columns = c("Analysis", "Bound", "Nominal p", "Z", "Probability")) -gt_to_latex(output) -``` - -``` -\begin{table}[t] -\caption*{ -{\fontsize{20}{25}\selectfont Bound summary for WLR design\fontsize{12}{15}\selectfont } \\ -{\fontsize{14}{17}\selectfont WLR approximation of \textasciitilde{}wHR at bound\fontsize{12}{15}\selectfont } -} -\fontsize{12.0pt}{14.0pt}\selectfont -\begin{tabular*}{\linewidth}{@{\extracolsep{\fill}}lrrrr} -\toprule - & & & \multicolumn{2}{c}{{Cumulative boundary crossing probability}} \\ -\cmidrule(lr){4-5} -Bound & Nominal p\textsuperscript{\textit{1}} & Z & Alternate hypothesis & Null hypothesis \\ -\midrule\addlinespace[2.5pt] -\multicolumn{5}{l}{Analysis: 1 Time: 14.9 N: 108 Events: 30 AHR: 0.79 Information fraction: 0.6\textsuperscript{\textit{2}}} \\[2.5pt] -\midrule\addlinespace[2.5pt] -Futility & 0.8798 & -1.17 & 0.0341 & 0.1202 \\ -Efficacy & 0.0037 & 2.68 & 0.0217 & 0.0037 \\ -\midrule\addlinespace[2.5pt] -\multicolumn{5}{l}{Analysis: 2 Time: 19.2 N: 108 Events: 40 AHR: 0.75 Information fraction: 0.8\textsuperscript{\textit{2}}} \\[2.5pt] -\midrule\addlinespace[2.5pt] -Futility & 0.7452 & -0.66 & 0.0664 & 0.2664 \\ -Efficacy & 0.0110 & 2.29 & 0.0886 & 0.0121 \\ -\midrule\addlinespace[2.5pt] -\multicolumn{5}{l}{Analysis: 3 Time: 24.5 N: 108 Events: 50 AHR: 0.71 Information fraction: 1\textsuperscript{\textit{2}}} \\[2.5pt] -\midrule\addlinespace[2.5pt] -Futility & 0.5881 & -0.22 & 0.1002 & 0.4319 \\ -Efficacy & 0.0212 & 2.03 & 0.2071 & 0.0250 \\ -\bottomrule -\end{tabular*} -\begin{minipage}{\linewidth} -\vspace{.05em} -\textsuperscript{\textit{1}}One-sided p-value for experimental vs control treatment. Value < 0.5 favors experimental, > 0.5 favors control.\\ -\textsuperscript{\textit{2}}wAHR is the weighted AHR.\\ -\end{minipage} -\end{table} -``` - diff --git a/vignettes/articles/story-ahr-under-nph.Rmd b/vignettes/articles/story-ahr-under-nph.Rmd index d20a90f63..fc86c2fc0 100644 --- a/vignettes/articles/story-ahr-under-nph.Rmd +++ b/vignettes/articles/story-ahr-under-nph.Rmd @@ -99,7 +99,7 @@ library(ggplot2) library(dplyr) library(tibble) library(survival) -library(gt) +library(lt) ``` # Single stratum non-proportional hazards example @@ -147,7 +147,7 @@ avehr <- ahr( total_duration = as.numeric(total_duration) ) -avehr |> gt() +avehr |> lt() ``` This result can be explained by the number of events observed before and after the first 3 months of treatment in each treatment group. @@ -158,7 +158,7 @@ xx <- pw_info( fail_rate = fail_rate, total_duration = as.numeric(total_duration) ) -xx |> gt() +xx |> lt() ``` Now we can replicate the geometric average hazard ratio (AHR) computed using the `ahr()` routine above. @@ -168,7 +168,7 @@ Exponentiating the resulting weighted average gives the geometric mean hazard ra ```{r, message=FALSE} xx |> summarize(AHR = exp(sum(event * log(hr) / sum(event)))) |> - gt() + lt() ``` ## Deriving the design @@ -199,7 +199,7 @@ avehr <- ahr( total_duration = as.numeric(total_duration) ) -avehr |> gt() +avehr |> lt() ``` We also compute sample size, rounding up to the nearest even integer. @@ -268,8 +268,8 @@ results1 |> sdEvents = sd(event), Events = mean(event), HR = exp(mean(ln_hr)), sdlnhr = sd(ln_hr), info = 1 / sdlnhr^2 ) |> - gt() |> - fmt_number(column = 2:9, decimals = 3) + lt() |> + lt_format(columns = 2:9, decimals = 3) ``` The column `HR` above is the exponentiated mean of the Cox regression coefficients (geometric mean of HR). @@ -279,7 +279,7 @@ In this case, the information approximation under the alternate hypothesis appea Nonetheless, the approximation for power appear quite good as noted above. ```{r} -avehr |> gt() +avehr |> lt() ``` # Different proportional hazards by strata @@ -320,14 +320,14 @@ Now we transform the enrollment rates to account for stratified population. ```{r avehr2, warning=FALSE, message=FALSE} ahr2 <- ahr(enroll_rate, fail_rate, total_duration) -ahr2 |> gt() +ahr2 |> lt() ``` We examine the expected events by stratum. ```{r} xx <- pw_info(enroll_rate, fail_rate, total_duration) -xx |> gt() +xx |> lt() ``` Getting the average of `log(HR)` weighted by `Events` and exponentiating, we get the overall `AHR` just derived. @@ -336,7 +336,7 @@ Getting the average of `log(HR)` weighted by `Events` and exponentiating, we get xx |> ungroup() |> summarise(lnhr = sum(event * log(hr)) / sum(event), AHR = exp(lnhr)) |> - gt() + lt() ``` ## Deriving the design @@ -364,7 +364,7 @@ ahr( enroll_rate = enroll_rate, fail_rate = fail_rate, total_duration = total_duration -) |> gt() +) |> lt() ``` The targeted sample size, rounding up to an even integer, is: @@ -410,7 +410,7 @@ er <- enroll_rate |> group_by(period) |> summarise(rate = sum(rate), duration = last(duration)) -er |> gt() +er |> lt() ``` @@ -440,8 +440,8 @@ results2 |> sdEvents = sd(event), Events = mean(event), HR = exp(mean(ln_hr)), sdlnhr = sd(ln_hr), info = 1 / sdlnhr^2 ) |> - gt() |> - fmt_number(column = 2:9, decimals = 3) + lt() |> + lt_format(columns = 2:9, decimals = 3) ``` Finally, compare the simulation results above to the asymptotic approximation below. @@ -453,7 +453,7 @@ ahr( enroll_rate = enroll_rate, fail_rate = fail_rate, total_duration = total_duration -) |> gt() +) |> lt() ``` # References diff --git a/vignettes/articles/story-compare-power-delay-effect.Rmd b/vignettes/articles/story-compare-power-delay-effect.Rmd index cc2fce4f4..bfd2440b2 100644 --- a/vignettes/articles/story-compare-power-delay-effect.Rmd +++ b/vignettes/articles/story-compare-power-delay-effect.Rmd @@ -20,7 +20,7 @@ knitr::opts_chunk$set(echo = TRUE) ``` ```{r packages, message=FALSE, warning=FALSE} -library(gt) +library(lt) library(tidyr) library(ggplot2) library(gsDesign) @@ -47,12 +47,12 @@ fail_rate <- define_fail_rate( ) enroll_rate |> - gt() |> - tab_header(title = "Enrollment Table of Scenario 1") + lt() |> + lt_header(title = "Enrollment Table of Scenario 1") fail_rate |> - gt() |> - tab_header(title = "Failure Table of Scenario 1") + lt() |> + lt_header(title = "Failure Table of Scenario 1") ``` For the above scenarios, we investigate the power, sample size and events under 6 tests: @@ -180,11 +180,11 @@ for (trial_duration in seq(24, 60, 4)) { } tab |> - gt() |> - fmt_number(columns = c(2, 3), decimals = 1) |> - fmt_number(columns = 4, decimals = 2) |> - fmt_number(columns = 5, decimals = 4) |> - fmt_number(columns = 6:11, decimals = 2) + lt() |> + lt_format(columns = c(2, 3), decimals = 1) |> + lt_format(columns = 4, decimals = 2) |> + lt_format(columns = 5, decimals = 4) |> + lt_format(columns = 6:11, decimals = 2) ``` # An Alternative Scenario @@ -202,11 +202,11 @@ fail_rate <- define_fail_rate( hr = c(1, .6, .85) ) enroll_rate |> - gt() |> - tab_header(title = "Enrollment Table of Scenario 2") + lt() |> + lt_header(title = "Enrollment Table of Scenario 2") fail_rate |> - gt() |> - tab_header(title = "Failure Table of Scenario 2") + lt() |> + lt_header(title = "Failure Table of Scenario 2") ``` ```{r, message=FALSE} @@ -320,9 +320,9 @@ for (trial_duration in seq(20, 60, 4)) { } tab |> - gt() |> - fmt_number(columns = c(2, 3), decimals = 1) |> - fmt_number(columns = 4, decimals = 2) |> - fmt_number(columns = 5, decimals = 4) |> - fmt_number(columns = 6:11, decimals = 2) + lt() |> + lt_format(columns = c(2, 3), decimals = 1) |> + lt_format(columns = 4, decimals = 2) |> + lt_format(columns = 5, decimals = 4) |> + lt_format(columns = 6:11, decimals = 2) ``` diff --git a/vignettes/articles/story-cp.Rmd b/vignettes/articles/story-cp.Rmd index 2d379a0b0..f787c7e19 100644 --- a/vignettes/articles/story-cp.Rmd +++ b/vignettes/articles/story-cp.Rmd @@ -28,7 +28,7 @@ options(width = 58) ```{r, message=FALSE, warning=FALSE} library(gsDesign) library(gsDesign2) -library(gt) +library(lt) library(ggplot2) library(tibble) ``` @@ -73,7 +73,7 @@ x <- gs_design_ahr( # Round analysis time to nearest month x$analysis$time <- round(x$analysis$time) -x |> gs_bound_summary() |> gt() +x |> gs_bound_summary() |> lt() ``` # Update design at time of interim analysis @@ -103,7 +103,7 @@ xu <- gs_update_ahr( event_tbl = data.frame(analysis = c(1, 1), event = c(90, 55))) xu$analysis$time <- c(17, x$analysis$time[2:3]) -xu |> gs_bound_summary() |> gt() +xu |> gs_bound_summary() |> lt() ``` diff --git a/vignettes/articles/story-design-with-ahr.Rmd b/vignettes/articles/story-design-with-ahr.Rmd index f4a391904..a2d5c21f1 100644 --- a/vignettes/articles/story-design-with-ahr.Rmd +++ b/vignettes/articles/story-design-with-ahr.Rmd @@ -53,7 +53,7 @@ library(gsDesign) library(gsDesign2) library(ggplot2) library(dplyr) -library(gt) +library(lt) library(tidyr) library(tibble) ``` @@ -288,10 +288,10 @@ ss_ahr_fixed <- do.call( ) ss_ahr_fixed |> - gt() |> - fmt_number(columns = 1:3, decimals = 0) |> - fmt_number(columns = 4, decimals = 3) |> - tab_header( + lt() |> + lt_format(columns = 1:3, decimals = 0) |> + lt_format(columns = 4, decimals = 3) |> + lt_header( title = "Sample Size and Events Required by Scenario", subtitle = "36 Month Trial duration, 2.5% One-sided Type 1 Error, 90% Power" ) @@ -323,10 +323,10 @@ do.call( } ) ) |> - gt() |> - fmt_number(columns = 1:3, decimals = 0) |> - fmt_number(columns = 4, decimals = 3) |> - tab_header( + lt() |> + lt_format(columns = 1:3, decimals = 0) |> + lt_format(columns = 4, decimals = 3) |> + lt_header( title = "Sample Size and Events Required by Trial Duration", subtitle = "Delayed Effect of 4 Months, HR = 0.6 Thereafter; 90% Power" ) @@ -370,8 +370,8 @@ ahr_by_analysis <- events_by_time_period |> ahr_by_analysis |> pivot_wider(names_from = Scenario, values_from = AHR1) |> - gt() |> - fmt_number(columns = 2:5, decimals = 3) + lt() |> + lt_format(columns = 2:5, decimals = 3) ``` ## Group Sequential Design @@ -402,7 +402,7 @@ nph_asymmetric <- gs_design_ahr( lpar = lpar ) -summary(nph_asymmetric) |> as_gt() +summary(nph_asymmetric) |> as_lt() ``` By scenario, we now wish to compute the adjusted expected futility bounds and the power implied. @@ -432,9 +432,9 @@ do.call( } ) ) |> - gt() |> - fmt_number(columns = "event", decimals = 1) |> - fmt_number(columns = 5:10, decimals = 4) + lt() |> + lt_format(columns = "event", decimals = 1) |> + lt_format(columns = 5:10, decimals = 4) ``` ### Weighted Logrank Method @@ -462,8 +462,8 @@ do.call( } ) ) |> - gt() |> - fmt_number(columns = 3:6, decimals = 4) + lt() |> + lt_format(columns = 3:6, decimals = 4) ``` The fixed design under the second weighting scheme for four scenario are summarized as follows. @@ -489,8 +489,8 @@ do.call( } ) ) |> - gt() |> - fmt_number(columns = 3:6, decimals = 4) + lt() |> + lt_format(columns = 3:6, decimals = 4) ``` # References diff --git a/vignettes/articles/story-design-with-spending.Rmd b/vignettes/articles/story-design-with-spending.Rmd index 9d46e4f6d..5cad587f4 100644 --- a/vignettes/articles/story-design-with-spending.Rmd +++ b/vignettes/articles/story-design-with-spending.Rmd @@ -25,6 +25,7 @@ knitr::opts_chunk$set( ```{r, message=FALSE, warning=FALSE} library(gsDesign) library(gsDesign2) +library(lt) ``` # Overview @@ -53,8 +54,8 @@ enroll_rate <- define_enroll_rate( ) enroll_rate |> - gt::gt() |> - gt::tab_header(title = "Planned Relative Enrollment Rates") + lt() |> + lt_header(title = "Planned Relative Enrollment Rates") ``` We assume a hazard ratio (HR) of 0.9 for the first 3 months 0.6 thereafter. @@ -69,8 +70,8 @@ fail_rate <- define_fail_rate( ) fail_rate |> - gt::gt() |> - gt::tab_header(title = "Table of Failure Rate Assumptions") + lt() |> + lt_header(title = "Table of Failure Rate Assumptions") ``` # Fixed design with no interim analysis @@ -124,5 +125,5 @@ gs <- gs_design_ahr( gs |> summary() |> - gt::gt() + lt() ``` diff --git a/vignettes/articles/story-integer-design.Rmd b/vignettes/articles/story-integer-design.Rmd index 20b9f244e..d4c3af6c3 100644 --- a/vignettes/articles/story-integer-design.Rmd +++ b/vignettes/articles/story-integer-design.Rmd @@ -27,7 +27,7 @@ library(gsDesign) library(gsDesign2) library(tibble) library(dplyr) -library(gt) +library(lt) ``` # Unstratified design @@ -82,12 +82,12 @@ tibble( ) ) |> group_by(Design) |> - gt() |> - tab_header( + lt() |> + lt_header( title = "Comparison between the original/integer design", subtitle = "on binary endpoints (unstratified design)" ) |> - fmt_number(columns = 2:5, decimals = 4) + lt_format(columns = 2:5, decimals = 4) ``` ## Survival outcome @@ -122,12 +122,12 @@ tibble( ) ) |> group_by(Design) |> - gt() |> - tab_header( + lt() |> + lt_header( title = "Comparison between the original/integer design", subtitle = "on survival endpoints (unstratified design)" ) |> - fmt_number(columns = 2:5, decimals = 4) + lt_format(columns = 2:5, decimals = 4) ``` # Stratified design @@ -184,10 +184,10 @@ tibble( ) ) |> group_by(Design) |> - gt() |> - tab_header( + lt() |> + lt_header( title = "Comparison between the original/integer design", subtitle = "on binary endpoints (unstratified design)" ) |> - fmt_number(columns = 2:5, decimals = 4) + lt_format(columns = 2:5, decimals = 4) ``` diff --git a/vignettes/articles/story-nph-futility.Rmd b/vignettes/articles/story-nph-futility.Rmd index 3f08890e3..5ac2b9b96 100644 --- a/vignettes/articles/story-nph-futility.Rmd +++ b/vignettes/articles/story-nph-futility.Rmd @@ -17,7 +17,7 @@ vignette: > ```{r, warning=FALSE, message=FALSE} library(gsDesign2) -library(gt) +library(lt) library(dplyr) library(tibble) library(ggplot2) @@ -68,9 +68,9 @@ fixedevents <- fixed_design_ahr( fixedevents |> summary() |> select(-Bound) |> - as_gt(footnote = "Power based on 512 events") |> - fmt_number(columns = 3:4, decimals = 2) |> - fmt_number(columns = 5:6, decimals = 3) + as_lt(footnote = "Power based on 512 events") |> + lt_format(columns = 3:4, decimals = 2) |> + lt_format(columns = 5:6, decimals = 3) ``` # Beta-spending futility bound with AHR @@ -133,7 +133,7 @@ betaspending <- gs_power_ahr( betaspending |> summary() |> - as_gt( + as_lt( title = "Group sequential design with futility only", subtitle = "Beta-spending futility bound" ) @@ -164,7 +164,7 @@ wieand <- gs_power_ahr( wieand |> summary() |> - as_gt( + as_lt( title = "Group sequential design with futility only at interim analyses", subtitle = "Wieand futility rule stops if HR > 1" ) @@ -299,7 +299,7 @@ kf <- gs_power_ahr( kf |> summary() |> - as_gt(title = "Group sequential design with futility only", + as_lt(title = "Group sequential design with futility only", subtitle = "Korn and Freidlin futility rule stops if HR > 1") ``` @@ -329,7 +329,7 @@ betaspending_classic <- gs_power_ahr( betaspending_classic |> summary() |> - as_gt( + as_lt( title = "Group sequential design with futility only", subtitle = "Classical beta-spending futility bound" ) diff --git a/vignettes/articles/story-package-architecture.Rmd b/vignettes/articles/story-package-architecture.Rmd index 1370de38f..37b38b14a 100644 --- a/vignettes/articles/story-package-architecture.Rmd +++ b/vignettes/articles/story-package-architecture.Rmd @@ -51,10 +51,10 @@ Since the only class designation used by the package is `"fixed_design"` or Specifically, the package provides S3 methods for `print()`, `summary()`, and `to_integer()`. Furthermore, the `summary()` S3 method returns corresponding objects of class `"fixed_design_summary"` or `"gs_design_summary"`, and the -package provides the S3 methods `as_gt()` and `as_rtf()` to convert the summary -tables to [gt][] or [RTF][] format, respectively. +package provides the S3 methods `as_lt()` and `as_rtf()` to convert the summary +tables to [lt][] or [RTF][] format, respectively. -[gt]: https://github.com/rstudio/gt +[lt]: https://github.com/yihui/lt [rtf]: https://en.wikipedia.org/wiki/Rich_Text_Format ## How to query the trial characteristics from the design object diff --git a/vignettes/articles/story-power-evaluation-with-spending-bound.Rmd b/vignettes/articles/story-power-evaluation-with-spending-bound.Rmd index 6fbddd30a..de068ef62 100644 --- a/vignettes/articles/story-power-evaluation-with-spending-bound.Rmd +++ b/vignettes/articles/story-power-evaluation-with-spending-bound.Rmd @@ -25,7 +25,7 @@ knitr::opts_chunk$set( ```{r, message=FALSE, warning=FALSE} library(tibble) -library(gt) +library(lt) library(gsDesign2) ``` @@ -213,7 +213,7 @@ For the CAPTURE trial, we have ```{r} h1 <- gs_info_binomial(p1 = .15, p2 = .1, xi1 = .5, n = c(350, 700, 1400)) -h1 |> gt() +h1 |> lt() ``` We can plug these into `gs_power_npe()` with the intended spending functions. We begin with power under the alternate hypothesis @@ -230,8 +230,8 @@ gs_power_npe( lower = gs_spending_bound, lpar = list(sf = gsDesign::sfHSD, param = -2, total_spend = 0.2) ) |> - gt() |> - fmt_number(columns = 3:10, decimals = 4) + lt() |> + lt_format(columns = 3:10, decimals = 4) ``` Now we examine information for a smaller assumed treatment difference than the alternative: @@ -247,8 +247,8 @@ gs_power_npe( lower = gs_spending_bound, lpar = list(sf = gsDesign::sfHSD, param = -2, total_spend = 0.2) ) |> - gt() |> - fmt_number(columns = 3:10, decimals = 4) + lt() |> + lt_format(columns = 3:10, decimals = 4) ``` # References diff --git a/vignettes/articles/story-risk-difference.Rmd b/vignettes/articles/story-risk-difference.Rmd index a3e5bcce6..5c377d807 100644 --- a/vignettes/articles/story-risk-difference.Rmd +++ b/vignettes/articles/story-risk-difference.Rmd @@ -34,7 +34,7 @@ library(dplyr) library(knitr) library(gsDesign) library(gsDesign2) -library(gt) +library(lt) ``` # Overview @@ -555,7 +555,7 @@ theta_h1 <- abs(p_c - p_e) / sigma_h1 tibble::tribble( ~n_c, ~n_e, ~p_c, ~p_e, ~theta_h1, ~theta_h0, ~info_h1, ~info_h0, n_c, n_e, p_c, p_e, theta_h1, theta_h0, info_h1, info_h0, -) |> gt::gt() +) |> lt() ``` The above logic is implemented in the function `gs_info_rd()`. @@ -571,8 +571,8 @@ x <- gs_info_rd( ) x |> - gt::gt() |> - gt::fmt_number(columns = 5:8, decimals = 6) + lt() |> + lt_format(columns = 5:8, decimals = 6) ``` By plugging the `theta` and `info` above into `gs_design_npe()`, one can @@ -626,8 +626,8 @@ tibble( `info_scale = "h1_info"` = y_1$info1[1] / x$info1[1], `info_scale = "h0_h1_info"` = y_2$info[1] / x$info1[1] ) |> - gt::gt() |> - gt::tab_header(title = "The sample size calculated by gsDesign2 under 3 info_scale") + lt() |> + lt_header(title = "The sample size calculated by gsDesign2 under 3 info_scale") ``` The above logic is implement in `gs_design_rd()` to calculate the sample @@ -702,16 +702,16 @@ tibble::tibble( EAST_unpool = 645, EAST_pool = 651 ) |> - gt::gt() |> - gt::tab_spanner( + lt() |> + lt_spanner( label = "gsDesign2", - columns = c(gsDesign2_info_scale_0, gsDesign2_info_scale_1, gsDesign2_info_scale_2) + columns = c("gsDesign2_info_scale_0", "gsDesign2_info_scale_1", "gsDesign2_info_scale_2") ) |> - gt::tab_spanner( + lt_spanner( label = "EAST", - columns = c(EAST_unpool, EAST_pool) + columns = c("EAST_unpool", "EAST_pool") ) |> - cols_label( + lt_cols_label( gsDesign2_info_scale_0 = "info_scale = \"h0_info\"", gsDesign2_info_scale_1 = "info_scale = \"h1_info\"", gsDesign2_info_scale_2 = "info_scale = \"h0_h1_info\"", @@ -745,8 +745,8 @@ x_gs <- gs_info_rd( ) x_gs |> - gt::gt() |> - gt::tab_header(title = "The statistical information of the group sequential design") + lt() |> + lt_header(title = "The statistical information of the group sequential design") ``` ```{r} @@ -794,8 +794,8 @@ tibble( `info_scale = "h1_info"` = y_gs1$info1 / x_gs$info1[3], `info_scale = "h0_h1_info"` = y_gs2$info / x_gs$info1[3] ) |> - gt::gt() |> - gt::tab_header( + lt() |> + lt_header( title = "The sample size calculated by `gsDesign2` under 3 info_scale", subtitle = "under group sequential design" ) @@ -933,16 +933,16 @@ tibble::tibble( EAST_unpool = c(617, 1233, 1850), EAST_pool = c(619, 1238, 1857) ) |> - gt::gt() |> - gt::tab_spanner( + lt() |> + lt_spanner( label = "gsDesign2", - columns = c(gsDesign2_info_scale_0, gsDesign2_info_scale_1, gsDesign2_info_scale_2) + columns = c("gsDesign2_info_scale_0", "gsDesign2_info_scale_1", "gsDesign2_info_scale_2") ) |> - gt::tab_spanner( + lt_spanner( label = "EAST", - columns = c(EAST_unpool, EAST_pool) + columns = c("EAST_unpool", "EAST_pool") ) |> - cols_label( + lt_cols_label( gsDesign2_info_scale_0 = "info_scale = \"h0_info\"", gsDesign2_info_scale_1 = "info_scale = \"h1_info\"", gsDesign2_info_scale_2 = "info_scale = \"h0_h1_info\"", @@ -990,29 +990,14 @@ x <- p_c |> mutate(n_c = n_c * xi_c, n_e = n_e * xi_e) x |> - gt::gt() |> - gt::fmt_number(columns = 4:8, decimals = 4) |> - gt::tab_footnote( - footnote = "p_pool = (p_c * n_c + p_e * n_e) / (n_c * n_e).", - locations = gt::cells_column_labels(columns = p_pool) - ) |> - gt::tab_footnote( - footnote = "xi_c = sample size of a strata / sample size of the control arm.", - locations = gt::cells_column_labels(columns = xi_c) - ) |> - gt::tab_footnote( - footnote = "xi_e = sample size of a strata / sample size of the experimental arm.", - locations = gt::cells_column_labels(columns = xi_e) - ) |> - gt::tab_footnote( - footnote = "n_c = total sample size of the control arm.", - locations = gt::cells_column_labels(columns = n_c) - ) |> - gt::tab_footnote( - footnote = "n_e = total size of the experimental arm.", - locations = gt::cells_column_labels(columns = n_e) - ) |> - gt::tab_header(title = "Stratified Example") + lt() |> + lt_format(columns = 4:8, decimals = 4) |> + lt_footnote(text = "p_pool = (p_c * n_c + p_e * n_e) / (n_c * n_e).", where = "column", columns = "p_pool") |> + lt_footnote(text = "xi_c = sample size of a strata / sample size of the control arm.", where = "column", columns = "xi_c") |> + lt_footnote(text = "xi_e = sample size of a strata / sample size of the experimental arm.", where = "column", columns = "xi_e") |> + lt_footnote(text = "n_c = total sample size of the control arm.", where = "column", columns = "n_c") |> + lt_footnote(text = "n_e = total size of the experimental arm.", where = "column", columns = "n_e") |> + lt_header(title = "Stratified Example") ``` First, we calculate the variance @@ -1049,16 +1034,10 @@ x <- x |> ) x |> - gt() |> - gt::fmt_number(6:11, decimals = 4) |> - gt::tab_footnote( - footnote = "sigma_h0 = the H0 sd per stratum per analysis.", - locations = gt::cells_column_labels(columns = sigma_h0) - ) |> - gt::tab_footnote( - footnote = "sigma_h1 = the H0 sd per stratum per analysis.", - locations = gt::cells_column_labels(columns = sigma_h1) - ) + lt() |> + lt_format(6:11, decimals = 4) |> + lt_footnote(text = "sigma_h0 = the H0 sd per stratum per analysis.", where = "column", columns = "sigma_h0") |> + lt_footnote(text = "sigma_h1 = the H0 sd per stratum per analysis.", where = "column", columns = "sigma_h1") ``` Second, we calculate the weight by using inverse variance @@ -1086,20 +1065,11 @@ x <- x |> select(-c(sum_invar_H0, sum_invar_H1, sum_ss)) x |> - gt() |> - fmt_number(6:14, decimals = 4) |> - gt::tab_footnote( - footnote = "weight_invar_H0 = the weight per stratum per analysis calculated by INVAR by using variance under H0.", - locations = gt::cells_column_labels(columns = weight_invar_H0) - ) |> - gt::tab_footnote( - footnote = "weight_invar_H1 = the weight per stratum per analysis calculated by INVAR by using variance under H1.", - locations = gt::cells_column_labels(columns = weight_invar_H1) - ) |> - gt::tab_footnote( - footnote = "weight_ss = the weight per stratum per analysis calculated by SS.", - locations = gt::cells_column_labels(columns = weight_ss) - ) + lt() |> + lt_format(6:14, decimals = 4) |> + lt_footnote(text = "weight_invar_H0 = the weight per stratum per analysis calculated by INVAR by using variance under H0.", where = "column", columns = "weight_invar_H0") |> + lt_footnote(text = "weight_invar_H1 = the weight per stratum per analysis calculated by INVAR by using variance under H1.", where = "column", columns = "weight_invar_H1") |> + lt_footnote(text = "weight_ss = the weight per stratum per analysis calculated by SS.", where = "column", columns = "weight_ss") ``` Third, we calculate the weighted risk difference and weighted @@ -1176,38 +1146,14 @@ x <- x |> ```{r} x |> - gt::gt() |> - fmt_number(c(2:4, 6:11), decimals = 6) |> - gt::tab_footnote( - footnote = "info_invar_H0 = the statistical information under H1 - per stratum per analysis calculated by INVAR by using variance under H0.", - locations = gt::cells_column_labels(columns = info_invar_H0) - ) |> - gt::tab_footnote( - footnote = "info_invar_H1 = the statistical information under H1 - per stratum per analysis calculated by INVAR by using variance under H0.", - locations = gt::cells_column_labels(columns = info_invar_H1) - ) |> - gt::tab_footnote( - footnote = "info_ss = the statistical information under H1 - per stratum per analysis calculated by SS.", - locations = gt::cells_column_labels(columns = info_ss) - ) |> - gt::tab_footnote( - footnote = "info0_invar_H0 = the statistical information under H0 - per stratum per analysis calculated by INVAR by using variance under H0.", - locations = gt::cells_column_labels(columns = info0_invar_H0) - ) |> - gt::tab_footnote( - footnote = "info0_invar_H1 = the statistical information under H0 - per stratum per analysis calculated by INVAR by using variance under H0.", - locations = gt::cells_column_labels(columns = info0_invar_H1) - ) |> - gt::tab_footnote( - footnote = "info0_ss = the statistical information under H0 - per stratum per analysis calculated by SS.", - locations = gt::cells_column_labels(columns = info0_ss) - ) + lt() |> + lt_format(c(2:4, 6:11), decimals = 6) |> + lt_footnote(text = "info_invar_H0 = the statistical information under H1 per stratum per analysis calculated by INVAR by using variance under H0.", where = "column", columns = "info_invar_H0") |> + lt_footnote(text = "info_invar_H1 = the statistical information under H1 per stratum per analysis calculated by INVAR by using variance under H0.", where = "column", columns = "info_invar_H1") |> + lt_footnote(text = "info_ss = the statistical information under H1 per stratum per analysis calculated by SS.", where = "column", columns = "info_ss") |> + lt_footnote(text = "info0_invar_H0 = the statistical information under H0 per stratum per analysis calculated by INVAR by using variance under H0.", where = "column", columns = "info0_invar_H0") |> + lt_footnote(text = "info0_invar_H1 = the statistical information under H0 per stratum per analysis calculated by INVAR by using variance under H0.", where = "column", columns = "info0_invar_H1") |> + lt_footnote(text = "info0_ss = the statistical information under H0 per stratum per analysis calculated by SS.", where = "column", columns = "info0_ss") ``` ```{r} @@ -1311,8 +1257,8 @@ ans_math <- tibble::tibble( ) ans_math |> - gt::gt() |> - gt::tab_header(title = "Sample size calculated by INVAR and SS") + lt() |> + lt_header(title = "Sample size calculated by INVAR and SS") ``` The above logic is implemented in `gs_design_rd()`. @@ -1518,9 +1464,9 @@ ans <- tibble::tibble( ) ans |> - gt::gt() |> - gt::tab_header(title = "Sample size calculated by INVAR and SS") |> - gt::tab_spanner( + lt() |> + lt_header(title = "Sample size calculated by INVAR and SS") |> + lt_spanner( label = "Inverse variance weighting ", columns = c( "INVAR0", @@ -1528,11 +1474,11 @@ ans |> "INVAR2" ) ) |> - gt::tab_spanner( + lt_spanner( label = "Sample size weighting", - columns = c(SS0, SS1, SS2) + columns = c("SS0", "SS1", "SS2") ) |> - cols_label( + lt_cols_label( INVAR0 = "info_scale = \"h0_info\"", INVAR1 = "info_scale = \"h1_info\"", INVAR2 = "info_scale = \"h0_h1_info\"", diff --git a/vignettes/articles/story-seven-test-types.Rmd b/vignettes/articles/story-seven-test-types.Rmd index 8c68d621f..0120ef862 100644 --- a/vignettes/articles/story-seven-test-types.Rmd +++ b/vignettes/articles/story-seven-test-types.Rmd @@ -100,7 +100,7 @@ one_sided <- gsDesign2::gs_design_ahr( one_sided |> summary() |> - gsDesign2::as_gt(title = "Efficacy bound only", subtitle = "alpha-spending") + gsDesign2::as_lt(title = "Efficacy bound only", subtitle = "alpha-spending") ``` Now we check this with `gsDesign::gsSurv().` As noted above, sample size and event counts vary slightly from the design derived using `gs_design_ahr()`. @@ -153,7 +153,7 @@ symmetric <- gs_design_ahr( symmetric |> summary() |> - gsDesign2::as_gt( + gsDesign2::as_lt( title = "2-sided Symmetric Design", subtitle = "Single spending function" ) @@ -209,7 +209,7 @@ asymmetric_binding <- gs_design_ahr( asymmetric_binding |> summary() |> - gsDesign2::as_gt( + gsDesign2::as_lt( title = "2-sided asymmetric design with binding futility", subtitle = "Both alpha- and beta-spending used" ) @@ -265,7 +265,7 @@ asymmetric_nonbinding <- gs_design_ahr( asymmetric_nonbinding |> summary() |> - gsDesign2::as_gt( + gsDesign2::as_lt( title = "2-sided asymmetric design with non-binding futility", subtitle = "Both alpha- and beta-spending used" ) @@ -325,7 +325,7 @@ asymmetric_safety_binding <- gs_design_ahr( asymmetric_safety_binding |> summary() |> - gsDesign2::as_gt( + gsDesign2::as_lt( title = "2-sided asymmetric safety design with binding futility", subtitle = "Alpha-spending used for both bounds, asymmetrically" ) @@ -381,11 +381,11 @@ asymmetric_safety_nonbinding <- gs_design_ahr( asymmetric_safety_nonbinding |> summary() |> - gsDesign2::as_gt( + gsDesign2::as_lt( title = "2-sided asymmetric safety design with non-binding futility", subtitle = "Alpha-spending used for both bounds, asymmetrically" ) |> - gt::tab_footnote(footnote = "Integer-based sample size and event counts") + lt::lt_note("Integer-based sample size and event counts") ``` The corresponding `gsDesign::gsSurv()` design is not strictly comparable since the option to eliminate some futility and efficacy analyses is not enabled. @@ -477,11 +477,11 @@ asymmetric_fixed_bounds <- gs_design_ahr( asymmetric_fixed_bounds |> summary() |> - gsDesign2::as_gt( + gsDesign2::as_lt( title = "2-sided asymmetric safety design with fixed non-binding futility", subtitle = "Futility bounds computed to approximate HR" ) |> - gt::tab_footnote(footnote = "Integer-based sample size and event counts") + lt::lt_note("Integer-based sample size and event counts") ``` We see that the targeted bounds are achieved with nominal $p$-values of 0.0001 for each interim efficacy bound and the targeted hazard ratios at interim futility bounds. diff --git a/vignettes/articles/story-spending-time-example.Rmd b/vignettes/articles/story-spending-time-example.Rmd index 6b972622c..f75ba3cdb 100644 --- a/vignettes/articles/story-spending-time-example.Rmd +++ b/vignettes/articles/story-spending-time-example.Rmd @@ -28,7 +28,7 @@ library(gsDesign) library(gsDesign2) library(tibble) library(dplyr) -library(gt) +library(lt) ``` # Overview @@ -128,7 +128,7 @@ xx <- gs_design_ahr(enroll_rate, summary(xx, analysis_vars = c("time", "n", "event", "ahr", "info_frac"), analysis_decimals = c(0, 0, 0, 4, 4) -) |> as_gt() +) |> as_lt() ``` ## Power when assumptions design are wrong @@ -166,7 +166,7 @@ yy <- gs_power_ahr( yy |> summary() |> - as_gt() + as_lt() ``` Now we also require 30 months trial duration in addition to the targeted events. @@ -192,7 +192,7 @@ yy <- gs_power_ahr( # get the summary table of updated design yy |> summary() |> - as_gt() + as_lt() ``` ## Scenario 2: low control event rates @@ -222,7 +222,7 @@ yy <- gs_power_ahr( yy |> summary() |> - as_gt() + as_lt() ``` If we also require adequate events, we restore power to 94.5, above the originally targeted level of 90%. @@ -247,7 +247,7 @@ yy <- gs_power_ahr( yy |> summary() |> - as_gt() + as_lt() ``` ## Conclusions for fixed design @@ -379,7 +379,7 @@ xx <- gs_design_ahr( # get the summary table xx |> summary() |> - as_gt() + as_lt() ``` ## Two alternate approaches @@ -416,7 +416,7 @@ yy <- gs_power_ahr( yy |> summary() |> - as_gt() + as_lt() ``` ### Fixed incremental spend with a variable number of analyses @@ -479,7 +479,7 @@ fho <- gs_power_ahr( fho |> summary() |> - as_gt() + as_lt() ``` ## Scenario with less treatment effect @@ -523,8 +523,8 @@ yy <- gs_power_ahr( yy |> summary() |> filter(Bound == "Efficacy") |> - gt() |> - fmt_number(columns = 3:6, decimals = 4) + lt() |> + lt_format(columns = 3:6, decimals = 4) ``` Just as important, the general design principle of making interim analysis criteria more stringent that final is ensured for this alternate scenario. @@ -544,8 +544,8 @@ yz <- gs_power_ahr( yz |> summary() |> - gt() |> - fmt_number(columns = 3:6, decimals = 4) + lt() |> + lt_format(columns = 3:6, decimals = 4) ``` ## Scenario with longer control median @@ -578,8 +578,8 @@ yy <- gs_power_ahr( yy |> summary() |> - gt() |> - fmt_number(columns = 3:6, decimals = 4) + lt() |> + lt_format(columns = 3:6, decimals = 4) ``` Since the number of events was less than expected, if we had used the actual number of events the interim bound would be more stringent than above and we obtain slightly greater power. @@ -598,8 +598,8 @@ yz <- gs_power_ahr( yz |> summary() |> - gt() |> - fmt_number(columns = 3:6, decimals = 4) + lt() |> + lt_format(columns = 3:6, decimals = 4) ``` ## Summary for spending time motivation assuming delayed benefit @@ -683,8 +683,8 @@ positive <- gs_design_ahr( positive |> summary() |> - gt() |> - fmt_number(columns = 3:6, decimals = 4) + lt() |> + lt_format(columns = 3:6, decimals = 4) ``` ## Planned design for overall population @@ -697,7 +697,7 @@ inflation_factor <- positive$enroll_rate$rate[1] / enroll_rate$rate[1] # Using this inflation factor, set planned enrollment rates planned_enroll_rate <- enroll_rate |> mutate(rate = rate * inflation_factor) -planned_enroll_rate |> gt() +planned_enroll_rate |> lt() # Store overall enrollment rates for future use overall_enroll_rate <- planned_enroll_rate |> @@ -707,7 +707,7 @@ overall_enroll_rate <- planned_enroll_rate |> rate = sum(rate) ) -overall_enroll_rate |> gt() +overall_enroll_rate |> lt() ``` Now we can examine the power for the overall population based on hazard ratio assumptions in biomarker negative and biomarker positive subgroups and the just calculated enrollment assumption. @@ -746,8 +746,8 @@ overall_planned_bounds <- gs_power_ahr( overall_planned_bounds |> summary() |> - gt() |> - fmt_number(columns = 3:6, decimals = 4) + lt() |> + lt_format(columns = 3:6, decimals = 4) ``` ## Alternate scenarios overview @@ -817,8 +817,8 @@ positive_60_enroll_rate$duration <- max(positive$analysis$n) / # display the updated enrollment rate table positive_60_enroll_rate |> - gt() |> - fmt_number(columns = "rate", decimals = 1) + lt() |> + lt_format(columns = "rate", decimals = 1) ``` Now we can compute the power for the biomarker positive group with the targeted events. @@ -843,8 +843,8 @@ positive_60_power <- gs_power_ahr( positive_60_power |> summary() |> - gt() |> - fmt_number(columns = 3:6, decimals = 4) + lt() |> + lt_format(columns = 3:6, decimals = 4) ``` #### Overall population power @@ -869,8 +869,8 @@ gs_power_ahr( lpar = rep(-Inf, 2) ) |> summary() |> - gt() |> - fmt_number(columns = 3:6, decimals = 4) + lt() |> + lt_format(columns = 3:6, decimals = 4) ``` If we had used information-based (i.e., event-based) spending, we would not have reached full spending at final analysis and thus would have lower power. @@ -891,8 +891,8 @@ gs_power_ahr( lpar = lpar ) |> summary() |> - gt() |> - fmt_number(columns = 3:6, decimals = 4) + lt() |> + lt_format(columns = 3:6, decimals = 4) ``` ### Biomarker subgroup prevalence lower than planned @@ -913,8 +913,8 @@ positive_40_enroll_rate$duration <- max(positive$analysis$n) / # display the enrollment table positive_40_enroll_rate |> - gt() |> - fmt_number(columns = "rate", decimals = 1) + lt() |> + lt_format(columns = "rate", decimals = 1) ``` #### Biomarker positive subgroup power @@ -942,8 +942,8 @@ positive_40_power <- gs_power_ahr( positive_40_power |> summary() |> - gt() |> - fmt_number(columns = 3:6, decimals = 4) + lt() |> + lt_format(columns = 3:6, decimals = 4) ``` #### Overall population power @@ -963,8 +963,8 @@ gs_power_ahr( lpar = rep(-Inf, 2) ) |> summary() |> - gt() |> - fmt_number(columns = 3:6, decimals = 4) + lt() |> + lt_format(columns = 3:6, decimals = 4) ``` ## Summary of findings diff --git a/vignettes/articles/story-update-boundary.Rmd b/vignettes/articles/story-update-boundary.Rmd index 3aa580551..c346e921f 100644 --- a/vignettes/articles/story-update-boundary.Rmd +++ b/vignettes/articles/story-update-boundary.Rmd @@ -23,7 +23,7 @@ knitr::opts_chunk$set(echo = TRUE) ```{r, message=FALSE, warning=FALSE} library(gsDesign2) -library(gt) +library(lt) ``` # Design assumptions @@ -116,8 +116,7 @@ over the targeted 90\%. ```{r} x |> summary() |> - as_gt() |> - tab_header(title = "Planned design") + as_lt(title = "Planned design") ``` ## Bounds for alternate alpha @@ -132,7 +131,7 @@ gs_update_ahr( alpha = 0.025 ) |> summary(col_decimals = c(z = 4)) |> - as_gt(title = "Updated design", + as_lt(title = "Updated design", subtitle = "For alternate alpha = 0.025") ``` The above updated boundaries utilize the planned treatment effect and the planned statistical information under null hypothesis, considering the original design has `info_scale = "h0_info"`. @@ -164,7 +163,7 @@ gs_update_ahr( event = c(30, 210, 32, 320)) ) |> summary(col_decimals = c(z = 4)) |> - as_gt(title = "Updated design", + as_lt(title = "Updated design", subtitle = paste0("With observed 240 events at IA and 352 events at FA")) ``` @@ -223,9 +222,8 @@ larger than we had above in the 1-sided example. ```{r} x |> summary() |> - as_gt() |> - tab_header(title = "Planned design", - subtitle = "2-sided asymmetric design, non-binding futility") + as_lt(title = "Planned design", + subtitle = "2-sided asymmetric design, non-binding futility") ``` ## Bounds for alternate alpha @@ -239,7 +237,7 @@ gs_update_ahr( alpha = 0.025 ) |> summary(col_decimals = c(z = 4)) |> - as_gt(title = "Updated design", + as_lt(title = "Updated design", subtitle = "For alpha = 0.025") ``` @@ -261,7 +259,7 @@ gs_update_ahr( event = c(30, 210, 32, 320)) ) |> summary(col_decimals = c(z = 4)) |> - as_gt(title = "Updated design", + as_lt(title = "Updated design", subtitle = paste0("With observed 240 events at IA and 352 events at FA")) ``` diff --git a/vignettes/gsDesign2.Rmd b/vignettes/gsDesign2.Rmd index abfd6450a..ae1588e4b 100644 --- a/vignettes/gsDesign2.Rmd +++ b/vignettes/gsDesign2.Rmd @@ -69,7 +69,7 @@ library(gsDesign) library(gsDesign2) library(knitr) library(dplyr) -library(gt) +library(lt) library(ggplot2) ``` @@ -86,7 +86,7 @@ enroll_rate <- define_enroll_rate( rate = (1:4) / 4 ) -enroll_rate |> gt() +enroll_rate |> lt() ``` # Failure and dropout rates @@ -112,7 +112,7 @@ fail_rate <- define_fail_rate( dropout_rate = .001 ) -fail_rate |> gt() +fail_rate |> lt() ``` # Fixed design @@ -138,14 +138,14 @@ Note that you would normally round up `N` up to an even number and `Events` to t ```{r} d |> summary() |> - as_gt() + as_lt() ``` The enrollment rates for each period have been increased proportionately to size the trial for the desired properties; the duration for each enrollment rate has not changed. ```{r} -d$enroll_rate |> gt() +d$enroll_rate |> lt() ``` # Group sequential design @@ -210,7 +210,7 @@ Note that expected sample size at time of each data cutoff for analysis is also ```{r} design1s |> summary() |> - as_gt( + as_lt( title = "1-sided group sequential bound using AHR method", subtitle = "Lan-DeMets spending to approximate O'Brien-Fleming bound" ) @@ -260,7 +260,7 @@ Design bounds are confirmed with: ```{r, message=FALSE} design2ss |> summary() |> - as_gt( + as_lt( title = "2-sided symmetric group sequential bound using AHR method", subtitle = "Lan-DeMets spending to approximate O'Brien-Fleming bound" ) @@ -308,7 +308,7 @@ Bounds are now: ```{r} design2sa |> summary() |> - as_gt( + as_lt( title = "2-sided asymmetric group sequential bound using AHR method", subtitle = "Lan-DeMets spending to approximate O'Brien-Fleming bound for efficacy, futility disaster check at IA1, IA2 only"