diff --git a/DESCRIPTION b/DESCRIPTION
index c96d6bdb..29d52db4 100644
--- a/DESCRIPTION
+++ b/DESCRIPTION
@@ -22,7 +22,7 @@ Imports:
dplyr (>= 1.1.0),
ggplot2 (>= 3.1.1),
graphics,
- gt,
+ lt,
methods,
r2rtf,
rlang,
@@ -44,6 +44,8 @@ Suggests:
testthat,
utils,
vdiffr
+Remotes:
+ yihui/lt
VignetteBuilder:
knitr
Config/roxygen2/version: 8.0.0
diff --git a/NAMESPACE b/NAMESPACE
index ff9aba52..38cac007 100644
--- a/NAMESPACE
+++ b/NAMESPACE
@@ -1,9 +1,9 @@
# Generated by roxygen2: do not edit by hand
-S3method(as_gt,gsBinomialExactTable)
S3method(as_rtf,gsBinomialExactTable)
S3method(as_rtf,gsBoundSummary)
S3method(as_table,gsBinomialExact)
+S3method(lt::lt,gsBinomialExactTable)
S3method(plot,binomialSPRT)
S3method(plot,gsBinomialExact)
S3method(plot,gsDesign)
@@ -140,13 +140,6 @@ importFrom(graphics,plot)
importFrom(graphics,points)
importFrom(graphics,strwidth)
importFrom(graphics,text)
-importFrom(gt,cols_label)
-importFrom(gt,fmt_number)
-importFrom(gt,fmt_percent)
-importFrom(gt,gt)
-importFrom(gt,html)
-importFrom(gt,tab_header)
-importFrom(gt,tab_spanner)
importFrom(methods,is)
importFrom(r2rtf,rtf_body)
importFrom(r2rtf,rtf_colheader)
diff --git a/NEWS.md b/NEWS.md
index 24f1e0ed..16b8662d 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -1,5 +1,14 @@
# gsDesign (development version)
+## Major changes
+
+- The (heavy) **gt** dependency has been replaced with the lightweight **lt**
+ package. The `as_gt()` function is deprecated in favor of `lt::lt()`. An S3
+ method for `lt()` is provided for `gsBinomialExactTable` objects, and all
+ vignettes now use lt functions (`lt()`, `lt_header()`, `lt_spanner()`,
+ `lt_format()`, `lt_footnote()`, `lt_note()`, `lt_label()`, `lt_align()`,
+ `lt_group()`). There are no significant visual changes in the HTML tables.
+
# gsDesign 3.10.0
## New features
diff --git a/R/as_gt.R b/R/as_gt.R
index 08113cf6..6c6cad02 100644
--- a/R/as_gt.R
+++ b/R/as_gt.R
@@ -1,82 +1,17 @@
-#' Convert a summary table object to a gt object
+#' Deprecated: use lt() instead
#'
-#' Convert a summary table object created with \code{\link{as_table}}
-#' to a \code{gt_tbl} object; currently only implemented for
-#' \code{\link{gsBinomialExact}}.
+#' \code{as_gt()} is deprecated; use \code{\link[lt]{lt}()} instead.
#'
#' @param x Object to be converted.
-#' @param ... Other parameters that may be specific to the object.
+#' @param ... Additional arguments passed to \code{\link[lt]{lt}()}.
#'
-#' @return A \code{gt_tbl} object that may be extended by overloaded versions of
-#' \code{\link{as_gt}}.
+#' @return An \code{lt_tbl} object.
#'
-#' @seealso \code{vignette("binomialSPRTExample")}
-#'
-#' @details
-#' Currently only implemented for \code{\link{gsBinomialExact}} objects.
-#' Creates a table to summarize an object.
-#' For \code{\link{gsBinomialExact}}, this summarized operating characteristics
-#' across a range of effect sizes.
-#'
-#' @export
-#'
-#' @examples
-#' safety_design <- binomialSPRT(
-#' p0 = .04, p1 = .1, alpha = .04, beta = .2, minn = 4, maxn = 75
-#' )
-#' safety_power <- gsBinomialExact(
-#' k = length(safety_design$n.I),
-#' theta = seq(.02, .16, .02),
-#' n.I = safety_design$n.I,
-#' a = safety_design$lower$bound,
-#' b = safety_design$upper$bound
-#' )
-#' safety_power |>
-#' as_table() |>
-#' as_gt(
-#' theta_label = gt::html("Underlying
AE rate"),
-#' prob_decimals = 3,
-#' bound_label = c("low rate", "high rate")
-#' )
-as_gt <- function(x, ...) UseMethod("as_gt")
-
-#' @rdname as_gt
-#'
-#' @param title Table title.
-#' @param subtitle Table subtitle.
-#' @param theta_label Label for theta.
-#' @param bound_label Label for bounds.
-#' @param prob_decimals Number of decimal places for probability of crossing.
-#' @param en_decimals Number of decimal places for expected number of
-#' observations when bound is crossed or when trial ends without crossing.
-#' @param rr_decimals Number of decimal places for response rates.
-#'
-#' @importFrom gt gt tab_spanner cols_label html fmt_number fmt_percent tab_header
+#' @seealso \code{\link{lt-methods}}
#'
#' @export
-as_gt.gsBinomialExactTable <- function(
- x,
- ...,
- title = "Operating Characteristics for the Truncated SPRT Design",
- subtitle = "Assumes trial evaluated sequentially after each response",
- theta_label = html("Underlying
response rate"),
- bound_label = c("Futility bound", "Efficacy bound"),
- prob_decimals = 2,
- en_decimals = 1,
- rr_decimals = 0) {
- out_gt <- x |>
- gt() |>
- tab_spanner(label = "Probability of crossing", columns = c(Lower, Upper)) |>
- cols_label(
- theta = theta_label,
- Lower = bound_label[1],
- Upper = bound_label[2],
- en = html("Average
sample size")
- ) |>
- fmt_number(columns = c(Lower, Upper), decimals = prob_decimals) |>
- fmt_number(columns = en, decimals = en_decimals) |>
- fmt_percent(columns = theta, decimals = rr_decimals) |>
- tab_header(title = title, subtitle = subtitle)
-
- out_gt
+as_gt <- function(x, ...) {
+ .Deprecated("lt", package = "lt",
+ msg = "as_gt() is deprecated; please use lt::lt() instead.")
+ lt::lt(x, ...)
}
diff --git a/R/as_lt.R b/R/as_lt.R
new file mode 100644
index 00000000..b5c393de
--- /dev/null
+++ b/R/as_lt.R
@@ -0,0 +1,72 @@
+#' Convert a summary table object to an lt table
+#'
+#' Convert a summary table object created with \code{\link{as_table}}
+#' to an \code{lt_tbl} object; currently only implemented for
+#' \code{\link{gsBinomialExact}}.
+#'
+#' @param data Object to be converted.
+#' @param ... Other parameters that may be specific to the object.
+#' @param title Table title.
+#' @param subtitle Table subtitle.
+#' @param theta_label Label for theta.
+#' @param bound_label Label for bounds.
+#' @param prob_decimals Number of decimal places for probability of crossing.
+#' @param en_decimals Number of decimal places for expected number of
+#' observations when bound is crossed or when trial ends without crossing.
+#' @param rr_decimals Number of decimal places for response rates.
+#'
+#' @return An \code{lt_tbl} object.
+#'
+#' @seealso \code{vignette("binomialSPRTExample")}
+#'
+#' @details
+#' Currently only implemented for \code{\link{gsBinomialExact}} objects.
+#' Creates a table to summarize an object.
+#' For \code{\link{gsBinomialExact}}, this summarized operating characteristics
+#' across a range of effect sizes.
+#'
+#' @name lt-methods
+#'
+#' @examples
+#' safety_design <- binomialSPRT(
+#' p0 = .04, p1 = .1, alpha = .04, beta = .2, minn = 4, maxn = 75
+#' )
+#' safety_power <- gsBinomialExact(
+#' k = length(safety_design$n.I),
+#' theta = seq(.02, .16, .02),
+#' n.I = safety_design$n.I,
+#' a = safety_design$lower$bound,
+#' b = safety_design$upper$bound
+#' )
+#' safety_power |>
+#' as_table() |>
+#' lt::lt(
+#' theta_label = I("Underlying
AE rate"),
+#' prob_decimals = 3,
+#' bound_label = c("low rate", "high rate")
+#' )
+#'
+#' @exportS3Method lt::lt
+lt.gsBinomialExactTable <- function(
+ data,
+ ...,
+ title = "Operating Characteristics for the Truncated SPRT Design",
+ subtitle = "Assumes trial evaluated sequentially after each response",
+ theta_label = I("Underlying
response rate"),
+ bound_label = c("Futility bound", "Efficacy bound"),
+ prob_decimals = 2,
+ en_decimals = 1,
+ rr_decimals = 0) {
+ lt::lt(as.data.frame(data), ...) |>
+ lt::lt_spanner(label = "Probability of crossing", columns = c("Lower", "Upper")) |>
+ lt::lt_label(
+ theta = theta_label,
+ Lower = bound_label[1],
+ Upper = bound_label[2],
+ en = I("Average
sample size")
+ ) |>
+ lt::lt_format(columns = c("Lower", "Upper"), decimals = prob_decimals) |>
+ lt::lt_format(columns = "en", decimals = en_decimals) |>
+ lt::lt_format(columns = "theta", decimals = rr_decimals, percent = TRUE) |>
+ lt::lt_header(title = title, subtitle = subtitle)
+}
diff --git a/R/as_table.R b/R/as_table.R
index d37b94b2..3b48a379 100644
--- a/R/as_table.R
+++ b/R/as_table.R
@@ -30,7 +30,7 @@
#' )
#' b_power |>
#' as_table() |>
-#' as_gt()
+#' lt::lt()
as_table <- function(x, ...) UseMethod("as_table")
#' @rdname as_table
diff --git a/R/globals.R b/R/globals.R
index 08605416..6df05d46 100644
--- a/R/globals.R
+++ b/R/globals.R
@@ -1,7 +1,7 @@
utils::globalVariables(
unique(
c(
- # From `as_gt.gsBinomialExactTable()`
+ # From `lt.gsBinomialExactTable()`
c("Lower", "Upper", "en", "theta"),
# From `binomialPowerTable()`
c("pE")
diff --git a/_pkgdown.yml b/_pkgdown.yml
index e798df10..71cfdb6b 100755
--- a/_pkgdown.yml
+++ b/_pkgdown.yml
@@ -131,8 +131,8 @@ reference:
contents:
- as_table
- as_table.gsBinomialExact
+ - lt-methods
- as_gt
- - as_gt.gsBinomialExactTable
- as_rtf
- as_rtf.gsBinomialExactTable
diff --git a/man/as_gt.Rd b/man/as_gt.Rd
index 09e13150..00b1b2ee 100644
--- a/man/as_gt.Rd
+++ b/man/as_gt.Rd
@@ -2,77 +2,21 @@
% Please edit documentation in R/as_gt.R
\name{as_gt}
\alias{as_gt}
-\alias{as_gt.gsBinomialExactTable}
-\title{Convert a summary table object to a gt object}
+\title{Deprecated: use lt() instead}
\usage{
as_gt(x, ...)
-
-\method{as_gt}{gsBinomialExactTable}(
- x,
- ...,
- title = "Operating Characteristics for the Truncated SPRT Design",
- subtitle = "Assumes trial evaluated sequentially after each response",
- theta_label = html("Underlying
response rate"),
- bound_label = c("Futility bound", "Efficacy bound"),
- prob_decimals = 2,
- en_decimals = 1,
- rr_decimals = 0
-)
}
\arguments{
\item{x}{Object to be converted.}
-\item{...}{Other parameters that may be specific to the object.}
-
-\item{title}{Table title.}
-
-\item{subtitle}{Table subtitle.}
-
-\item{theta_label}{Label for theta.}
-
-\item{bound_label}{Label for bounds.}
-
-\item{prob_decimals}{Number of decimal places for probability of crossing.}
-
-\item{en_decimals}{Number of decimal places for expected number of
-observations when bound is crossed or when trial ends without crossing.}
-
-\item{rr_decimals}{Number of decimal places for response rates.}
+\item{...}{Additional arguments passed to \code{\link[lt]{lt}()}.}
}
\value{
-A \code{gt_tbl} object that may be extended by overloaded versions of
- \code{\link{as_gt}}.
+An \code{lt_tbl} object.
}
\description{
-Convert a summary table object created with \code{\link{as_table}}
-to a \code{gt_tbl} object; currently only implemented for
-\code{\link{gsBinomialExact}}.
-}
-\details{
-Currently only implemented for \code{\link{gsBinomialExact}} objects.
-Creates a table to summarize an object.
-For \code{\link{gsBinomialExact}}, this summarized operating characteristics
-across a range of effect sizes.
-}
-\examples{
-safety_design <- binomialSPRT(
- p0 = .04, p1 = .1, alpha = .04, beta = .2, minn = 4, maxn = 75
-)
-safety_power <- gsBinomialExact(
- k = length(safety_design$n.I),
- theta = seq(.02, .16, .02),
- n.I = safety_design$n.I,
- a = safety_design$lower$bound,
- b = safety_design$upper$bound
-)
-safety_power |>
- as_table() |>
- as_gt(
- theta_label = gt::html("Underlying
AE rate"),
- prob_decimals = 3,
- bound_label = c("low rate", "high rate")
- )
+\code{as_gt()} is deprecated; use \code{\link[lt]{lt}()} instead.
}
\seealso{
-\code{vignette("binomialSPRTExample")}
+\code{\link{lt-methods}}
}
diff --git a/man/as_table.Rd b/man/as_table.Rd
index 57a8564f..c486ebe5 100644
--- a/man/as_table.Rd
+++ b/man/as_table.Rd
@@ -35,7 +35,7 @@ b_power <- gsBinomialExact(
)
b_power |>
as_table() |>
- as_gt()
+ lt::lt()
}
\seealso{
\code{vignette("binomialSPRTExample")}
diff --git a/man/lt-methods.Rd b/man/lt-methods.Rd
new file mode 100644
index 00000000..c0f25fe4
--- /dev/null
+++ b/man/lt-methods.Rd
@@ -0,0 +1,76 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/as_lt.R
+\name{lt-methods}
+\alias{lt-methods}
+\alias{lt.gsBinomialExactTable}
+\title{Convert a summary table object to an lt table}
+\usage{
+\method{lt}{gsBinomialExactTable}(
+ data,
+ ...,
+ title = "Operating Characteristics for the Truncated SPRT Design",
+ subtitle = "Assumes trial evaluated sequentially after each response",
+ theta_label = I("Underlying
response rate"),
+ bound_label = c("Futility bound", "Efficacy bound"),
+ prob_decimals = 2,
+ en_decimals = 1,
+ rr_decimals = 0
+)
+}
+\arguments{
+\item{data}{Object to be converted.}
+
+\item{...}{Other parameters that may be specific to the object.}
+
+\item{title}{Table title.}
+
+\item{subtitle}{Table subtitle.}
+
+\item{theta_label}{Label for theta.}
+
+\item{bound_label}{Label for bounds.}
+
+\item{prob_decimals}{Number of decimal places for probability of crossing.}
+
+\item{en_decimals}{Number of decimal places for expected number of
+observations when bound is crossed or when trial ends without crossing.}
+
+\item{rr_decimals}{Number of decimal places for response rates.}
+}
+\value{
+An \code{lt_tbl} object.
+}
+\description{
+Convert a summary table object created with \code{\link{as_table}}
+to an \code{lt_tbl} object; currently only implemented for
+\code{\link{gsBinomialExact}}.
+}
+\details{
+Currently only implemented for \code{\link{gsBinomialExact}} objects.
+Creates a table to summarize an object.
+For \code{\link{gsBinomialExact}}, this summarized operating characteristics
+across a range of effect sizes.
+}
+\examples{
+safety_design <- binomialSPRT(
+ p0 = .04, p1 = .1, alpha = .04, beta = .2, minn = 4, maxn = 75
+)
+safety_power <- gsBinomialExact(
+ k = length(safety_design$n.I),
+ theta = seq(.02, .16, .02),
+ n.I = safety_design$n.I,
+ a = safety_design$lower$bound,
+ b = safety_design$upper$bound
+)
+safety_power |>
+ as_table() |>
+ lt::lt(
+ theta_label = I("Underlying
AE rate"),
+ prob_decimals = 3,
+ bound_label = c("low rate", "high rate")
+ )
+
+}
+\seealso{
+\code{vignette("binomialSPRTExample")}
+}
diff --git a/tests/testthat/_snaps/independent-test-as_gt.md b/tests/testthat/_snaps/independent-test-as_gt.md
deleted file mode 100644
index a9dfc5d7..00000000
--- a/tests/testthat/_snaps/independent-test-as_gt.md
+++ /dev/null
@@ -1,26 +0,0 @@
-# Snapshot test for gsBinomialExact safety table
-
- \begin{table}[t]
- \caption*{
- {\fontsize{20}{25}\selectfont Operating Characteristics for the Truncated SPRT Design\fontsize{12}{15}\selectfont } \\
- {\fontsize{14}{17}\selectfont Assumes trial evaluated sequentially after each response\fontsize{12}{15}\selectfont }
- }
- \fontsize{12.0pt}{14.0pt}\selectfont
- \begin{tabular*}{\linewidth}{@{\extracolsep{\fill}}rrrr}
- \toprule
- & \multicolumn{2}{c}{{Probability of crossing}} & \\
- \cmidrule(lr){2-3}
- Underlying
AE rate & low rate & high rate & Average
sample size \\
- \midrule\addlinespace[2.5pt]
- 2\% & 0.964 & 0.001 & 34.8 \\
- 4\% & 0.769 & 0.019 & 46.4 \\
- 6\% & 0.506 & 0.108 & 54.3 \\
- 8\% & 0.291 & 0.290 & 56.1 \\
- 10\% & 0.155 & 0.516 & 52.8 \\
- 12\% & 0.079 & 0.714 & 46.8 \\
- 14\% & 0.039 & 0.851 & 40.2 \\
- 16\% & 0.020 & 0.930 & 34.2 \\
- \bottomrule
- \end{tabular*}
- \end{table}
-
diff --git a/tests/testthat/test-independent-test-as_gt.R b/tests/testthat/test-independent-test-as_gt.R
deleted file mode 100644
index 0aa53165..00000000
--- a/tests/testthat/test-independent-test-as_gt.R
+++ /dev/null
@@ -1,76 +0,0 @@
-test_that("Snapshot test for gsBinomialExact safety table", {
- skip_on_cran()
-
- gt_to_latex <- function(data) cat(as.character(gt::as_latex(data)))
-
- safety_design <- binomialSPRT(p0 = 0.04, p1 = 0.1, alpha = 0.04, beta = 0.2, minn = 4, maxn = 75)
- safety_power <- gsBinomialExact(
- k = length(safety_design$n.I),
- theta = seq(0.02, 0.16, 0.02),
- n.I = safety_design$n.I,
- a = safety_design$lower$bound,
- b = safety_design$upper$bound
- )
- output <- safety_power |>
- as_table() |>
- as_gt(
- theta_label = gt::html("Underlying
AE rate"),
- prob_decimals = 3,
- bound_label = c("low rate", "high rate")
- )
-
- expect_s3_class(output, "gt_tbl")
-
- local_edition(3)
- expect_snapshot_output(gt_to_latex(output))
-})
-
-test_that("Number of set decimals for `Probability of crossing` are respected", {
- safety_design <- binomialSPRT(p0 = 0.04, p1 = 0.1, alpha = 0.04, beta = 0.2, minn = 4, maxn = 75)
- safety_power <- gsBinomialExact(
- k = length(safety_design$n.I),
- theta = seq(0.02, 0.16, 0.02),
- n.I = safety_design$n.I,
- a = safety_design$lower$bound,
- b = safety_design$upper$bound
- )
- output <- safety_power |>
- as_table() |>
- as_gt(
- theta_label = gt::html("Underlying
AE rate"),
- prob_decimals = 3,
- bound_label = c("low rate", "high rate")
- )
-
- # Get formats where columns include "Lower" or "Upper"
- prob_format <- Filter(function(x) any(x$columns %in% c("Lower", "Upper")), output[["_formats"]])
-
- # Get formats where columns include "theta"
- rr_format <- Filter(function(x) any(x$columns == "theta"), output[["_formats"]])
-
- expect_true(all(sapply(prob_format, function(x) x$decimals == 3)))
- expect_true(all(sapply(rr_format, function(x) x$decimals == 1)))
-})
-
-test_that("We can set custom title and subtitles", {
- safety_design <- binomialSPRT(p0 = 0.04, p1 = 0.1, alpha = 0.04, beta = 0.2, minn = 4, maxn = 75)
- safety_power <- gsBinomialExact(
- k = length(safety_design$n.I),
- theta = seq(0.02, 0.16, 0.02),
- n.I = safety_design$n.I,
- a = safety_design$lower$bound,
- b = safety_design$upper$bound
- )
- output <- safety_power |>
- as_table() |>
- as_gt(
- title = "Custom Title",
- subtitle = "Custom Subtitle",
- theta_label = gt::html("Underlying
AE rate"),
- prob_decimals = 3,
- bound_label = c("low rate", "high rate")
- )
-
- expect_equal(output[["_heading"]]$title, "Custom Title")
- expect_equal(output[["_heading"]]$subtitle, "Custom Subtitle")
-})
diff --git a/tests/testthat/test-independent-test-lt.R b/tests/testthat/test-independent-test-lt.R
new file mode 100644
index 00000000..862fe255
--- /dev/null
+++ b/tests/testthat/test-independent-test-lt.R
@@ -0,0 +1,48 @@
+safety_lt <- function(...) {
+ safety_design <- binomialSPRT(p0 = 0.04, p1 = 0.1, alpha = 0.04, beta = 0.2, minn = 4, maxn = 75)
+ safety_power <- gsBinomialExact(
+ k = length(safety_design$n.I),
+ theta = seq(0.02, 0.16, 0.02),
+ n.I = safety_design$n.I,
+ a = safety_design$lower$bound,
+ b = safety_design$upper$bound
+ )
+ safety_power |>
+ as_table() |>
+ lt::lt(...)
+}
+
+# Number formatting operations recorded on an lt_tbl for the given columns.
+fmt_for <- function(x, cols) {
+ Filter(
+ function(op) op$type == "fmt_number" && any(op$columns %in% cols),
+ x$ops
+ )
+}
+
+test_that("Number of set decimals for `Probability of crossing` are respected", {
+ output <- safety_lt(
+ theta_label = I("Underlying
AE rate"),
+ prob_decimals = 3,
+ bound_label = c("low rate", "high rate")
+ )
+
+ prob_format <- fmt_for(output, c("Lower", "Upper"))
+ rr_format <- fmt_for(output, "theta")
+
+ expect_true(all(vapply(prob_format, function(x) x$decimals == 3, logical(1))))
+ expect_true(all(vapply(rr_format, function(x) x$decimals == 0, logical(1))))
+})
+
+test_that("We can set custom title and subtitles", {
+ output <- safety_lt(
+ title = "Custom Title",
+ subtitle = "Custom Subtitle",
+ theta_label = I("Underlying
AE rate"),
+ prob_decimals = 3,
+ bound_label = c("low rate", "high rate")
+ )
+
+ expect_equal(output$header$title, "Custom Title")
+ expect_equal(output$header$subtitle, "Custom Subtitle")
+})
diff --git a/vignettes/ConditionalErrorSpending.Rmd b/vignettes/ConditionalErrorSpending.Rmd
index eef6875b..65b20a43 100755
--- a/vignettes/ConditionalErrorSpending.Rmd
+++ b/vignettes/ConditionalErrorSpending.Rmd
@@ -1,6 +1,8 @@
---
title: "Conditional error spending functions"
-output: rmarkdown::html_vignette
+output:
+ rmarkdown::html_vignette:
+ css: vignette.css
bibliography: gsDesign.bib
vignette: >
%\VignetteIndexEntry{Conditional error spending functions}
@@ -53,7 +55,7 @@ We also compare results to other commonly used spending functions.
library(gsDesign)
library(tibble)
library(dplyr)
-library(gt)
+library(lt)
```
### Method 1
@@ -247,21 +249,22 @@ xx <- rbind(
transpose_df(ce(x1.8)) |> mutate(gamma = "gamma = 0.8")
)
xx |>
- gt(groupname_col = "gamma") |>
- tab_spanner(label = "Analysis", columns = 2:5) |>
- fmt_number(columns = 2:5, decimals = 3) |>
- tab_options(data_row.padding = px(1)) |>
- tab_header(
+ lt() |>
+ lt_group(~ gamma, sep = TRUE, sort = FALSE) |>
+ lt_spanner(label = "Analysis", columns = 2:5) |>
+ lt_format(columns = 2:5, decimals = 3) |>
+ lt_label(rowname = "") |>
+ lt_header(
title = "Xi-Gallo, Method 1 Spending Function",
subtitle = "Conditional Error Spending Functions"
) |>
- tab_footnote(
- footnote = "Conditional Error not accounting for future interim bounds.",
- locations = cells_stub(rows = seq(2, 20, 3))
+ lt_footnote(
+ "Conditional Error not accounting for future interim bounds.",
+ where = "body", columns = "rowname", rows = seq(2, 20, 3)
) |>
- tab_footnote(
- footnote = "CE = Conditional Error accounting for all analyses.",
- locations = cells_stub(rows = seq(3, 21, 3))
+ lt_footnote(
+ "CE = Conditional Error accounting for all analyses.",
+ where = "body", columns = "rowname", rows = seq(3, 21, 3)
)
```
@@ -288,19 +291,20 @@ xx <- rbind(
transpose_df(ce(x1.8)) |> mutate(gamma = "gamma = 0.8")
)
xx |>
- gt(groupname_col = "gamma") |>
- tab_spanner(label = "Analysis", columns = 2:5) |>
- fmt_number(columns = 2:5, decimals = 3) |>
- tab_options(data_row.padding = px(1)) |>
- tab_footnote(
- footnote = "Conditional Error not accounting for future interim bounds.",
- locations = cells_stub(rows = seq(2, 20, 3))
+ lt() |>
+ lt_group(~ gamma, sep = TRUE, sort = FALSE) |>
+ lt_spanner(label = "Analysis", columns = 2:5) |>
+ lt_format(columns = 2:5, decimals = 3) |>
+ lt_label(rowname = "") |>
+ lt_footnote(
+ "Conditional Error not accounting for future interim bounds.",
+ where = "body", columns = "rowname", rows = seq(2, 20, 3)
) |>
- tab_footnote(
- footnote = "CE = Conditional Error accounting for all analyses.",
- locations = cells_stub(rows = seq(3, 21, 3))
+ lt_footnote(
+ "CE = Conditional Error accounting for all analyses.",
+ where = "body", columns = "rowname", rows = seq(3, 21, 3)
) |>
- tab_header(
+ lt_header(
title = "Xi-Gallo, Method 2 Spending Function",
subtitle = "Conditional Error Spending Functions"
)
@@ -353,19 +357,20 @@ xx <- rbind(
transpose_df(ce(x3.05)) |> mutate(gamma = "gamma = 0.05 ")
)
xx |>
- gt(groupname_col = "gamma") |>
- tab_spanner(label = "Analysis", columns = 2:5) |>
- fmt_number(columns = 2:5, decimals = 3) |>
- tab_options(data_row.padding = px(1)) |>
- tab_footnote(
- footnote = "Conditional Error not accounting for future interim bounds.",
- locations = cells_stub(rows = seq(2, 11, 3))
+ lt() |>
+ lt_group(~ gamma, sep = TRUE, sort = FALSE) |>
+ lt_spanner(label = "Analysis", columns = 2:5) |>
+ lt_format(columns = 2:5, decimals = 3) |>
+ lt_label(rowname = "") |>
+ lt_footnote(
+ "Conditional Error not accounting for future interim bounds.",
+ where = "body", columns = "rowname", rows = seq(2, 11, 3)
) |>
- tab_footnote(
- footnote = "CE = Conditional Error accounting for all analyses.",
- locations = cells_stub(rows = seq(3, 12, 3))
+ lt_footnote(
+ "CE = Conditional Error accounting for all analyses.",
+ where = "body", columns = "rowname", rows = seq(3, 12, 3)
) |>
- tab_header(
+ lt_header(
title = "Xi-Gallo, Method 3 Spending Function",
subtitle = "Conditional Error Spending Functions"
)
diff --git a/vignettes/MultiSeasonRareEvents.Rmd b/vignettes/MultiSeasonRareEvents.Rmd
index 2e05ea04..897a0ce2 100644
--- a/vignettes/MultiSeasonRareEvents.Rmd
+++ b/vignettes/MultiSeasonRareEvents.Rmd
@@ -1,6 +1,8 @@
---
title: "Multi-season studies for rare events"
-output: rmarkdown::html_vignette
+output:
+ rmarkdown::html_vignette:
+ css: vignette.css
bibliography: gsDesign.bib
vignette: >
%\VignetteIndexEntry{Multi-season studies for rare events}
@@ -25,7 +27,7 @@ options(width = 58)
```{r, message=FALSE, warning=FALSE}
library(gsDesign)
-library(gt)
+library(lt)
library(tibble)
```
@@ -249,46 +251,46 @@ tibble(
`Achieved cumulative alpha spend` = achieved_alpha_spend,
`Cumulative power under H1` = achieved_power_h1
) |>
- gt() |>
- fmt_number(columns = 2, decimals = 3) |>
- fmt_percent(columns = c(`VE at bound (efficacy)`, `VE at bound (futility)`), decimals = 1) |>
- fmt_number(
+ lt() |>
+ lt_format(columns = 2, decimals = 3) |>
+ lt_format(columns = c("VE at bound (efficacy)", "VE at bound (futility)"), decimals = 1, percent = TRUE) |>
+ lt_format(
columns = c(
- `Nominal 1-sided p at bound (efficacy)`,
- `Nominal 1-sided p at bound (futility)`,
- `Target cumulative alpha spend`,
- `Achieved cumulative alpha spend`,
- `Cumulative power under H1`
+ "Nominal 1-sided p at bound (efficacy)",
+ "Nominal 1-sided p at bound (futility)",
+ "Target cumulative alpha spend",
+ "Achieved cumulative alpha spend",
+ "Cumulative power under H1"
),
decimals = 4
) |>
- tab_spanner(
+ lt_spanner(
label = "Efficacy",
columns = c(
- `Exact efficacy bound (x <= a)`,
- `VE at bound (efficacy)`,
- `Nominal 1-sided p at bound (efficacy)`
+ "Exact efficacy bound (x <= a)",
+ "VE at bound (efficacy)",
+ "Nominal 1-sided p at bound (efficacy)"
)
) |>
- tab_spanner(
+ lt_spanner(
label = "Futility",
columns = c(
- `Exact futility bound (x >= b)`,
- `VE at bound (futility)`,
- `Nominal 1-sided p at bound (futility)`
+ "Exact futility bound (x >= b)",
+ "VE at bound (futility)",
+ "Nominal 1-sided p at bound (futility)"
)
) |>
- tab_header(
+ lt_header(
title = "Planned exact binomial seasonal monitoring",
subtitle = "Super-superiority example with Pocock-like efficacy spending"
) |>
- tab_footnote(
- footnote = "x denotes cumulative observed events in the experimental arm; efficacy is established when x is at or below the listed efficacy bound.",
- locations = cells_column_labels(columns = `Exact efficacy bound (x <= a)`)
+ lt_footnote(
+ "x denotes cumulative observed events in the experimental arm; efficacy is established when x is at or below the listed efficacy bound.",
+ where = "column", columns = "Exact efficacy bound (x <= a)"
) |>
- tab_footnote(
- footnote = "Blank futility entries indicate no futility stopping boundary at that analysis.",
- locations = cells_column_labels(columns = `Exact futility bound (x >= b)`)
+ lt_footnote(
+ "Blank futility entries indicate no futility stopping boundary at that analysis.",
+ where = "column", columns = "Exact futility bound (x >= b)"
)
```
@@ -315,8 +317,8 @@ dplyr::bind_rows(
`Cumulative planned enrollment` = sum(enrollment_table$`Total planned enrollment`)
)
) |>
- gt() |>
- tab_header(title = "Planned enrollment by season and overall")
+ lt() |>
+ lt_header(title = "Planned enrollment by season and overall")
```
## Example repeated and sequential p-values
@@ -390,8 +392,8 @@ tibble(
`Updated futility bound, default spending` = update_exact$upper$bound,
`Updated futility bound, maxSpend=TRUE` = update_exact_full$upper$bound
) |>
- gt() |>
- tab_header(title = "Updated exact bounds using observedEvents")
+ lt() |>
+ lt_header(title = "Updated exact bounds using observedEvents")
```
## Lightweight runnable simulation
@@ -439,16 +441,16 @@ oc <- sim_light$summary |>
)
oc |>
- gt() |>
- fmt_number(columns = 2:5, decimals = 4) |>
- fmt_number(columns = 6:8, decimals = 2) |>
- tab_header(
+ lt() |>
+ lt_format(columns = 2:5, decimals = 4) |>
+ lt_format(columns = 6:8, decimals = 2) |>
+ lt_header(
title = "Lightweight simulation results",
subtitle = "Exact-binomial monitoring with seasonal analyses"
) |>
- tab_footnote(
- footnote = "For VE=30% scenarios, efficacy crossing probability is Type I error under the non-binding futility convention (futility crossings do not block later efficacy crossings).",
- locations = cells_column_labels(columns = `Efficacy crossing probability`)
+ lt_footnote(
+ "For VE=30% scenarios, efficacy crossing probability is Type I error under the non-binding futility convention (futility crossings do not block later efficacy crossings).",
+ where = "column", columns = "Efficacy crossing probability"
)
```
@@ -516,16 +518,16 @@ tibble(
low$mean_looks[low$adaptive & low$scenario == "H1 (VE=80%)"]
)
) |>
- gt() |>
- fmt_number(columns = 2:3, decimals = 4) |>
- fmt_number(columns = 4:6, decimals = 2) |>
- tab_header(
+ lt() |>
+ lt_format(columns = 2:3, decimals = 4) |>
+ lt_format(columns = 4:6, decimals = 2) |>
+ lt_header(
title = "Lower-than-planned event rate illustration",
subtitle = "Adaptive approach increases enrollment to recover information"
) |>
- tab_footnote(
- footnote = "Type I error rows use non-binding futility for efficacy crossing probability; futility stopping probability is shown separately.",
- locations = cells_column_labels(columns = `Efficacy crossing probability`)
+ lt_footnote(
+ "Type I error rows use non-binding futility for efficacy crossing probability; futility stopping probability is shown separately.",
+ where = "column", columns = "Efficacy crossing probability"
)
```
diff --git a/vignettes/PoissonMixtureModel.Rmd b/vignettes/PoissonMixtureModel.Rmd
index d3c3e926..f1f39f02 100644
--- a/vignettes/PoissonMixtureModel.Rmd
+++ b/vignettes/PoissonMixtureModel.Rmd
@@ -1,6 +1,8 @@
---
title: "A cure model calendar-based design"
-output: rmarkdown::html_vignette
+output:
+ rmarkdown::html_vignette:
+ css: vignette.css
bibliography: gsDesign.bib
vignette: >
%\VignetteIndexEntry{A cure model calendar-based design}
@@ -26,7 +28,7 @@ library(gsDesign)
library(dplyr)
library(tibble)
library(ggplot2)
-library(gt)
+library(lt)
```
## Introduction
@@ -335,8 +337,8 @@ design_calendar <-
)
design_calendar |>
gsBoundSummary(exclude = c("B-value", "CP", "CP H1", "PP")) |>
- gt() |>
- tab_header(
+ lt() |>
+ lt_header(
title = "Calendar-Based Design",
subtitle = "Calendar Spending"
)
diff --git a/vignettes/VaccineEfficacy.Rmd b/vignettes/VaccineEfficacy.Rmd
index beb7ae99..df81ffa4 100644
--- a/vignettes/VaccineEfficacy.Rmd
+++ b/vignettes/VaccineEfficacy.Rmd
@@ -1,6 +1,8 @@
---
title: "Vaccine efficacy trial design"
-output: rmarkdown::html_vignette
+output:
+ rmarkdown::html_vignette:
+ css: vignette.css
bibliography: gsDesign.bib
vignette: >
%\VignetteIndexEntry{Vaccine efficacy trial design}
@@ -25,7 +27,7 @@ options(width = 58)
```{r, message=FALSE, warning=FALSE}
library(gsDesign)
-library(gt)
+library(lt)
```
## Introduction
@@ -95,9 +97,8 @@ We also translate several vaccine efficacy values to proportion of events in the
ve <- c(.5, .6, .65, .7, .75, .8)
prob_experimental <- ratio / (ratio + 1 / (1 - ve))
tibble::tibble(VE = ve, "P(Experimental)" = prob_experimental) |>
- gt() |>
- tab_options(data_row.padding = px(1)) |>
- fmt_number(columns = 2, decimals = 3)
+ lt() |>
+ lt_format(columns = 2, decimals = 3)
```
@@ -178,12 +179,11 @@ gsBoundSummary(xx,
tdigits = 1, logdelta = TRUE, deltaname = "HR", Nname = "Events",
exclude = c("B-value", "CP", "CP H1", "PP")
) |>
- gt() |>
- tab_header(
+ lt() |>
+ lt_header(
title = "Initial group sequential approximation",
subtitle = "Integer event counts at analyses"
- ) |>
- tab_options(data_row.padding = px(1))
+ )
```
A textual summary for the design is:
@@ -247,39 +247,39 @@ veTable <- function(xbDesign, tteDesign, ve) {
```{r, echo=FALSE}
veTable(xb, x, ve) |>
- gt() |>
- fmt_number(columns = 2, decimals = 1) |>
- fmt_number(columns = c(7:8, 11:16), decimals = 2) |>
- fmt_number(columns = 9:10, decimals = 4) |>
- tab_spanner(label = "Experimental Cases at Bound", columns = 5:6, id = "cases") |>
- tab_spanner(label = "Power by Vaccine Efficacy", columns = 11:16, id = "power") |>
- tab_spanner(label = "Error Spending", columns = 9:10, id = "spend") |>
- tab_spanner(label = "Vaccine Efficacy at Bound", columns = 7:8, id = "vebound") |>
- cols_label(
+ lt() |>
+ lt_format(columns = 2, decimals = 1) |>
+ lt_format(columns = c(7:8, 11:16), decimals = 2) |>
+ lt_format(columns = 9:10, decimals = 4) |>
+ lt_spanner(label = "Experimental Cases at Bound", columns = c("Success", "Futility")) |>
+ lt_spanner(label = "Power by Vaccine Efficacy", columns = paste0(ve * 100, "%")) |>
+ lt_spanner(label = "Error Spending", columns = c("alpha", "beta")) |>
+ lt_spanner(label = "Vaccine Efficacy at Bound", columns = c("ve_efficacy", "ve_futility")) |>
+ lt_label(
ve_efficacy = "Efficacy",
ve_futility = "Futility"
) |>
- tab_footnote(
- footnote = "Cumulative spending at each analysis",
- locations = cells_column_spanners(spanners = "spend")
+ lt_footnote(
+ "Cumulative spending at each analysis",
+ where = "spanner", columns = "Error Spending"
) |>
- tab_footnote(
- footnote = "Experimental case counts to cross between success and futility counts do not stop trial",
- locations = cells_column_spanners(spanners = "cases")
+ lt_footnote(
+ "Experimental case counts to cross between success and futility counts do not stop trial",
+ where = "spanner", columns = "Experimental Cases at Bound"
) |>
- tab_footnote(
- footnote = "Exact vaccine efficacy required to cross bound",
- locations = cells_column_spanners(spanners = "vebound")
+ lt_footnote(
+ "Exact vaccine efficacy required to cross bound",
+ where = "spanner", columns = "Vaccine Efficacy at Bound"
) |>
- tab_footnote(
- footnote = "Cumulative power at each analysis by underlying vaccine efficacy",
- locations = cells_column_spanners(spanners = "power")
+ lt_footnote(
+ "Cumulative power at each analysis by underlying vaccine efficacy",
+ where = "spanner", columns = "Power by Vaccine Efficacy"
) |>
- tab_footnote(
- footnote = "alpha-spending for efficacy ignores non-binding futility bound",
- location = cells_column_labels(columns = alpha)
+ lt_footnote(
+ "alpha-spending for efficacy ignores non-binding futility bound",
+ where = "column", columns = "alpha"
) |>
- tab_header("Design Bounds and Operating Characteristics")
+ lt_header("Design Bounds and Operating Characteristics")
```
The initial approximation of bounds for the exact binomial design was generated from the time-to-event design as follows.
First, we computed nominal p-value 1-sided bounds under the null hypothesis for the efficacy bounds using the normal approximation that the time-to-event design used:
@@ -423,38 +423,38 @@ We hide the code to produce the table; this is available in package vignette cod
beta = as.vector(cumsum(ebUpdate$upper$prob[, 2]))
)
out_tab <- cbind(out_tab, power_table)
- out_tab |> gt() |>
- fmt_number(columns = c(5:6, 9:11), decimals = 2) |>
- fmt_number(columns = 7:8, decimals = 4) |>
- tab_spanner(label = "Cases at Bound", columns = 3:4, id = "cases") |>
- tab_spanner(label = "Power by VE", columns = 9:11, id = "power") |>
- tab_spanner(label = "Error Spending", columns = 7:8, id = "spend") |>
- tab_spanner(label = "VE at Bound", columns = 5:6, id = "vebound") |>
- cols_label(
+ out_tab |> lt() |>
+ lt_format(columns = c(5:6, 9:11), decimals = 2) |>
+ lt_format(columns = 7:8, decimals = 4) |>
+ lt_spanner(label = "Cases at Bound", columns = c("Success", "Futility")) |>
+ lt_spanner(label = "Power by VE", columns = paste0(ve * 100, "%")) |>
+ lt_spanner(label = "Error Spending", columns = c("alpha", "beta")) |>
+ lt_spanner(label = "VE at Bound", columns = c("ve_efficacy", "ve_futility")) |>
+ lt_label(
ve_efficacy = "Efficacy",
ve_futility = "Futility"
) |>
- tab_footnote(
- footnote = "Cumulative spending at each analysis",
- locations = cells_column_spanners(spanners = "spend")
+ lt_footnote(
+ "Cumulative spending at each analysis",
+ where = "spanner", columns = "Error Spending"
) |>
- tab_footnote(
- footnote = "Experimental case counts; counts between success and futility bounds do not stop trial",
- locations = cells_column_spanners(spanners = "cases")
+ lt_footnote(
+ "Experimental case counts; counts between success and futility bounds do not stop trial",
+ where = "spanner", columns = "Cases at Bound"
) |>
- tab_footnote(
- footnote = "Exact vaccine efficacy required to cross bound",
- locations = cells_column_spanners(spanners = "vebound")
+ lt_footnote(
+ "Exact vaccine efficacy required to cross bound",
+ where = "spanner", columns = "VE at Bound"
) |>
- tab_footnote(
- footnote = "Cumulative power at each analysis by underlying vaccine efficacy",
- locations = cells_column_spanners(spanners = "power")
+ lt_footnote(
+ "Cumulative power at each analysis by underlying vaccine efficacy",
+ where = "spanner", columns = "Power by VE"
) |>
- tab_footnote(
- footnote = "Efficacy spending ignores non-binding futility bound",
- location = cells_column_labels(columns = alpha)
+ lt_footnote(
+ "Efficacy spending ignores non-binding futility bound",
+ where = "column", columns = "alpha"
) |>
- tab_header(title = "Updated Bounds for Actual Analyses from SPUTNIK trial")
+ lt_header(title = "Updated Bounds for Actual Analyses from SPUTNIK trial")
```
## Summary
diff --git a/vignettes/binomialSPRTExample.Rmd b/vignettes/binomialSPRTExample.Rmd
index deed99a7..72037d47 100644
--- a/vignettes/binomialSPRTExample.Rmd
+++ b/vignettes/binomialSPRTExample.Rmd
@@ -1,6 +1,8 @@
---
title: "Binomial SPRT"
-output: rmarkdown::html_vignette
+output:
+ rmarkdown::html_vignette:
+ css: vignette.css
bibliography: "gsDesign.bib"
vignette: >
%\VignetteIndexEntry{Binomial SPRT}
@@ -91,7 +93,7 @@ b_power <- gsBinomialExact(
```{r}
b_power |>
as_table() |>
- as_gt()
+ lt::lt()
```
## Safety monitoring example
@@ -131,8 +133,8 @@ safety_power <- gsBinomialExact(
)
safety_power |>
as_table() |>
- as_gt(
- theta_label = gt::html("Underlying
AE rate"),
+ lt::lt(
+ theta_label = I("Underlying
AE rate"),
prob_decimals = 3,
bound_label = c("low rate", "high rate")
)
diff --git a/vignettes/binomialTwoSample.Rmd b/vignettes/binomialTwoSample.Rmd
index 9a87124b..1c284ab8 100644
--- a/vignettes/binomialTwoSample.Rmd
+++ b/vignettes/binomialTwoSample.Rmd
@@ -1,6 +1,8 @@
---
title: "Binomial two arm trial design and analysis"
-output: rmarkdown::html_vignette
+output:
+ rmarkdown::html_vignette:
+ css: vignette.css
bibliography: "gsDesign.bib"
vignette: >
%\VignetteIndexEntry{Binomial two arm trial design and analysis}
@@ -41,7 +43,7 @@ The R packages we use are:
library(gsDesign)
library(ggplot2)
library(tidyr)
-library(gt)
+library(lt)
library(dplyr)
```
@@ -72,8 +74,8 @@ tibble(scale, "Sample size" = c(
nBinomial(p1 = 0.2, p2 = 0.1, ratio = 0.5, alpha = 0.025, beta = 0.15, scale = scale[2]) |> ceiling(),
nBinomial(p1 = 0.2, p2 = 0.1, ratio = 0.5, alpha = 0.025, beta = 0.15, scale = scale[3]) |> ceiling()
)) |>
- gt() |>
- tab_header("Sample size by scale for a superiority design",
+ lt() |>
+ lt_header("Sample size by scale for a superiority design",
subtitle = "alpha = 0.025, beta = 0.15, pE = 0.2, pC = 0.1"
)
```
@@ -131,11 +133,11 @@ rbind(
scale = c("Risk difference", "Risk-ratio", "Odds-ratio"),
Effect = c(rd, rr, orr)
) |>
- gt() |>
- tab_header("Confidence intervals for a binomial effect size",
+ lt() |>
+ lt_header("Confidence intervals for a binomial effect size",
subtitle = "x1 = 20, n1 = 30, x2 = 10, n2 = 30"
) |>
- fmt_number(columns = c(lower, upper, Effect), n_sigfig = 3)
+ lt_format(columns = c("lower", "upper", "Effect"), decimals = 3)
```
Again, how treatment groups are assigned makes a difference.
@@ -166,19 +168,19 @@ tibble(
ceiling(nBinomial(p1 = 0.2, p2 = 0.1, alpha = 0.025, beta = 0.15, ratio = 0.5, delta0 = 0.02))
)
) |>
- gt() |>
- tab_header("Sample size for binomial two arm trial design",
+ lt() |>
+ lt_header("Sample size for binomial two arm trial design",
subtitle = "alpha = 0.025, beta = 0.15"
) |>
- fmt_number(columns = c(`p1 (pE)`, `p2 (pC)`), decimals = 2) |>
- cols_label(
+ lt_format(columns = c("p1 (pE)", "p2 (pC)"), decimals = 2) |>
+ lt_label(
Design = "Design",
`p1 (pE)` = "Experimental group rate",
`p2 (pC)` = "Control group rate",
delta0 = "Null hypothesis value of rate difference (delta0)",
`Sample size` = "Sample size"
) |>
- tab_footnote("Randomization ratio is 2:1 (Experimental:Control) with assumed control failure rate p1 = 0.2 and experimental rate 0.1.")
+ lt_note("Randomization ratio is 2:1 (Experimental:Control) with assumed control failure rate p1 = 0.2 and experimental rate 0.1.")
```
Testing for non-inferiority and super-superiority is equivalent to whether or not the confidence intervals contain the margin `delta0`.
@@ -224,12 +226,12 @@ In any case, this produces a slightly conservative Type I error rate.
```{r}
zcut <- quantile(z, 0.975)
tibble("Z cutoff" = zcut, "p cutoff" = pnorm(zcut, lower.tail = FALSE)) |>
- gt() |>
- fmt_number(columns = c("Z cutoff", "p cutoff"), n_sigfig = 3) |>
- tab_header("Exact cutoff for Type I error rate",
+ lt() |>
+ lt_format(columns = c("Z cutoff", "p cutoff"), decimals = 3) |>
+ lt_header("Exact cutoff for Type I error rate",
subtitle = "Based on 1 million simulations"
) |>
- tab_footnote("The Z cutoff is the quantile of the simulated Z-values at 0.975 using p1 = p2 = 0.15.")
+ lt_note("The Z cutoff is the quantile of the simulated Z-values at 0.975 using p1 = p2 = 0.15.")
```
Now we examine power with the asymptotic and exact cutoffs.
@@ -254,14 +256,14 @@ ptab <- tibble(
)
)
ptab |>
- gt() |>
- tab_header("Simulation power for sample size based on risk-difference and odds-ratio",
+ lt() |>
+ lt_header("Simulation power for sample size based on risk-difference and odds-ratio",
subtitle = "pE = 0.2, pC = 0.1, alpha = 0.025, beta = 0.15"
) |>
- fmt_number(columns = c(n, Power), n_sigfig = 3) |>
- cols_label(Scale = "Scale", n = "Sample size", Power = "Power") |>
- tab_footnote("Power based on 100,000 simulated trials and nominal alpha = 0.025 test; 2 x simulation error = 0.002") |>
- tab_footnote("Power based on Z-test for risk-difference with no continuity correction.", location = cells_column_labels("Power"))
+ lt_format(columns = c("n", "Power"), decimals = 3) |>
+ lt_label(Scale = "Scale", n = "Sample size", Power = "Power") |>
+ lt_footnote("Power based on Z-test for risk-difference with no continuity correction.", where = "column", columns = "Power") |>
+ lt_note("Power based on 100,000 simulated trials and nominal alpha = 0.025 test; 2 x simulation error = 0.002")
```
## Power table
@@ -280,9 +282,9 @@ binomialPowerTable(
ratio = 1, alpha = 0.025, simulation = TRUE, nsim = 1e6, adj = 0
) |>
rename("Type I error" = "Power") |>
- gt() |>
- fmt_number(columns = "Type I error", n_sigfig = 3) |>
- tab_header("Type I error is not controlled with nominal p = 0.025 cutoff")
+ lt() |>
+ lt_format(columns = "Type I error", decimals = 3) |>
+ lt_header("Type I error is not controlled with nominal p = 0.025 cutoff")
```
Adding the continuity correction (`adj = 1`) helps a small amount at better controlling Type I error in this case.
@@ -295,9 +297,9 @@ binomialPowerTable(
ratio = 1, alpha = 0.023, simulation = TRUE, nsim = 1e6, adj = 0
) |>
rename("Type I error" = "Power") |>
- gt() |>
- fmt_number(columns = "Type I error", n_sigfig = 3) |>
- tab_header("Type I error is controlled at 0.025 with nominal p = 0.023 cutoff")
+ lt() |>
+ lt_format(columns = "Type I error", decimals = 3) |>
+ lt_header("Type I error is controlled at 0.025 with nominal p = 0.023 cutoff")
```
Now we look at power for a range of control rates and treatment effects.
@@ -367,13 +369,13 @@ power_table_simulation |>
values_from = Power
) |>
dplyr::rename(`Control group rate` = pC) |>
- gt::gt() |>
- gt::tab_spanner(
+ lt::lt() |>
+ lt::lt_spanner(
label = "Treatment effect (delta)",
columns = 2:7
) |>
- gt::fmt_percent(decimals = 1) |>
- gt::tab_header("Power by Control Group Rate and Treatment Effect")
+ lt::lt_format(columns = 1:7, decimals = 1, percent = TRUE) |>
+ lt::lt_header("Power by Control Group Rate and Treatment Effect")
```
## Summary
diff --git a/vignettes/gsSurvBasicExamples.Rmd b/vignettes/gsSurvBasicExamples.Rmd
index f0b841f9..9dad6b0f 100644
--- a/vignettes/gsSurvBasicExamples.Rmd
+++ b/vignettes/gsSurvBasicExamples.Rmd
@@ -1,6 +1,8 @@
---
title: "Basic time-to-event group sequential design using gsSurv"
-output: rmarkdown::html_vignette
+output:
+ rmarkdown::html_vignette:
+ css: vignette.css
bibliography: gsDesign.bib
vignette: >
%\VignetteIndexEntry{Basic time-to-event group sequential design using gsSurv}
@@ -204,15 +206,15 @@ An important addition not provided above is that the median time-to-event is ass
Following are the enrollment rates required to power the trial.
```{r, warning=FALSE}
-library(gt)
+library(lt)
library(tibble)
tibble(
Period = paste("Month", rownames(x$gamma)),
Rate = as.numeric(x$gamma)
) |>
- gt() |>
- tab_header(title = "Enrollment rate requirements")
+ lt() |>
+ lt_header(title = "Enrollment rate requirements")
```
Next we provide a tabular summary of bounds for the design.
@@ -246,15 +248,15 @@ caption <- paste(
```{r, echo=TRUE, message=FALSE}
gsBoundSummary(x) |>
- gt() |>
- tab_header(title = "Time-to-event group sequential design") |>
- cols_align("left") |>
- tab_footnote(footnoteUS, locations = cells_column_labels(columns = 3)) |>
- tab_footnote(footnoteLS, locations = cells_column_labels(columns = 4)) |>
- tab_footnote(footnoteHR, locations = cells_body(columns = 2, rows = c(3, 8, 13))) |>
- tab_footnote(footnoteM, locations = cells_body(columns = 1, rows = c(4, 9, 14))) |>
- tab_footnote(footnote1, locations = cells_body(columns = 2, rows = c(4, 5, 9, 10, 14, 15))) |>
- tab_footnote(footnote2, locations = cells_body(columns = 2, rows = c(4, 9, 14)))
+ lt() |>
+ lt_header(title = "Time-to-event group sequential design") |>
+ lt_align(columns = c("Analysis", "Value", "Efficacy", "Futility"), align = "left") |>
+ lt_footnote(footnoteUS, where = "column", columns = "Efficacy") |>
+ lt_footnote(footnoteLS, where = "column", columns = "Futility") |>
+ lt_footnote(footnoteHR, where = "body", columns = "Value", rows = c(3, 8, 13)) |>
+ lt_footnote(footnoteM, where = "body", columns = "Analysis", rows = c(4, 9, 14)) |>
+ lt_footnote(footnote1, where = "body", columns = "Value", rows = c(4, 5, 9, 10, 14, 15)) |>
+ lt_footnote(footnote2, where = "body", columns = "Value", rows = c(4, 9, 14))
```
### Summary plots
@@ -317,23 +319,23 @@ gsBoundSummary(
"PP", "P(Cross) if HR=1", "P(Cross) if HR=0.75"
)
) |>
- gt() |>
- cols_align("left") |>
- tab_header(
+ lt() |>
+ lt_align(columns = c("Analysis", "Value", "Efficacy", "Futility"), align = "left") |>
+ lt_header(
title = "Time-to-event group sequential bound guidance",
subtitle = "Bounds updated based on event counts through IA2"
) |>
- tab_footnote(
+ lt_footnote(
"Nominal p-value required to establish statistical significance.",
- locations = cells_body(columns = 3, rows = c(2, 5, 8))
+ where = "body", columns = "Efficacy", rows = c(2, 5, 8)
) |>
- tab_footnote(
+ lt_footnote(
"Interim futility guidance based on observed HR is non-binding.",
- locations = cells_body(columns = 4, rows = c(3, 6))
+ where = "body", columns = "Futility", rows = c(3, 6)
) |>
- tab_footnote(
+ lt_footnote(
"HR bounds are approximations; decisions on crossing are based solely on p-values.",
- locations = cells_body(column = 2, rows = c(3, 6, 9))
+ where = "body", columns = "Value", rows = c(3, 6, 9)
)
```
diff --git a/vignettes/vignette.css b/vignettes/vignette.css
new file mode 100644
index 00000000..232206e6
--- /dev/null
+++ b/vignettes/vignette.css
@@ -0,0 +1,20 @@
+body {
+ font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size: 14px;
+ line-height: 1.35;
+ max-width: 700px;
+ margin: 1.5em auto;
+ padding: 0 1em;
+}
+pre, code {
+ background-color: #f7f7f7;
+ border-radius: 3px;
+ font-size: 90%;
+}
+pre {
+ padding: 10px;
+ white-space: pre-wrap;
+}
+.lt-table {
+ min-width: 70%;
+}