Title: | Group Sequential Design with Non-Constant Effect |
---|---|
Description: | The goal of 'gsDesign2' is to enable fixed or group sequential design under non-proportional hazards. To enable highly flexible enrollment, time-to-event and time-to-dropout assumptions, 'gsDesign2' offers piecewise constant enrollment, failure rates, and dropout rates for a stratified population. This package includes three methods for designs: average hazard ratio, weighted logrank tests in Yung and Liu (2019) <doi:10.1111/biom.13196>, and MaxCombo tests. Substantial flexibility on top of what is in the 'gsDesign' package is intended for selecting boundaries. |
Authors: | Keaven Anderson [aut], Yilong Zhang [aut], Yujie Zhao [aut, cre], Jianxiao Yang [aut], Nan Xiao [aut], Amin Shirazi [ctb], Ruixue Wang [ctb], Yi Cui [ctb], Ping Yang [ctb], Xin Tong Li [ctb], Chenxiang Li [ctb], Hiroaki Fukuda [ctb], Hongtao Zhang [ctb], Yalin Zhu [ctb], John Blischak [ctb], Dickson Wanjau [ctb], Merck & Co., Inc., Rahway, NJ, USA and its affiliates [cph] |
Maintainer: | Yujie Zhao <[email protected]> |
License: | GPL-3 |
Version: | 1.1.3 |
Built: | 2024-11-15 21:21:38 UTC |
Source: | https://github.com/merck/gsdesign2 |
Provides a geometric average hazard ratio under various non-proportional hazards assumptions for either single or multiple strata studies. The piecewise exponential distribution allows a simple method to specify a distribution and enrollment pattern where the enrollment, failure and dropout rates changes over time.
ahr( enroll_rate = define_enroll_rate(duration = c(2, 2, 10), rate = c(3, 6, 9)), fail_rate = define_fail_rate(duration = c(3, 100), fail_rate = log(2)/c(9, 18), hr = c(0.9, 0.6), dropout_rate = 0.001), total_duration = 30, ratio = 1 )
ahr( enroll_rate = define_enroll_rate(duration = c(2, 2, 10), rate = c(3, 6, 9)), fail_rate = define_fail_rate(duration = c(3, 100), fail_rate = log(2)/c(9, 18), hr = c(0.9, 0.6), dropout_rate = 0.001), total_duration = 30, ratio = 1 )
enroll_rate |
An |
fail_rate |
A |
total_duration |
Total follow-up from start of enrollment to data cutoff; this can be a single value or a vector of positive numbers. |
ratio |
Ratio of experimental to control randomization. |
A data frame with time
(from total_duration
),
ahr
(average hazard ratio), n
(sample size), event
(expected number of events),
info
(information under given scenarios), and
info0
(information under related null hypothesis) for each value of
total_duration
input.
The contents of this section are shown in PDF user manual only.
# Example 1: default ahr() # Example 2: default with multiple analysis times (varying total_duration) ahr(total_duration = c(15, 30)) # Example 3: stratified population enroll_rate <- define_enroll_rate( stratum = c(rep("Low", 2), rep("High", 3)), duration = c(2, 10, 4, 4, 8), rate = c(5, 10, 0, 3, 6) ) fail_rate <- define_fail_rate( stratum = c(rep("Low", 2), rep("High", 2)), duration = c(1, Inf, 1, Inf), fail_rate = c(.1, .2, .3, .4), dropout_rate = .001, hr = c(.9, .75, .8, .6) ) ahr(enroll_rate = enroll_rate, fail_rate = fail_rate, total_duration = c(15, 30))
# Example 1: default ahr() # Example 2: default with multiple analysis times (varying total_duration) ahr(total_duration = c(15, 30)) # Example 3: stratified population enroll_rate <- define_enroll_rate( stratum = c(rep("Low", 2), rep("High", 3)), duration = c(2, 10, 4, 4, 8), rate = c(5, 10, 0, 3, 6) ) fail_rate <- define_fail_rate( stratum = c(rep("Low", 2), rep("High", 2)), duration = c(1, Inf, 1, Inf), fail_rate = c(.1, .2, .3, .4), dropout_rate = .001, hr = c(.9, .75, .8, .6) ) ahr(enroll_rate = enroll_rate, fail_rate = fail_rate, total_duration = c(15, 30))
Based on blinded data and assumed hazard ratios in different intervals, compute a blinded estimate of average hazard ratio (AHR) and corresponding estimate of statistical information. This function is intended for use in computing futility bounds based on spending assuming the input hazard ratio (hr) values for intervals specified here.
ahr_blinded( surv = survival::Surv(time = simtrial::ex1_delayed_effect$month, event = simtrial::ex1_delayed_effect$evntd), intervals = c(3, Inf), hr = c(1, 0.6), ratio = 1 )
ahr_blinded( surv = survival::Surv(time = simtrial::ex1_delayed_effect$month, event = simtrial::ex1_delayed_effect$evntd), intervals = c(3, Inf), hr = c(1, 0.6), ratio = 1 )
surv |
Input survival object (see |
intervals |
Vector containing positive values indicating interval lengths where the exponential rates are assumed. Note that a final infinite interval is added if any events occur after the final interval specified. |
hr |
Vector of hazard ratios assumed for each interval. |
ratio |
Ratio of experimental to control randomization. |
A tibble
with one row containing
ahr
- Blinded average hazard ratio based on assumed period-specific
hazard ratios input in fail_rate
and observed events in the
corresponding intervals.
event
- Total observed number of events.
info0
- Information under related null hypothesis.
theta
- Natural parameter for group sequential design representing
expected incremental drift at all analyses.
The contents of this section are shown in PDF user manual only.
ahr_blinded( surv = survival::Surv( time = simtrial::ex2_delayed_effect$month, event = simtrial::ex2_delayed_effect$evntd ), intervals = c(4, 100), hr = c(1, .55), ratio = 1 )
ahr_blinded( surv = survival::Surv( time = simtrial::ex2_delayed_effect$month, event = simtrial::ex2_delayed_effect$evntd ), intervals = c(4, 100), hr = c(1, .55), ratio = 1 )
Convert summary table of a fixed or group sequential design object to a gt object
as_gt(x, ...) ## S3 method for class 'fixed_design' as_gt(x, title = NULL, footnote = NULL, ...) ## S3 method for class 'gs_design' as_gt( 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, ... )
as_gt(x, ...) ## S3 method for class 'fixed_design' as_gt(x, title = NULL, footnote = NULL, ...) ## S3 method for class 'gs_design' as_gt( 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 |
A summary object of a fixed or group sequential design. |
... |
Additional arguments (not used). |
title |
A string to specify the title of the gt table. |
footnote |
A list containing |
subtitle |
A string to specify the subtitle of the gt table. |
colname_spanner |
A string to specify the spanner of the gt table. |
colname_spannersub |
A vector of strings to specify the spanner details of the gt table. |
display_bound |
A vector of strings specifying the label of the bounds.
The default is |
display_columns |
A vector of strings specifying the variables to be displayed in the summary table. |
display_inf_bound |
Logical, whether to display the +/-inf bound. |
A gt_tbl
object.
library(dplyr) # 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() library(dplyr) # Example 1 ---- # The default output gs_design_ahr() %>% summary() %>% as_gt() gs_power_ahr() %>% summary() %>% as_gt() gs_design_wlr() %>% summary() %>% as_gt() gs_power_wlr() %>% 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() %>% 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() %>% 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() %>% 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() %>% 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() %>% summary() %>% as_gt(display_columns = c("Analysis", "Bound", "Nominal p", "Z", "Probability"))
library(dplyr) # 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() library(dplyr) # Example 1 ---- # The default output gs_design_ahr() %>% summary() %>% as_gt() gs_power_ahr() %>% summary() %>% as_gt() gs_design_wlr() %>% summary() %>% as_gt() gs_power_wlr() %>% 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() %>% 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() %>% 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() %>% 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() %>% 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() %>% summary() %>% as_gt(display_columns = c("Analysis", "Bound", "Nominal p", "Z", "Probability"))
Write summary table of a fixed or group sequential design object to an RTF file
as_rtf(x, ...) ## S3 method for class 'fixed_design' as_rtf( x, title = NULL, footnote = NULL, col_rel_width = NULL, orientation = c("portrait", "landscape"), text_font_size = 9, file, ... ) ## S3 method for class 'gs_design' as_rtf( 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 = TRUE, col_rel_width = NULL, orientation = c("portrait", "landscape"), text_font_size = 9, file, ... )
as_rtf(x, ...) ## S3 method for class 'fixed_design' as_rtf( x, title = NULL, footnote = NULL, col_rel_width = NULL, orientation = c("portrait", "landscape"), text_font_size = 9, file, ... ) ## S3 method for class 'gs_design' as_rtf( 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 = TRUE, col_rel_width = NULL, orientation = c("portrait", "landscape"), text_font_size = 9, file, ... )
x |
A summary object of a fixed or group sequential design. |
... |
Additional arguments (not used). |
title |
A string to specify the title of the RTF table. |
footnote |
A list containing |
col_rel_width |
Column relative width in a vector e.g. c(2,1,1) refers to 2:1:1. Default is NULL for equal column width. |
orientation |
Orientation in 'portrait' or 'landscape'. |
text_font_size |
Text font size. To vary text font size by column, use numeric vector with length of vector equal to number of columns displayed e.g. c(9,20,40). |
file |
File path for the output. |
subtitle |
A string to specify the subtitle of the RTF table. |
colname_spanner |
A string to specify the spanner of the RTF table. |
colname_spannersub |
A vector of strings to specify the spanner details of the RTF table. |
display_bound |
A vector of strings specifying the label of the bounds.
The default is |
display_columns |
A vector of strings specifying the variables to be displayed in the summary table. |
display_inf_bound |
Logical, whether to display the +/-inf bound. |
as_rtf()
returns the input x
invisibly.
library(dplyr) # 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 # AHR ---- # under fixed power x <- fixed_design_ahr( alpha = alpha, power = 1 - beta, enroll_rate = enroll_rate, fail_rate = fail_rate, study_duration = study_duration, ratio = ratio ) %>% summary() x %>% as_rtf(file = tempfile(fileext = ".rtf")) x %>% as_rtf(title = "Fixed design", file = tempfile(fileext = ".rtf")) x %>% as_rtf( footnote = "Power computed with average hazard ratio method given the sample size", file = tempfile(fileext = ".rtf") ) x %>% as_rtf(text_font_size = 10, file = tempfile(fileext = ".rtf")) # FH ---- # under fixed power fixed_design_fh( alpha = alpha, power = 1 - beta, enroll_rate = enroll_rate, fail_rate = fail_rate, study_duration = study_duration, ratio = ratio ) %>% summary() %>% as_rtf(file = tempfile(fileext = ".rtf")) #' # the default output library(dplyr) gs_design_ahr() %>% summary() %>% as_rtf(file = tempfile(fileext = ".rtf")) gs_power_ahr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) %>% summary() %>% as_rtf(file = tempfile(fileext = ".rtf")) gs_design_wlr() %>% summary() %>% as_rtf(file = tempfile(fileext = ".rtf")) gs_power_wlr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) %>% summary() %>% as_rtf(file = tempfile(fileext = ".rtf")) gs_power_combo() %>% summary() %>% as_rtf(file = tempfile(fileext = ".rtf")) gs_design_rd() %>% summary() %>% as_rtf(file = tempfile(fileext = ".rtf")) gs_power_rd() %>% summary() %>% as_rtf(file = tempfile(fileext = ".rtf")) # usage of title = ..., subtitle = ... # to edit the title/subtitle gs_power_wlr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) %>% summary() %>% as_rtf( title = "Bound Summary", subtitle = "from gs_power_wlr", file = tempfile(fileext = ".rtf") ) # 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_rtf( colname_spanner = "Cumulative probability to cross boundaries", colname_spannersub = c("under H1", "under H0"), file = tempfile(fileext = ".rtf") ) # usage of footnote = ... # to edit the footnote gs_power_wlr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) %>% summary() %>% as_rtf( 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") ), file = tempfile(fileext = ".rtf") ) # 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_rtf( display_bound = "Efficacy", file = tempfile(fileext = ".rtf") ) # 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_rtf( display_columns = c("Analysis", "Bound", "Nominal p", "Z", "Probability"), file = tempfile(fileext = ".rtf") )
library(dplyr) # 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 # AHR ---- # under fixed power x <- fixed_design_ahr( alpha = alpha, power = 1 - beta, enroll_rate = enroll_rate, fail_rate = fail_rate, study_duration = study_duration, ratio = ratio ) %>% summary() x %>% as_rtf(file = tempfile(fileext = ".rtf")) x %>% as_rtf(title = "Fixed design", file = tempfile(fileext = ".rtf")) x %>% as_rtf( footnote = "Power computed with average hazard ratio method given the sample size", file = tempfile(fileext = ".rtf") ) x %>% as_rtf(text_font_size = 10, file = tempfile(fileext = ".rtf")) # FH ---- # under fixed power fixed_design_fh( alpha = alpha, power = 1 - beta, enroll_rate = enroll_rate, fail_rate = fail_rate, study_duration = study_duration, ratio = ratio ) %>% summary() %>% as_rtf(file = tempfile(fileext = ".rtf")) #' # the default output library(dplyr) gs_design_ahr() %>% summary() %>% as_rtf(file = tempfile(fileext = ".rtf")) gs_power_ahr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) %>% summary() %>% as_rtf(file = tempfile(fileext = ".rtf")) gs_design_wlr() %>% summary() %>% as_rtf(file = tempfile(fileext = ".rtf")) gs_power_wlr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) %>% summary() %>% as_rtf(file = tempfile(fileext = ".rtf")) gs_power_combo() %>% summary() %>% as_rtf(file = tempfile(fileext = ".rtf")) gs_design_rd() %>% summary() %>% as_rtf(file = tempfile(fileext = ".rtf")) gs_power_rd() %>% summary() %>% as_rtf(file = tempfile(fileext = ".rtf")) # usage of title = ..., subtitle = ... # to edit the title/subtitle gs_power_wlr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) %>% summary() %>% as_rtf( title = "Bound Summary", subtitle = "from gs_power_wlr", file = tempfile(fileext = ".rtf") ) # 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_rtf( colname_spanner = "Cumulative probability to cross boundaries", colname_spannersub = c("under H1", "under H0"), file = tempfile(fileext = ".rtf") ) # usage of footnote = ... # to edit the footnote gs_power_wlr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) %>% summary() %>% as_rtf( 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") ), file = tempfile(fileext = ".rtf") ) # 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_rtf( display_bound = "Efficacy", file = tempfile(fileext = ".rtf") ) # 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_rtf( display_columns = c("Analysis", "Bound", "Nominal p", "Z", "Probability"), file = tempfile(fileext = ".rtf") )
Define the enrollment rate of subjects for a study as following a piecewise exponential distribution.
define_enroll_rate(duration, rate, stratum = "All")
define_enroll_rate(duration, rate, stratum = "All")
duration |
A numeric vector of ordered piecewise study duration interval. |
rate |
A numeric vector of enrollment rate in each |
stratum |
A character vector of stratum name. |
The duration
are ordered piecewise for a duration equal to
, where
.
The enrollment rates are defined in each duration with the same length.
For a study with multiple strata, different duration and rates can be specified in each stratum.
An enroll_rate
data frame.
# Define enroll rate without stratum define_enroll_rate( duration = c(2, 2, 10), rate = c(3, 6, 9) ) # Define enroll rate with stratum define_enroll_rate( duration = rep(c(2, 2, 2, 18), 3), rate = c((1:4) / 3, (1:4) / 2, (1:4) / 6), stratum = c(array("High", 4), array("Moderate", 4), array("Low", 4)) )
# Define enroll rate without stratum define_enroll_rate( duration = c(2, 2, 10), rate = c(3, 6, 9) ) # Define enroll rate with stratum define_enroll_rate( duration = rep(c(2, 2, 2, 18), 3), rate = c((1:4) / 3, (1:4) / 2, (1:4) / 6), stratum = c(array("High", 4), array("Moderate", 4), array("Low", 4)) )
Define subject failure rate for a study with two treatment groups. Also supports stratified designs that have different failure rates in each stratum.
define_fail_rate(duration, fail_rate, dropout_rate, hr = 1, stratum = "All")
define_fail_rate(duration, fail_rate, dropout_rate, hr = 1, stratum = "All")
duration |
A numeric vector of ordered piecewise study duration interval. |
fail_rate |
A numeric vector of failure rate in each |
dropout_rate |
A numeric vector of dropout rate in each |
hr |
A numeric vector of hazard ratio between treatment and control group. |
stratum |
A character vector of stratum name. |
Define the failure and dropout rate of subjects for a study as following
a piecewise exponential distribution.
The duration
are ordered piecewise for a duration equal to
, where
.
The failure rate, dropout rate, and hazard ratio in a study duration
can be specified.
For a study with multiple strata, different duration, failure rates, dropout rates, and hazard ratios can be specified in each stratum.
A fail_rate
data frame.
# Define enroll rate define_fail_rate( duration = c(3, 100), fail_rate = log(2) / c(9, 18), hr = c(.9, .6), dropout_rate = .001 ) # Define enroll rate with stratum define_fail_rate( stratum = c(rep("Low", 2), rep("High", 2)), duration = 1, fail_rate = c(.1, .2, .3, .4), dropout_rate = .001, hr = c(.9, .75, .8, .6) )
# Define enroll rate define_fail_rate( duration = c(3, 100), fail_rate = log(2) / c(9, 18), hr = c(.9, .6), dropout_rate = .001 ) # Define enroll rate with stratum define_fail_rate( stratum = c(rep("Low", 2), rep("High", 2)), duration = 1, fail_rate = c(.1, .2, .3, .4), dropout_rate = .001, hr = c(.9, .75, .8, .6) )
Computes the expected cumulative enrollment (accrual) given a set of piecewise constant enrollment rates and times.
expected_accrual( time = 0:24, enroll_rate = define_enroll_rate(duration = c(3, 3, 18), rate = c(5, 10, 20)) )
expected_accrual( time = 0:24, enroll_rate = define_enroll_rate(duration = c(3, 3, 18), rate = c(5, 10, 20)) )
time |
Times at which enrollment is to be computed. |
enroll_rate |
An |
A vector with expected cumulative enrollment for the specified times
.
The contents of this section are shown in PDF user manual only.
library(tibble) # Example 1: default expected_accrual() # Example 2: unstratified design expected_accrual( time = c(5, 10, 20), enroll_rate = define_enroll_rate( duration = c(3, 3, 18), rate = c(5, 10, 20) ) ) expected_accrual( time = c(5, 10, 20), enroll_rate = define_enroll_rate( duration = c(3, 3, 18), rate = c(5, 10, 20), ) ) # Example 3: stratified design expected_accrual( time = c(24, 30, 40), enroll_rate = define_enroll_rate( stratum = c("subgroup", "complement"), duration = c(33, 33), rate = c(30, 30) ) ) # Example 4: expected accrual over time # Scenario 4.1: for the enrollment in the first 3 months, # it is exactly 3 * 5 = 15. expected_accrual( time = 3, enroll_rate = define_enroll_rate(duration = c(3, 3, 18), rate = c(5, 10, 20)) ) # Scenario 4.2: for the enrollment in the first 6 months, # it is exactly 3 * 5 + 3 * 10 = 45. expected_accrual( time = 6, enroll_rate = define_enroll_rate(duration = c(3, 3, 18), rate = c(5, 10, 20)) ) # Scenario 4.3: for the enrollment in the first 24 months, # it is exactly 3 * 5 + 3 * 10 + 18 * 20 = 405. expected_accrual( time = 24, enroll_rate = define_enroll_rate(duration = c(3, 3, 18), rate = c(5, 10, 20)) ) # Scenario 4.4: for the enrollment after 24 months, # it is the same as that from the 24 months, since the enrollment is stopped. expected_accrual( time = 25, enroll_rate = define_enroll_rate(duration = c(3, 3, 18), rate = c(5, 10, 20)) ) # Instead of compute the enrolled subjects one time point by one time point, # we can also compute it once. expected_accrual( time = c(3, 6, 24, 25), enroll_rate = define_enroll_rate(duration = c(3, 3, 18), rate = c(5, 10, 20)) )
library(tibble) # Example 1: default expected_accrual() # Example 2: unstratified design expected_accrual( time = c(5, 10, 20), enroll_rate = define_enroll_rate( duration = c(3, 3, 18), rate = c(5, 10, 20) ) ) expected_accrual( time = c(5, 10, 20), enroll_rate = define_enroll_rate( duration = c(3, 3, 18), rate = c(5, 10, 20), ) ) # Example 3: stratified design expected_accrual( time = c(24, 30, 40), enroll_rate = define_enroll_rate( stratum = c("subgroup", "complement"), duration = c(33, 33), rate = c(30, 30) ) ) # Example 4: expected accrual over time # Scenario 4.1: for the enrollment in the first 3 months, # it is exactly 3 * 5 = 15. expected_accrual( time = 3, enroll_rate = define_enroll_rate(duration = c(3, 3, 18), rate = c(5, 10, 20)) ) # Scenario 4.2: for the enrollment in the first 6 months, # it is exactly 3 * 5 + 3 * 10 = 45. expected_accrual( time = 6, enroll_rate = define_enroll_rate(duration = c(3, 3, 18), rate = c(5, 10, 20)) ) # Scenario 4.3: for the enrollment in the first 24 months, # it is exactly 3 * 5 + 3 * 10 + 18 * 20 = 405. expected_accrual( time = 24, enroll_rate = define_enroll_rate(duration = c(3, 3, 18), rate = c(5, 10, 20)) ) # Scenario 4.4: for the enrollment after 24 months, # it is the same as that from the 24 months, since the enrollment is stopped. expected_accrual( time = 25, enroll_rate = define_enroll_rate(duration = c(3, 3, 18), rate = c(5, 10, 20)) ) # Instead of compute the enrolled subjects one time point by one time point, # we can also compute it once. expected_accrual( time = c(3, 6, 24, 25), enroll_rate = define_enroll_rate(duration = c(3, 3, 18), rate = c(5, 10, 20)) )
Computes expected events over time and by strata under the assumption of piecewise constant enrollment rates and piecewise exponential failure and censoring rates. The piecewise exponential distribution allows a simple method to specify a distribution and enrollment pattern where the enrollment, failure and dropout rates changes over time. While the main purpose may be to generate a trial that can be analyzed at a single point in time or using group sequential methods, the routine can also be used to simulate an adaptive trial design. The intent is to enable sample size calculations under non-proportional hazards assumptions for stratified populations.
expected_event( enroll_rate = define_enroll_rate(duration = c(2, 2, 10), rate = c(3, 6, 9)), fail_rate = define_fail_rate(duration = c(3, 100), fail_rate = log(2)/c(9, 18), dropout_rate = 0.001), total_duration = 25, simple = TRUE )
expected_event( enroll_rate = define_enroll_rate(duration = c(2, 2, 10), rate = c(3, 6, 9)), fail_rate = define_fail_rate(duration = c(3, 100), fail_rate = log(2)/c(9, 18), dropout_rate = 0.001), total_duration = 25, simple = TRUE )
enroll_rate |
An |
fail_rate |
A |
total_duration |
Total follow-up from start of enrollment to data cutoff. |
simple |
If default ( |
More periods will generally be supplied in output than those that are input. The intent is to enable expected event calculations in a tidy format to maximize flexibility for a variety of purposes.
The default when simple = TRUE
is to return the total expected
number of events as a real number.
Otherwise, when simple = FALSE
, a data frame is returned with
the following variables for each period specified in fail_rate
:
t
: start of period.
fail_rate
: failure rate during the period.
event
: expected events during the period.
The records in the returned data frame correspond to the input data frame fail_rate
.
library(gsDesign2) # Default arguments, simple output (total event count only) expected_event() # Event count by time period expected_event(simple = FALSE) # Early cutoff expected_event(total_duration = .5) # Single time period example expected_event( enroll_rate = define_enroll_rate(duration = 10, rate = 10), fail_rate = define_fail_rate(duration = 100, fail_rate = log(2) / 6, dropout_rate = .01), total_duration = 22, simple = FALSE ) # Single time period example, multiple enrollment periods expected_event( enroll_rate = define_enroll_rate(duration = c(5, 5), rate = c(10, 20)), fail_rate = define_fail_rate(duration = 100, fail_rate = log(2) / 6, dropout_rate = .01), total_duration = 22, simple = FALSE )
library(gsDesign2) # Default arguments, simple output (total event count only) expected_event() # Event count by time period expected_event(simple = FALSE) # Early cutoff expected_event(total_duration = .5) # Single time period example expected_event( enroll_rate = define_enroll_rate(duration = 10, rate = 10), fail_rate = define_fail_rate(duration = 100, fail_rate = log(2) / 6, dropout_rate = .01), total_duration = 22, simple = FALSE ) # Single time period example, multiple enrollment periods expected_event( enroll_rate = define_enroll_rate(duration = c(5, 5), rate = c(10, 20)), fail_rate = define_fail_rate(duration = 100, fail_rate = log(2) / 6, dropout_rate = .01), total_duration = 22, simple = FALSE )
expected_time()
is made to match input format with ahr()
and to solve for the
time at which the expected accumulated events is equal to an input target.
Enrollment and failure rate distributions are specified as follows.
The piecewise exponential distribution allows a simple method to specify a distribution
and enrollment pattern
where the enrollment, failure and dropout rates changes over time.
expected_time( enroll_rate = define_enroll_rate(duration = c(2, 2, 10), rate = c(3, 6, 9) * 5), fail_rate = define_fail_rate(stratum = "All", duration = c(3, 100), fail_rate = log(2)/c(9, 18), hr = c(0.9, 0.6), dropout_rate = rep(0.001, 2)), target_event = 150, ratio = 1, interval = c(0.01, 100) )
expected_time( enroll_rate = define_enroll_rate(duration = c(2, 2, 10), rate = c(3, 6, 9) * 5), fail_rate = define_fail_rate(stratum = "All", duration = c(3, 100), fail_rate = log(2)/c(9, 18), hr = c(0.9, 0.6), dropout_rate = rep(0.001, 2)), target_event = 150, ratio = 1, interval = c(0.01, 100) )
enroll_rate |
An |
fail_rate |
A |
target_event |
The targeted number of events to be achieved. |
ratio |
Experimental:Control randomization ratio. |
interval |
An interval that is presumed to include the time at which
expected event count is equal to |
A data frame with Time
(computed to match events in target_event
),
AHR
(average hazard ratio), Events
(target_event
input),
info
(information under given scenarios), and info0
(information under related null hypothesis) for each value of
total_duration
input.
# Example 1 ---- # default expected_time() # Example 2 ---- # check that result matches a finding using AHR() # Start by deriving an expected event count enroll_rate <- define_enroll_rate(duration = c(2, 2, 10), rate = c(3, 6, 9) * 5) fail_rate <- define_fail_rate( duration = c(3, 100), fail_rate = log(2) / c(9, 18), hr = c(.9, .6), dropout_rate = .001 ) total_duration <- 20 xx <- ahr(enroll_rate, fail_rate, total_duration) xx # Next we check that the function confirms the timing of the final analysis. expected_time(enroll_rate, fail_rate, target_event = xx$event, interval = c(.5, 1.5) * xx$time ) # Example 3 ---- # In this example, we verify `expected_time()` by `ahr()`. x <- ahr( enroll_rate = enroll_rate, fail_rate = fail_rate, ratio = 1, total_duration = 20 ) cat("The number of events by 20 months is ", x$event, ".\n") y <- expected_time( enroll_rate = enroll_rate, fail_rate = fail_rate, ratio = 1, target_event = x$event ) cat("The time to get ", x$event, " is ", y$time, "months.\n")
# Example 1 ---- # default expected_time() # Example 2 ---- # check that result matches a finding using AHR() # Start by deriving an expected event count enroll_rate <- define_enroll_rate(duration = c(2, 2, 10), rate = c(3, 6, 9) * 5) fail_rate <- define_fail_rate( duration = c(3, 100), fail_rate = log(2) / c(9, 18), hr = c(.9, .6), dropout_rate = .001 ) total_duration <- 20 xx <- ahr(enroll_rate, fail_rate, total_duration) xx # Next we check that the function confirms the timing of the final analysis. expected_time(enroll_rate, fail_rate, target_event = xx$event, interval = c(.5, 1.5) * xx$time ) # Example 3 ---- # In this example, we verify `expected_time()` by `ahr()`. x <- ahr( enroll_rate = enroll_rate, fail_rate = fail_rate, ratio = 1, total_duration = 20 ) cat("The number of events by 20 months is ", x$event, ".\n") y <- expected_time( enroll_rate = enroll_rate, fail_rate = fail_rate, ratio = 1, target_event = x$event ) cat("The time to get ", x$event, " is ", y$time, "months.\n")
Computes fixed design sample size (given power) or power (given sample size) by:
fixed_design_ahr()
- Average hazard ratio method.
fixed_design_fh()
- Weighted logrank test with Fleming-Harrington
weights (Farrington and Manning, 1990).
fixed_design_mb()
- Weighted logrank test with Magirr-Burman weights.
fixed_design_lf()
- Lachin-Foulkes method (Lachin and Foulkes, 1986).
fixed_design_maxcombo()
- MaxCombo method.
fixed_design_rmst()
- RMST method.
fixed_design_milestone()
- Milestone method.
Additionally, fixed_design_rd()
provides fixed design for binary endpoint
with treatment effect measuring in risk difference.
fixed_design_ahr( enroll_rate, fail_rate, alpha = 0.025, power = NULL, ratio = 1, study_duration = 36, event = NULL ) fixed_design_fh( alpha = 0.025, power = NULL, ratio = 1, study_duration = 36, enroll_rate, fail_rate, rho = 0, gamma = 0 ) fixed_design_lf( alpha = 0.025, power = NULL, ratio = 1, study_duration = 36, enroll_rate, fail_rate ) fixed_design_maxcombo( alpha = 0.025, power = NULL, ratio = 1, study_duration = 36, enroll_rate, fail_rate, rho = c(0, 0, 1), gamma = c(0, 1, 0), tau = rep(-1, 3) ) fixed_design_mb( alpha = 0.025, power = NULL, ratio = 1, study_duration = 36, enroll_rate, fail_rate, tau = 6, w_max = Inf ) fixed_design_milestone( alpha = 0.025, power = NULL, ratio = 1, enroll_rate, fail_rate, study_duration = 36, tau = NULL ) fixed_design_rd( alpha = 0.025, power = NULL, ratio = 1, p_c, p_e, rd0 = 0, n = NULL ) fixed_design_rmst( alpha = 0.025, power = NULL, ratio = 1, study_duration = 36, enroll_rate, fail_rate, tau = NULL )
fixed_design_ahr( enroll_rate, fail_rate, alpha = 0.025, power = NULL, ratio = 1, study_duration = 36, event = NULL ) fixed_design_fh( alpha = 0.025, power = NULL, ratio = 1, study_duration = 36, enroll_rate, fail_rate, rho = 0, gamma = 0 ) fixed_design_lf( alpha = 0.025, power = NULL, ratio = 1, study_duration = 36, enroll_rate, fail_rate ) fixed_design_maxcombo( alpha = 0.025, power = NULL, ratio = 1, study_duration = 36, enroll_rate, fail_rate, rho = c(0, 0, 1), gamma = c(0, 1, 0), tau = rep(-1, 3) ) fixed_design_mb( alpha = 0.025, power = NULL, ratio = 1, study_duration = 36, enroll_rate, fail_rate, tau = 6, w_max = Inf ) fixed_design_milestone( alpha = 0.025, power = NULL, ratio = 1, enroll_rate, fail_rate, study_duration = 36, tau = NULL ) fixed_design_rd( alpha = 0.025, power = NULL, ratio = 1, p_c, p_e, rd0 = 0, n = NULL ) fixed_design_rmst( alpha = 0.025, power = NULL, ratio = 1, study_duration = 36, enroll_rate, fail_rate, tau = NULL )
enroll_rate |
Enrollment rates. |
fail_rate |
Failure and dropout rates. |
alpha |
One-sided Type I error (strictly between 0 and 1). |
power |
Power ( |
ratio |
Experimental:Control randomization ratio. |
study_duration |
Study duration. |
event |
Targeted event at each analysis. |
rho |
A vector of numbers paring with gamma and tau for MaxCombo test. |
gamma |
A vector of numbers paring with rho and tau for MaxCombo test. |
tau |
Test parameter in RMST. |
w_max |
Test parameter of Magirr-Burman method. |
p_c |
A numerical value of the control arm rate. |
p_e |
A numerical value of the experimental arm rate. |
rd0 |
Risk difference under null hypothesis, default is 0. |
n |
Sample size. If NULL with power input, the sample size will be computed to achieve the targeted power |
A list of design characteristic summary.
# AHR method ---- library(dplyr) # Example 1: given power and compute sample size x <- fixed_design_ahr( alpha = .025, power = .9, enroll_rate = define_enroll_rate(duration = 18, rate = 1), fail_rate = define_fail_rate( duration = c(4, 100), fail_rate = log(2) / 12, hr = c(1, .6), dropout_rate = .001 ), study_duration = 36 ) x %>% summary() # Example 2: given sample size and compute power x <- fixed_design_ahr( alpha = .025, enroll_rate = define_enroll_rate(duration = 18, rate = 20), fail_rate = define_fail_rate( duration = c(4, 100), fail_rate = log(2) / 12, hr = c(1, .6), dropout_rate = .001 ), study_duration = 36 ) x %>% summary() # WLR test with FH weights ---- library(dplyr) # Example 1: given power and compute sample size x <- fixed_design_fh( alpha = .025, power = .9, enroll_rate = define_enroll_rate(duration = 18, rate = 1), fail_rate = define_fail_rate( duration = c(4, 100), fail_rate = log(2) / 12, hr = c(1, .6), dropout_rate = .001 ), study_duration = 36, rho = 1, gamma = 1 ) x %>% summary() # Example 2: given sample size and compute power x <- fixed_design_fh( alpha = .025, enroll_rate = define_enroll_rate(duration = 18, rate = 20), fail_rate = define_fail_rate( duration = c(4, 100), fail_rate = log(2) / 12, hr = c(1, .6), dropout_rate = .001 ), study_duration = 36, rho = 1, gamma = 1 ) x %>% summary() # LF method ---- library(dplyr) # Example 1: given power and compute sample size x <- fixed_design_lf( alpha = .025, power = .9, enroll_rate = define_enroll_rate(duration = 18, rate = 1), fail_rate = define_fail_rate( duration = 100, fail_rate = log(2) / 12, hr = .7, dropout_rate = .001 ), study_duration = 36 ) x %>% summary() # Example 2: given sample size and compute power x <- fixed_design_lf( alpha = .025, enroll_rate = define_enroll_rate(duration = 18, rate = 20), fail_rate = define_fail_rate( duration = 100, fail_rate = log(2) / 12, hr = .7, dropout_rate = .001 ), study_duration = 36 ) x %>% summary() # MaxCombo test ---- library(dplyr) # Example 1: given power and compute sample size x <- fixed_design_maxcombo( alpha = .025, power = .9, enroll_rate = define_enroll_rate(duration = 18, rate = 1), fail_rate = define_fail_rate( duration = c(4, 100), fail_rate = log(2) / 12, hr = c(1, .6), dropout_rate = .001 ), study_duration = 36, rho = c(0, 0.5), gamma = c(0, 0), tau = c(-1, -1) ) x %>% summary() # Example 2: given sample size and compute power x <- fixed_design_maxcombo( alpha = .025, enroll_rate = define_enroll_rate(duration = 18, rate = 20), fail_rate = define_fail_rate( duration = c(4, 100), fail_rate = log(2) / 12, hr = c(1, .6), dropout_rate = .001 ), study_duration = 36, rho = c(0, 0.5), gamma = c(0, 0), tau = c(-1, -1) ) x %>% summary() # WLR test with MB weights ---- library(dplyr) # Example 1: given power and compute sample size x <- fixed_design_mb( alpha = .025, power = .9, enroll_rate = define_enroll_rate(duration = 18, rate = 1), fail_rate = define_fail_rate( duration = c(4, 100), fail_rate = log(2) / 12, hr = c(1, .6), dropout_rate = .001 ), study_duration = 36, tau = 4, w_max = 2 ) x %>% summary() # Example 2: given sample size and compute power x <- fixed_design_mb( alpha = .025, enroll_rate = define_enroll_rate(duration = 18, rate = 20), fail_rate = define_fail_rate( duration = c(4, 100), fail_rate = log(2) / 12, hr = c(1, .6), dropout_rate = .001 ), study_duration = 36, tau = 4, w_max = 2 ) x %>% summary() # Milestone method ---- library(dplyr) # Example 1: given power and compute sample size x <- fixed_design_milestone( alpha = .025, power = .9, enroll_rate = define_enroll_rate(duration = 18, rate = 1), fail_rate = define_fail_rate( duration = 100, fail_rate = log(2) / 12, hr = .7, dropout_rate = .001 ), study_duration = 36, tau = 18 ) x %>% summary() # Example 2: given sample size and compute power x <- fixed_design_milestone( alpha = .025, enroll_rate = define_enroll_rate(duration = 18, rate = 20), fail_rate = define_fail_rate( duration = 100, fail_rate = log(2) / 12, hr = .7, dropout_rate = .001 ), study_duration = 36, tau = 18 ) x %>% summary() # Binary endpoint with risk differences ---- library(dplyr) # Example 1: given power and compute sample size x <- fixed_design_rd( alpha = 0.025, power = 0.9, p_c = .15, p_e = .1, rd0 = 0, ratio = 1 ) x %>% summary() # Example 2: given sample size and compute power x <- fixed_design_rd( alpha = 0.025, power = NULL, p_c = .15, p_e = .1, rd0 = 0, n = 2000, ratio = 1 ) x %>% summary() # RMST method ---- library(dplyr) # Example 1: given power and compute sample size x <- fixed_design_rmst( alpha = .025, power = .9, enroll_rate = define_enroll_rate(duration = 18, rate = 1), fail_rate = define_fail_rate( duration = 100, fail_rate = log(2) / 12, hr = .7, dropout_rate = .001 ), study_duration = 36, tau = 18 ) x %>% summary() # Example 2: given sample size and compute power x <- fixed_design_rmst( alpha = .025, enroll_rate = define_enroll_rate(duration = 18, rate = 20), fail_rate = define_fail_rate( duration = 100, fail_rate = log(2) / 12, hr = .7, dropout_rate = .001 ), study_duration = 36, tau = 18 ) x %>% summary()
# AHR method ---- library(dplyr) # Example 1: given power and compute sample size x <- fixed_design_ahr( alpha = .025, power = .9, enroll_rate = define_enroll_rate(duration = 18, rate = 1), fail_rate = define_fail_rate( duration = c(4, 100), fail_rate = log(2) / 12, hr = c(1, .6), dropout_rate = .001 ), study_duration = 36 ) x %>% summary() # Example 2: given sample size and compute power x <- fixed_design_ahr( alpha = .025, enroll_rate = define_enroll_rate(duration = 18, rate = 20), fail_rate = define_fail_rate( duration = c(4, 100), fail_rate = log(2) / 12, hr = c(1, .6), dropout_rate = .001 ), study_duration = 36 ) x %>% summary() # WLR test with FH weights ---- library(dplyr) # Example 1: given power and compute sample size x <- fixed_design_fh( alpha = .025, power = .9, enroll_rate = define_enroll_rate(duration = 18, rate = 1), fail_rate = define_fail_rate( duration = c(4, 100), fail_rate = log(2) / 12, hr = c(1, .6), dropout_rate = .001 ), study_duration = 36, rho = 1, gamma = 1 ) x %>% summary() # Example 2: given sample size and compute power x <- fixed_design_fh( alpha = .025, enroll_rate = define_enroll_rate(duration = 18, rate = 20), fail_rate = define_fail_rate( duration = c(4, 100), fail_rate = log(2) / 12, hr = c(1, .6), dropout_rate = .001 ), study_duration = 36, rho = 1, gamma = 1 ) x %>% summary() # LF method ---- library(dplyr) # Example 1: given power and compute sample size x <- fixed_design_lf( alpha = .025, power = .9, enroll_rate = define_enroll_rate(duration = 18, rate = 1), fail_rate = define_fail_rate( duration = 100, fail_rate = log(2) / 12, hr = .7, dropout_rate = .001 ), study_duration = 36 ) x %>% summary() # Example 2: given sample size and compute power x <- fixed_design_lf( alpha = .025, enroll_rate = define_enroll_rate(duration = 18, rate = 20), fail_rate = define_fail_rate( duration = 100, fail_rate = log(2) / 12, hr = .7, dropout_rate = .001 ), study_duration = 36 ) x %>% summary() # MaxCombo test ---- library(dplyr) # Example 1: given power and compute sample size x <- fixed_design_maxcombo( alpha = .025, power = .9, enroll_rate = define_enroll_rate(duration = 18, rate = 1), fail_rate = define_fail_rate( duration = c(4, 100), fail_rate = log(2) / 12, hr = c(1, .6), dropout_rate = .001 ), study_duration = 36, rho = c(0, 0.5), gamma = c(0, 0), tau = c(-1, -1) ) x %>% summary() # Example 2: given sample size and compute power x <- fixed_design_maxcombo( alpha = .025, enroll_rate = define_enroll_rate(duration = 18, rate = 20), fail_rate = define_fail_rate( duration = c(4, 100), fail_rate = log(2) / 12, hr = c(1, .6), dropout_rate = .001 ), study_duration = 36, rho = c(0, 0.5), gamma = c(0, 0), tau = c(-1, -1) ) x %>% summary() # WLR test with MB weights ---- library(dplyr) # Example 1: given power and compute sample size x <- fixed_design_mb( alpha = .025, power = .9, enroll_rate = define_enroll_rate(duration = 18, rate = 1), fail_rate = define_fail_rate( duration = c(4, 100), fail_rate = log(2) / 12, hr = c(1, .6), dropout_rate = .001 ), study_duration = 36, tau = 4, w_max = 2 ) x %>% summary() # Example 2: given sample size and compute power x <- fixed_design_mb( alpha = .025, enroll_rate = define_enroll_rate(duration = 18, rate = 20), fail_rate = define_fail_rate( duration = c(4, 100), fail_rate = log(2) / 12, hr = c(1, .6), dropout_rate = .001 ), study_duration = 36, tau = 4, w_max = 2 ) x %>% summary() # Milestone method ---- library(dplyr) # Example 1: given power and compute sample size x <- fixed_design_milestone( alpha = .025, power = .9, enroll_rate = define_enroll_rate(duration = 18, rate = 1), fail_rate = define_fail_rate( duration = 100, fail_rate = log(2) / 12, hr = .7, dropout_rate = .001 ), study_duration = 36, tau = 18 ) x %>% summary() # Example 2: given sample size and compute power x <- fixed_design_milestone( alpha = .025, enroll_rate = define_enroll_rate(duration = 18, rate = 20), fail_rate = define_fail_rate( duration = 100, fail_rate = log(2) / 12, hr = .7, dropout_rate = .001 ), study_duration = 36, tau = 18 ) x %>% summary() # Binary endpoint with risk differences ---- library(dplyr) # Example 1: given power and compute sample size x <- fixed_design_rd( alpha = 0.025, power = 0.9, p_c = .15, p_e = .1, rd0 = 0, ratio = 1 ) x %>% summary() # Example 2: given sample size and compute power x <- fixed_design_rd( alpha = 0.025, power = NULL, p_c = .15, p_e = .1, rd0 = 0, n = 2000, ratio = 1 ) x %>% summary() # RMST method ---- library(dplyr) # Example 1: given power and compute sample size x <- fixed_design_rmst( alpha = .025, power = .9, enroll_rate = define_enroll_rate(duration = 18, rate = 1), fail_rate = define_fail_rate( duration = 100, fail_rate = log(2) / 12, hr = .7, dropout_rate = .001 ), study_duration = 36, tau = 18 ) x %>% summary() # Example 2: given sample size and compute power x <- fixed_design_rmst( alpha = .025, enroll_rate = define_enroll_rate(duration = 18, rate = 20), fail_rate = define_fail_rate( duration = 100, fail_rate = log(2) / 12, hr = .7, dropout_rate = .001 ), study_duration = 36, tau = 18 ) x %>% summary()
gs_b()
is the simplest version of a function to be used with the upper
and lower
arguments in gs_power_npe()
and gs_design_npe()
or the
upper_bound
and lower_bound
arguments in gs_prob_combo()
and
pmvnorm_combo()
.
It simply returns the vector of Z-values in the input vector par
or,
if k
is specified, par[k]
is returned.
Note that if bounds need to change with changing information at analyses,
gs_b()
should not be used.
For instance, for spending function bounds use gs_spending_bound()
.
gs_b(par = NULL, k = NULL, ...)
gs_b(par = NULL, k = NULL, ...)
par |
For |
k |
Is |
... |
Further arguments passed to or from other methods. |
Returns the vector input par
if k
is NULL
, otherwise, par[k]
.
The contents of this section are shown in PDF user manual only.
# Simple: enter a vector of length 3 for bound gs_b(par = 4:2) # 2nd element of par gs_b(par = 4:2, k = 2) # Generate an efficacy bound using a spending function # Use Lan-DeMets spending approximation of O'Brien-Fleming bound # as 50%, 75% and 100% of final spending # Information fraction IF <- c(.5, .75, 1) gs_b(par = gsDesign::gsDesign( alpha = .025, k = length(IF), test.type = 1, sfu = gsDesign::sfLDOF, timing = IF )$upper$bound)
# Simple: enter a vector of length 3 for bound gs_b(par = 4:2) # 2nd element of par gs_b(par = 4:2, k = 2) # Generate an efficacy bound using a spending function # Use Lan-DeMets spending approximation of O'Brien-Fleming bound # as 50%, 75% and 100% of final spending # Information fraction IF <- c(.5, .75, 1) gs_b(par = gsDesign::gsDesign( alpha = .025, k = length(IF), test.type = 1, sfu = gsDesign::sfLDOF, timing = IF )$upper$bound)
Create npsurvSS arm object
gs_create_arm(enroll_rate, fail_rate, ratio, total_time = 1e+06)
gs_create_arm(enroll_rate, fail_rate, ratio, total_time = 1e+06)
enroll_rate |
Enrollment rates from |
fail_rate |
Failure and dropout rates from |
ratio |
Experimental:Control randomization ratio. |
total_time |
Total analysis time. |
A list of the two arms.
The contents of this section are shown in PDF user manual only.
enroll_rate <- define_enroll_rate( duration = c(2, 2, 10), rate = c(3, 6, 9) ) fail_rate <- define_fail_rate( duration = c(3, 100), fail_rate = log(2) / c(9, 18), hr = c(.9, .6), dropout_rate = .001 ) gs_create_arm(enroll_rate, fail_rate, ratio = 1)
enroll_rate <- define_enroll_rate( duration = c(2, 2, 10), rate = c(3, 6, 9) ) fail_rate <- define_fail_rate( duration = c(3, 100), fail_rate = log(2) / c(9, 18), hr = c(.9, .6), dropout_rate = .001 ) gs_create_arm(enroll_rate, fail_rate, ratio = 1)
Group sequential design using average hazard ratio under non-proportional hazards
gs_design_ahr( enroll_rate = define_enroll_rate(duration = c(2, 2, 10), rate = c(3, 6, 9)), fail_rate = define_fail_rate(duration = c(3, 100), fail_rate = log(2)/c(9, 18), hr = c(0.9, 0.6), dropout_rate = 0.001), alpha = 0.025, beta = 0.1, info_frac = NULL, analysis_time = 36, ratio = 1, binding = FALSE, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = alpha), lower = gs_spending_bound, lpar = list(sf = gsDesign::sfLDOF, total_spend = beta), h1_spending = TRUE, test_upper = TRUE, test_lower = TRUE, info_scale = c("h0_h1_info", "h0_info", "h1_info"), r = 18, tol = 1e-06, interval = c(0.01, 1000) )
gs_design_ahr( enroll_rate = define_enroll_rate(duration = c(2, 2, 10), rate = c(3, 6, 9)), fail_rate = define_fail_rate(duration = c(3, 100), fail_rate = log(2)/c(9, 18), hr = c(0.9, 0.6), dropout_rate = 0.001), alpha = 0.025, beta = 0.1, info_frac = NULL, analysis_time = 36, ratio = 1, binding = FALSE, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = alpha), lower = gs_spending_bound, lpar = list(sf = gsDesign::sfLDOF, total_spend = beta), h1_spending = TRUE, test_upper = TRUE, test_lower = TRUE, info_scale = c("h0_h1_info", "h0_info", "h1_info"), r = 18, tol = 1e-06, interval = c(0.01, 1000) )
enroll_rate |
Enrollment rates. |
fail_rate |
Failure and dropout rates. |
alpha |
One-sided Type I error. |
beta |
Type II error. |
info_frac |
Targeted information fraction at each analysis. |
analysis_time |
Minimum time of analysis. |
ratio |
Experimental:Control randomization ratio (not yet implemented). |
binding |
Indicator of whether futility bound is binding;
default of |
upper |
Function to compute upper bound. |
upar |
Parameters passed to |
lower |
Function to compute lower bound. |
lpar |
Parameters passed to |
h1_spending |
Indicator that lower bound to be set by spending
under alternate hypothesis (input |
test_upper |
Indicator of which analyses should include an upper
(efficacy) bound; single value of |
test_lower |
Indicator of which analyses should include an lower bound;
single value of |
info_scale |
Information scale for calculation. Options are:
|
r |
Integer value controlling grid for numerical integration as in
Jennison and Turnbull (2000); default is 18, range is 1 to 80.
Larger values provide larger number of grid points and greater accuracy.
Normally, |
tol |
Tolerance parameter for boundary convergence (on Z-scale). |
interval |
An interval that is presumed to include the time at which expected event count is equal to targeted event. |
To be added.
A list with input parameters, enrollment rate, analysis, and bound.
The contents of this section are shown in PDF user manual only.
library(gsDesign) library(gsDesign2) library(dplyr) # Example 1 ---- # call with defaults gs_design_ahr() # Example 2 ---- # Single analysis gs_design_ahr(analysis_time = 40) # Example 3 ---- # Multiple analysis_time gs_design_ahr(analysis_time = c(12, 24, 36)) # Example 4 ---- # Specified information fraction gs_design_ahr(info_frac = c(.25, .75, 1), analysis_time = 36) # Example 5 ---- # multiple analysis times & info_frac # driven by times gs_design_ahr(info_frac = c(.25, .75, 1), analysis_time = c(12, 25, 36)) # driven by info_frac gs_design_ahr(info_frac = c(1 / 3, .8, 1), analysis_time = c(12, 25, 36)) # Example 6 ---- # 2-sided symmetric design with O'Brien-Fleming spending gs_design_ahr( analysis_time = c(12, 24, 36), binding = TRUE, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL), lower = gs_spending_bound, lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL), h1_spending = FALSE ) # 2-sided asymmetric design with O'Brien-Fleming upper spending # Pocock lower spending under H1 (NPH) gs_design_ahr( analysis_time = c(12, 24, 36), binding = TRUE, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL), lower = gs_spending_bound, lpar = list(sf = gsDesign::sfLDPocock, total_spend = 0.1, param = NULL, timing = NULL), h1_spending = TRUE ) # Example 7 ---- gs_design_ahr( alpha = 0.0125, analysis_time = c(12, 24, 36), upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.0125, param = NULL, timing = NULL), lower = gs_b, lpar = rep(-Inf, 3) ) gs_design_ahr( alpha = 0.0125, analysis_time = c(12, 24, 36), upper = gs_b, upar = gsDesign::gsDesign( k = 3, test.type = 1, n.I = c(.25, .75, 1), sfu = sfLDOF, sfupar = NULL, alpha = 0.0125 )$upper$bound, lower = gs_b, lpar = rep(-Inf, 3) )
library(gsDesign) library(gsDesign2) library(dplyr) # Example 1 ---- # call with defaults gs_design_ahr() # Example 2 ---- # Single analysis gs_design_ahr(analysis_time = 40) # Example 3 ---- # Multiple analysis_time gs_design_ahr(analysis_time = c(12, 24, 36)) # Example 4 ---- # Specified information fraction gs_design_ahr(info_frac = c(.25, .75, 1), analysis_time = 36) # Example 5 ---- # multiple analysis times & info_frac # driven by times gs_design_ahr(info_frac = c(.25, .75, 1), analysis_time = c(12, 25, 36)) # driven by info_frac gs_design_ahr(info_frac = c(1 / 3, .8, 1), analysis_time = c(12, 25, 36)) # Example 6 ---- # 2-sided symmetric design with O'Brien-Fleming spending gs_design_ahr( analysis_time = c(12, 24, 36), binding = TRUE, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL), lower = gs_spending_bound, lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL), h1_spending = FALSE ) # 2-sided asymmetric design with O'Brien-Fleming upper spending # Pocock lower spending under H1 (NPH) gs_design_ahr( analysis_time = c(12, 24, 36), binding = TRUE, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL), lower = gs_spending_bound, lpar = list(sf = gsDesign::sfLDPocock, total_spend = 0.1, param = NULL, timing = NULL), h1_spending = TRUE ) # Example 7 ---- gs_design_ahr( alpha = 0.0125, analysis_time = c(12, 24, 36), upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.0125, param = NULL, timing = NULL), lower = gs_b, lpar = rep(-Inf, 3) ) gs_design_ahr( alpha = 0.0125, analysis_time = c(12, 24, 36), upper = gs_b, upar = gsDesign::gsDesign( k = 3, test.type = 1, n.I = c(.25, .75, 1), sfu = sfLDOF, sfupar = NULL, alpha = 0.0125 )$upper$bound, lower = gs_b, lpar = rep(-Inf, 3) )
Group sequential design using MaxCombo test under non-proportional hazards
gs_design_combo( enroll_rate = define_enroll_rate(duration = 12, rate = 500/12), fail_rate = define_fail_rate(duration = c(4, 100), fail_rate = log(2)/15, hr = c(1, 0.6), dropout_rate = 0.001), fh_test = rbind(data.frame(rho = 0, gamma = 0, tau = -1, test = 1, analysis = 1:3, analysis_time = c(12, 24, 36)), data.frame(rho = c(0, 0.5), gamma = 0.5, tau = -1, test = 2:3, analysis = 3, analysis_time = 36)), ratio = 1, alpha = 0.025, beta = 0.2, binding = FALSE, upper = gs_b, upar = c(3, 2, 1), lower = gs_b, lpar = c(-1, 0, 1), algorithm = mvtnorm::GenzBretz(maxpts = 1e+05, abseps = 1e-05), n_upper_bound = 1000, ... )
gs_design_combo( enroll_rate = define_enroll_rate(duration = 12, rate = 500/12), fail_rate = define_fail_rate(duration = c(4, 100), fail_rate = log(2)/15, hr = c(1, 0.6), dropout_rate = 0.001), fh_test = rbind(data.frame(rho = 0, gamma = 0, tau = -1, test = 1, analysis = 1:3, analysis_time = c(12, 24, 36)), data.frame(rho = c(0, 0.5), gamma = 0.5, tau = -1, test = 2:3, analysis = 3, analysis_time = 36)), ratio = 1, alpha = 0.025, beta = 0.2, binding = FALSE, upper = gs_b, upar = c(3, 2, 1), lower = gs_b, lpar = c(-1, 0, 1), algorithm = mvtnorm::GenzBretz(maxpts = 1e+05, abseps = 1e-05), n_upper_bound = 1000, ... )
enroll_rate |
Enrollment rates. |
fail_rate |
Failure and dropout rates. |
fh_test |
A data frame to summarize the test in each analysis. See examples for its data structure. |
ratio |
Experimental:Control randomization ratio (not yet implemented). |
alpha |
One-sided Type I error. |
beta |
Type II error. |
binding |
Indicator of whether futility bound is binding;
default of |
upper |
Function to compute upper bound. |
upar |
Parameters passed to |
lower |
Function to compute lower bound. |
lpar |
Parameters passed to |
algorithm |
an object of class |
n_upper_bound |
A numeric value of upper limit of sample size. |
... |
Additional parameters passed to mvtnorm::pmvnorm. |
A list with input parameters, enrollment rate, analysis, and bound.
# The example is slow to run library(dplyr) library(mvtnorm) library(gsDesign) enroll_rate <- define_enroll_rate( duration = 12, rate = 500 / 12 ) fail_rate <- define_fail_rate( duration = c(4, 100), fail_rate = log(2) / 15, # median survival 15 month hr = c(1, .6), dropout_rate = 0.001 ) fh_test <- rbind( data.frame( rho = 0, gamma = 0, tau = -1, test = 1, analysis = 1:3, analysis_time = c(12, 24, 36) ), data.frame( rho = c(0, 0.5), gamma = 0.5, tau = -1, test = 2:3, analysis = 3, analysis_time = 36 ) ) x <- gsSurv( k = 3, test.type = 4, alpha = 0.025, beta = 0.2, astar = 0, timing = 1, sfu = sfLDOF, sfupar = 0, sfl = sfLDOF, sflpar = 0, lambdaC = 0.1, hr = 0.6, hr0 = 1, eta = 0.01, gamma = 10, R = 12, S = NULL, T = 36, minfup = 24, ratio = 1 ) # Example 1 ---- # User-defined boundary gs_design_combo( enroll_rate, fail_rate, fh_test, alpha = 0.025, beta = 0.2, ratio = 1, binding = FALSE, upar = x$upper$bound, lpar = x$lower$bound ) # Example 2 ---- # Boundary derived by spending function gs_design_combo( enroll_rate, fail_rate, fh_test, alpha = 0.025, beta = 0.2, ratio = 1, binding = FALSE, upper = gs_spending_combo, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025), # alpha spending lower = gs_spending_combo, lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.2), # beta spending )
# The example is slow to run library(dplyr) library(mvtnorm) library(gsDesign) enroll_rate <- define_enroll_rate( duration = 12, rate = 500 / 12 ) fail_rate <- define_fail_rate( duration = c(4, 100), fail_rate = log(2) / 15, # median survival 15 month hr = c(1, .6), dropout_rate = 0.001 ) fh_test <- rbind( data.frame( rho = 0, gamma = 0, tau = -1, test = 1, analysis = 1:3, analysis_time = c(12, 24, 36) ), data.frame( rho = c(0, 0.5), gamma = 0.5, tau = -1, test = 2:3, analysis = 3, analysis_time = 36 ) ) x <- gsSurv( k = 3, test.type = 4, alpha = 0.025, beta = 0.2, astar = 0, timing = 1, sfu = sfLDOF, sfupar = 0, sfl = sfLDOF, sflpar = 0, lambdaC = 0.1, hr = 0.6, hr0 = 1, eta = 0.01, gamma = 10, R = 12, S = NULL, T = 36, minfup = 24, ratio = 1 ) # Example 1 ---- # User-defined boundary gs_design_combo( enroll_rate, fail_rate, fh_test, alpha = 0.025, beta = 0.2, ratio = 1, binding = FALSE, upar = x$upper$bound, lpar = x$lower$bound ) # Example 2 ---- # Boundary derived by spending function gs_design_combo( enroll_rate, fail_rate, fh_test, alpha = 0.025, beta = 0.2, ratio = 1, binding = FALSE, upper = gs_spending_combo, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025), # alpha spending lower = gs_spending_combo, lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.2), # beta spending )
Derives group sequential design size, bounds and boundary crossing probabilities based on proportionate information and effect size at analyses. It allows a non-constant treatment effect over time, but also can be applied for the usual homogeneous effect size designs. It requires treatment effect and proportionate statistical information at each analysis as well as a method of deriving bounds, such as spending. The routine enables two things not available in the gsDesign package:
non-constant effect, 2) more flexibility in boundary selection.
For many applications, the non-proportional-hazards design function
gs_design_nph()
will be used; it calls this function.
Initial bound types supported are 1) spending bounds,
fixed bounds, and 3) Haybittle-Peto-like bounds.
The requirement is to have a boundary update method that
can each bound without knowledge of future bounds.
As an example, bounds based on conditional power that
require knowledge of all future bounds are not supported by this routine;
a more limited conditional power method will be demonstrated.
Boundary family designs Wang-Tsiatis designs including
the original (non-spending-function-based) O'Brien-Fleming and Pocock designs
are not supported by gs_power_npe()
.
gs_design_npe( theta = 0.1, theta0 = NULL, theta1 = NULL, info = 1, info0 = NULL, info1 = NULL, info_scale = c("h0_h1_info", "h0_info", "h1_info"), alpha = 0.025, beta = 0.1, upper = gs_b, upar = qnorm(0.975), lower = gs_b, lpar = -Inf, test_upper = TRUE, test_lower = TRUE, binding = FALSE, r = 18, tol = 1e-06 )
gs_design_npe( theta = 0.1, theta0 = NULL, theta1 = NULL, info = 1, info0 = NULL, info1 = NULL, info_scale = c("h0_h1_info", "h0_info", "h1_info"), alpha = 0.025, beta = 0.1, upper = gs_b, upar = qnorm(0.975), lower = gs_b, lpar = -Inf, test_upper = TRUE, test_lower = TRUE, binding = FALSE, r = 18, tol = 1e-06 )
theta |
Natural parameter for group sequential design representing expected incremental drift at all analyses; used for power calculation. |
theta0 |
Natural parameter used for upper bound spending;
if |
theta1 |
Natural parameter used for lower bound spending;
if |
info |
Proportionate statistical information at
all analyses for input |
info0 |
Proportionate statistical information under null hypothesis, if different than alternative; impacts null hypothesis bound calculation. |
info1 |
Proportionate statistical information under alternate hypothesis; impacts null hypothesis bound calculation. |
info_scale |
Information scale for calculation. Options are:
|
alpha |
One-sided Type I error. |
beta |
Type II error. |
upper |
Function to compute upper bound. |
upar |
Parameters passed to the function provided in |
lower |
Function to compare lower bound. |
lpar |
Parameters passed to the function provided in |
test_upper |
Indicator of which analyses should include
an upper (efficacy) bound; single value of |
test_lower |
Indicator of which analyses should include an lower bound;
single value of |
binding |
Indicator of whether futility bound is binding;
default of |
r |
Integer value controlling grid for numerical integration
as in Jennison and Turnbull (2000); default is 18, range is 1 to 80.
Larger values provide larger number of grid points and greater accuracy.
Normally |
tol |
Tolerance parameter for boundary convergence (on Z-scale). |
The inputs info
and info0
should be
vectors of the same length with increasing positive numbers.
The design returned will change these by some constant scale
factor to ensure the design has power 1 - beta
.
The bound specifications in upper
, lower
, upar
, lpar
will be used to ensure Type I error and other boundary properties are as specified.
A tibble with columns analysis, bound, z, probability, theta, info, info0.
The contents of this section are shown in PDF user manual only.
Keaven Anderson [email protected]
library(dplyr) library(gsDesign) # Example 1 ---- # Single analysis # Lachin book p 71 difference of proportions example pc <- .28 # Control response rate pe <- .40 # Experimental response rate p0 <- (pc + pe) / 2 # Ave response rate under H0 # Information per increment of 1 in sample size info0 <- 1 / (p0 * (1 - p0) * 4) info <- 1 / (pc * (1 - pc) * 2 + pe * (1 - pe) * 2) # Result should round up to next even number = 652 # Divide information needed under H1 by information per patient added gs_design_npe(theta = pe - pc, info = info, info0 = info0) # Example 2 ---- # Fixed bound x <- gs_design_npe( alpha = 0.0125, theta = c(.1, .2, .3), info = (1:3) * 80, info0 = (1:3) * 80, upper = gs_b, upar = gsDesign::gsDesign(k = 3, sfu = gsDesign::sfLDOF, alpha = 0.0125)$upper$bound, lower = gs_b, lpar = c(-1, 0, 0) ) x # Same upper bound; this represents non-binding Type I error and will total 0.025 gs_power_npe( theta = rep(0, 3), info = (x %>% filter(bound == "upper"))$info, upper = gs_b, upar = (x %>% filter(bound == "upper"))$z, lower = gs_b, lpar = rep(-Inf, 3) ) # Example 3 ---- # Spending bound examples # Design with futility only at analysis 1; efficacy only at analyses 2, 3 # Spending bound for efficacy; fixed bound for futility # NOTE: test_upper and test_lower DO NOT WORK with gs_b; must explicitly make bounds infinite # test_upper and test_lower DO WORK with gs_spending_bound gs_design_npe( theta = c(.1, .2, .3), info = (1:3) * 40, info0 = (1:3) * 40, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL), lower = gs_b, lpar = c(-1, -Inf, -Inf), test_upper = c(FALSE, TRUE, TRUE) ) # one can try `info_scale = "h1_info"` or `info_scale = "h0_info"` here gs_design_npe( theta = c(.1, .2, .3), info = (1:3) * 40, info0 = (1:3) * 30, info_scale = "h1_info", upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL), lower = gs_b, lpar = c(-1, -Inf, -Inf), test_upper = c(FALSE, TRUE, TRUE) ) # Example 4 ---- # Spending function bounds # 2-sided asymmetric bounds # Lower spending based on non-zero effect gs_design_npe( theta = c(.1, .2, .3), info = (1:3) * 40, info0 = (1:3) * 30, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL), lower = gs_spending_bound, lpar = list(sf = gsDesign::sfHSD, total_spend = 0.1, param = -1, timing = NULL) ) # Example 5 ---- # Two-sided symmetric spend, O'Brien-Fleming spending # Typically, 2-sided bounds are binding xx <- gs_design_npe( theta = c(.1, .2, .3), info = (1:3) * 40, binding = TRUE, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL), lower = gs_spending_bound, lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL) ) xx # Re-use these bounds under alternate hypothesis # Always use binding = TRUE for power calculations gs_power_npe( theta = c(.1, .2, .3), info = (1:3) * 40, binding = TRUE, upper = gs_b, lower = gs_b, upar = (xx %>% filter(bound == "upper"))$z, lpar = -(xx %>% filter(bound == "upper"))$z )
library(dplyr) library(gsDesign) # Example 1 ---- # Single analysis # Lachin book p 71 difference of proportions example pc <- .28 # Control response rate pe <- .40 # Experimental response rate p0 <- (pc + pe) / 2 # Ave response rate under H0 # Information per increment of 1 in sample size info0 <- 1 / (p0 * (1 - p0) * 4) info <- 1 / (pc * (1 - pc) * 2 + pe * (1 - pe) * 2) # Result should round up to next even number = 652 # Divide information needed under H1 by information per patient added gs_design_npe(theta = pe - pc, info = info, info0 = info0) # Example 2 ---- # Fixed bound x <- gs_design_npe( alpha = 0.0125, theta = c(.1, .2, .3), info = (1:3) * 80, info0 = (1:3) * 80, upper = gs_b, upar = gsDesign::gsDesign(k = 3, sfu = gsDesign::sfLDOF, alpha = 0.0125)$upper$bound, lower = gs_b, lpar = c(-1, 0, 0) ) x # Same upper bound; this represents non-binding Type I error and will total 0.025 gs_power_npe( theta = rep(0, 3), info = (x %>% filter(bound == "upper"))$info, upper = gs_b, upar = (x %>% filter(bound == "upper"))$z, lower = gs_b, lpar = rep(-Inf, 3) ) # Example 3 ---- # Spending bound examples # Design with futility only at analysis 1; efficacy only at analyses 2, 3 # Spending bound for efficacy; fixed bound for futility # NOTE: test_upper and test_lower DO NOT WORK with gs_b; must explicitly make bounds infinite # test_upper and test_lower DO WORK with gs_spending_bound gs_design_npe( theta = c(.1, .2, .3), info = (1:3) * 40, info0 = (1:3) * 40, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL), lower = gs_b, lpar = c(-1, -Inf, -Inf), test_upper = c(FALSE, TRUE, TRUE) ) # one can try `info_scale = "h1_info"` or `info_scale = "h0_info"` here gs_design_npe( theta = c(.1, .2, .3), info = (1:3) * 40, info0 = (1:3) * 30, info_scale = "h1_info", upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL), lower = gs_b, lpar = c(-1, -Inf, -Inf), test_upper = c(FALSE, TRUE, TRUE) ) # Example 4 ---- # Spending function bounds # 2-sided asymmetric bounds # Lower spending based on non-zero effect gs_design_npe( theta = c(.1, .2, .3), info = (1:3) * 40, info0 = (1:3) * 30, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL), lower = gs_spending_bound, lpar = list(sf = gsDesign::sfHSD, total_spend = 0.1, param = -1, timing = NULL) ) # Example 5 ---- # Two-sided symmetric spend, O'Brien-Fleming spending # Typically, 2-sided bounds are binding xx <- gs_design_npe( theta = c(.1, .2, .3), info = (1:3) * 40, binding = TRUE, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL), lower = gs_spending_bound, lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL) ) xx # Re-use these bounds under alternate hypothesis # Always use binding = TRUE for power calculations gs_power_npe( theta = c(.1, .2, .3), info = (1:3) * 40, binding = TRUE, upper = gs_b, lower = gs_b, upar = (xx %>% filter(bound == "upper"))$z, lpar = -(xx %>% filter(bound == "upper"))$z )
Group sequential design of binary outcome measuring in risk difference
gs_design_rd( p_c = tibble::tibble(stratum = "All", rate = 0.2), p_e = tibble::tibble(stratum = "All", rate = 0.15), info_frac = 1:3/3, rd0 = 0, alpha = 0.025, beta = 0.1, ratio = 1, stratum_prev = NULL, weight = c("unstratified", "ss", "invar"), upper = gs_b, lower = gs_b, upar = gsDesign(k = 3, test.type = 1, sfu = sfLDOF, sfupar = NULL)$upper$bound, lpar = c(qnorm(0.1), rep(-Inf, 2)), test_upper = TRUE, test_lower = TRUE, info_scale = c("h0_h1_info", "h0_info", "h1_info"), binding = FALSE, r = 18, tol = 1e-06, h1_spending = TRUE )
gs_design_rd( p_c = tibble::tibble(stratum = "All", rate = 0.2), p_e = tibble::tibble(stratum = "All", rate = 0.15), info_frac = 1:3/3, rd0 = 0, alpha = 0.025, beta = 0.1, ratio = 1, stratum_prev = NULL, weight = c("unstratified", "ss", "invar"), upper = gs_b, lower = gs_b, upar = gsDesign(k = 3, test.type = 1, sfu = sfLDOF, sfupar = NULL)$upper$bound, lpar = c(qnorm(0.1), rep(-Inf, 2)), test_upper = TRUE, test_lower = TRUE, info_scale = c("h0_h1_info", "h0_info", "h1_info"), binding = FALSE, r = 18, tol = 1e-06, h1_spending = TRUE )
p_c |
Rate at the control group. |
p_e |
Rate at the experimental group. |
info_frac |
Statistical information fraction. |
rd0 |
Treatment effect under super-superiority designs, the default is 0. |
alpha |
One-sided Type I error. |
beta |
Type II error. |
ratio |
Experimental:Control randomization ratio (not yet implemented). |
stratum_prev |
Randomization ratio of different stratum.
If it is unstratified design then |
weight |
The weighting scheme for stratified population. |
upper |
Function to compute upper bound. |
lower |
Function to compute lower bound. |
upar |
Parameters passed to |
lpar |
Parameters passed to |
test_upper |
Indicator of which analyses should include an upper
(efficacy) bound; single value of |
test_lower |
Indicator of which analyses should include an lower bound;
single value of |
info_scale |
Information scale for calculation. Options are:
|
binding |
Indicator of whether futility bound is binding;
default of |
r |
Integer value controlling grid for numerical integration
as in Jennison and Turnbull (2000); default is 18, range is 1 to 80.
Larger values provide larger number of grid points and greater accuracy.
Normally, |
tol |
Tolerance parameter for boundary convergence (on Z-scale). |
h1_spending |
Indicator that lower bound to be set by
spending under alternate hypothesis (input |
To be added.
A list with input parameters, analysis, and bound.
library(gsDesign) # Example 1 ---- # unstratified group sequential design x <- gs_design_rd( p_c = tibble::tibble(stratum = "All", rate = .2), p_e = tibble::tibble(stratum = "All", rate = .15), info_frac = c(0.7, 1), rd0 = 0, alpha = .025, beta = .1, ratio = 1, stratum_prev = NULL, weight = "unstratified", upper = gs_b, lower = gs_b, upar = gsDesign(k = 2, test.type = 1, sfu = sfLDOF, sfupar = NULL)$upper$bound, lpar = c(qnorm(.1), rep(-Inf, 2)) ) y <- gs_power_rd( p_c = tibble::tibble(stratum = "All", rate = .2), p_e = tibble::tibble(stratum = "All", rate = .15), n = tibble::tibble(stratum = "All", n = x$analysis$n, analysis = 1:2), rd0 = 0, ratio = 1, weight = "unstratified", upper = gs_b, lower = gs_b, upar = gsDesign(k = 2, test.type = 1, sfu = sfLDOF, sfupar = NULL)$upper$bound, lpar = c(qnorm(.1), rep(-Inf, 2)) ) # The above 2 design share the same power with the same sample size and treatment effect x$bound$probability[x$bound$bound == "upper" & x$bound$analysis == 2] y$bound$probability[y$bound$bound == "upper" & y$bound$analysis == 2] # Example 2 ---- # stratified group sequential design gs_design_rd( p_c = tibble::tibble( stratum = c("biomarker positive", "biomarker negative"), rate = c(.2, .25) ), p_e = tibble::tibble( stratum = c("biomarker positive", "biomarker negative"), rate = c(.15, .22) ), info_frac = c(0.7, 1), rd0 = 0, alpha = .025, beta = .1, ratio = 1, stratum_prev = tibble::tibble( stratum = c("biomarker positive", "biomarker negative"), prevalence = c(.4, .6) ), weight = "ss", upper = gs_spending_bound, lower = gs_b, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL), lpar = rep(-Inf, 2) )
library(gsDesign) # Example 1 ---- # unstratified group sequential design x <- gs_design_rd( p_c = tibble::tibble(stratum = "All", rate = .2), p_e = tibble::tibble(stratum = "All", rate = .15), info_frac = c(0.7, 1), rd0 = 0, alpha = .025, beta = .1, ratio = 1, stratum_prev = NULL, weight = "unstratified", upper = gs_b, lower = gs_b, upar = gsDesign(k = 2, test.type = 1, sfu = sfLDOF, sfupar = NULL)$upper$bound, lpar = c(qnorm(.1), rep(-Inf, 2)) ) y <- gs_power_rd( p_c = tibble::tibble(stratum = "All", rate = .2), p_e = tibble::tibble(stratum = "All", rate = .15), n = tibble::tibble(stratum = "All", n = x$analysis$n, analysis = 1:2), rd0 = 0, ratio = 1, weight = "unstratified", upper = gs_b, lower = gs_b, upar = gsDesign(k = 2, test.type = 1, sfu = sfLDOF, sfupar = NULL)$upper$bound, lpar = c(qnorm(.1), rep(-Inf, 2)) ) # The above 2 design share the same power with the same sample size and treatment effect x$bound$probability[x$bound$bound == "upper" & x$bound$analysis == 2] y$bound$probability[y$bound$bound == "upper" & y$bound$analysis == 2] # Example 2 ---- # stratified group sequential design gs_design_rd( p_c = tibble::tibble( stratum = c("biomarker positive", "biomarker negative"), rate = c(.2, .25) ), p_e = tibble::tibble( stratum = c("biomarker positive", "biomarker negative"), rate = c(.15, .22) ), info_frac = c(0.7, 1), rd0 = 0, alpha = .025, beta = .1, ratio = 1, stratum_prev = tibble::tibble( stratum = c("biomarker positive", "biomarker negative"), prevalence = c(.4, .6) ), weight = "ss", upper = gs_spending_bound, lower = gs_b, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL), lpar = rep(-Inf, 2) )
Group sequential design using weighted log-rank test under non-proportional hazards
gs_design_wlr( enroll_rate = define_enroll_rate(duration = c(2, 2, 10), rate = c(3, 6, 9)), fail_rate = tibble(stratum = "All", duration = c(3, 100), fail_rate = log(2)/c(9, 18), hr = c(0.9, 0.6), dropout_rate = rep(0.001, 2)), weight = wlr_weight_fh, approx = "asymptotic", alpha = 0.025, beta = 0.1, ratio = 1, info_frac = NULL, info_scale = c("h0_h1_info", "h0_info", "h1_info"), analysis_time = 36, binding = FALSE, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = alpha), lower = gs_spending_bound, lpar = list(sf = gsDesign::sfLDOF, total_spend = beta), test_upper = TRUE, test_lower = TRUE, h1_spending = TRUE, r = 18, tol = 1e-06, interval = c(0.01, 1000) )
gs_design_wlr( enroll_rate = define_enroll_rate(duration = c(2, 2, 10), rate = c(3, 6, 9)), fail_rate = tibble(stratum = "All", duration = c(3, 100), fail_rate = log(2)/c(9, 18), hr = c(0.9, 0.6), dropout_rate = rep(0.001, 2)), weight = wlr_weight_fh, approx = "asymptotic", alpha = 0.025, beta = 0.1, ratio = 1, info_frac = NULL, info_scale = c("h0_h1_info", "h0_info", "h1_info"), analysis_time = 36, binding = FALSE, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = alpha), lower = gs_spending_bound, lpar = list(sf = gsDesign::sfLDOF, total_spend = beta), test_upper = TRUE, test_lower = TRUE, h1_spending = TRUE, r = 18, tol = 1e-06, interval = c(0.01, 1000) )
enroll_rate |
Enrollment rates. |
fail_rate |
Failure and dropout rates. |
weight |
Weight of weighted log rank test:
|
approx |
Approximate estimation method for Z statistics.
|
alpha |
One-sided Type I error. |
beta |
Type II error. |
ratio |
Experimental:Control randomization ratio (not yet implemented). |
info_frac |
Targeted information fraction at each analysis. |
info_scale |
Information scale for calculation. Options are:
|
analysis_time |
Minimum time of analysis. |
binding |
Indicator of whether futility bound is binding;
default of |
upper |
Function to compute upper bound. |
upar |
Parameters passed to |
lower |
Function to compute lower bound. |
lpar |
Parameters passed to |
test_upper |
Indicator of which analyses should include an upper
(efficacy) bound; single value of |
test_lower |
Indicator of which analyses should include an lower bound;
single value of |
h1_spending |
Indicator that lower bound to be set by spending
under alternate hypothesis (input |
r |
Integer value controlling grid for numerical integration as in
Jennison and Turnbull (2000); default is 18, range is 1 to 80.
Larger values provide larger number of grid points and greater accuracy.
Normally, |
tol |
Tolerance parameter for boundary convergence (on Z-scale). |
interval |
An interval that is presumed to include the time at which expected event count is equal to targeted event. |
A list with input parameters, enrollment rate, analysis, and bound.
The contents of this section are shown in PDF user manual only.
library(dplyr) library(mvtnorm) library(gsDesign) library(gsDesign2) # set enrollment rates enroll_rate <- define_enroll_rate(duration = 12, rate = 1) # set failure rates fail_rate <- define_fail_rate( duration = c(4, 100), fail_rate = log(2) / 15, # median survival 15 month hr = c(1, .6), dropout_rate = 0.001 ) # Example 1 ---- # Information fraction driven design gs_design_wlr( enroll_rate = enroll_rate, fail_rate = fail_rate, ratio = 1, alpha = 0.025, beta = 0.2, weight = function(x, arm0, arm1) { wlr_weight_fh(x, arm0, arm1, rho = 0, gamma = 0.5) }, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025), lower = gs_spending_bound, lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.2), analysis_time = 36, info_frac = c(0.6, 1) ) # Example 2 ---- # Calendar time driven design gs_design_wlr( enroll_rate = enroll_rate, fail_rate = fail_rate, ratio = 1, alpha = 0.025, beta = 0.2, weight = function(x, arm0, arm1) { wlr_weight_fh(x, arm0, arm1, rho = 0, gamma = 0.5) }, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025), lower = gs_spending_bound, lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.2), analysis_time = c(24, 36), info_frac = NULL ) # Example 3 ---- # Both calendar time and information fraction driven design gs_design_wlr( enroll_rate = enroll_rate, fail_rate = fail_rate, ratio = 1, alpha = 0.025, beta = 0.2, weight = function(x, arm0, arm1) { wlr_weight_fh(x, arm0, arm1, rho = 0, gamma = 0.5) }, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025), lower = gs_spending_bound, lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.2), analysis_time = c(24, 36), info_frac = c(0.6, 1) )
library(dplyr) library(mvtnorm) library(gsDesign) library(gsDesign2) # set enrollment rates enroll_rate <- define_enroll_rate(duration = 12, rate = 1) # set failure rates fail_rate <- define_fail_rate( duration = c(4, 100), fail_rate = log(2) / 15, # median survival 15 month hr = c(1, .6), dropout_rate = 0.001 ) # Example 1 ---- # Information fraction driven design gs_design_wlr( enroll_rate = enroll_rate, fail_rate = fail_rate, ratio = 1, alpha = 0.025, beta = 0.2, weight = function(x, arm0, arm1) { wlr_weight_fh(x, arm0, arm1, rho = 0, gamma = 0.5) }, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025), lower = gs_spending_bound, lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.2), analysis_time = 36, info_frac = c(0.6, 1) ) # Example 2 ---- # Calendar time driven design gs_design_wlr( enroll_rate = enroll_rate, fail_rate = fail_rate, ratio = 1, alpha = 0.025, beta = 0.2, weight = function(x, arm0, arm1) { wlr_weight_fh(x, arm0, arm1, rho = 0, gamma = 0.5) }, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025), lower = gs_spending_bound, lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.2), analysis_time = c(24, 36), info_frac = NULL ) # Example 3 ---- # Both calendar time and information fraction driven design gs_design_wlr( enroll_rate = enroll_rate, fail_rate = fail_rate, ratio = 1, alpha = 0.025, beta = 0.2, weight = function(x, arm0, arm1) { wlr_weight_fh(x, arm0, arm1, rho = 0, gamma = 0.5) }, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025), lower = gs_spending_bound, lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.2), analysis_time = c(24, 36), info_frac = c(0.6, 1) )
Based on piecewise enrollment rate, failure rate, and dropout rates computes approximate information and effect size using an average hazard ratio model.
gs_info_ahr( enroll_rate = define_enroll_rate(duration = c(2, 2, 10), rate = c(3, 6, 9)), fail_rate = define_fail_rate(duration = c(3, 100), fail_rate = log(2)/c(9, 18), hr = c(0.9, 0.6), dropout_rate = 0.001), ratio = 1, event = NULL, analysis_time = NULL, interval = c(0.01, 1000) )
gs_info_ahr( enroll_rate = define_enroll_rate(duration = c(2, 2, 10), rate = c(3, 6, 9)), fail_rate = define_fail_rate(duration = c(3, 100), fail_rate = log(2)/c(9, 18), hr = c(0.9, 0.6), dropout_rate = 0.001), ratio = 1, event = NULL, analysis_time = NULL, interval = c(0.01, 1000) )
enroll_rate |
Enrollment rates from |
fail_rate |
Failure and dropout rates from |
ratio |
Experimental:Control randomization ratio. |
event |
Targeted minimum events at each analysis. |
analysis_time |
Targeted minimum study duration at each analysis. |
interval |
An interval that is presumed to include the time at which expected event count is equal to targeted event. |
The ahr()
function computes statistical information at targeted
event times. The expected_time()
function is used to get events and
average HR at targeted analysis_time
.
A data frame with columns analysis
, time
, ahr
, event
, theta
, info
, info0
.
The columns info
and info0
contain statistical information under H1, H0, respectively.
For analysis k
, time[k]
is the maximum of analysis_time[k]
and the
expected time required to accrue the targeted event[k]
.
ahr
is the expected average hazard ratio at each analysis.
The contents of this section are shown in PDF user manual only.
library(gsDesign) library(gsDesign2) # Example 1 ---- # Only put in targeted events gs_info_ahr(event = c(30, 40, 50)) # Example 2 ---- # Only put in targeted analysis times gs_info_ahr(analysis_time = c(18, 27, 36)) # Example 3 ---- # Some analysis times after time at which targeted event accrue # Check that both Time >= input analysis_time and event >= input event gs_info_ahr(event = c(30, 40, 50), analysis_time = c(16, 19, 26)) gs_info_ahr(event = c(30, 40, 50), analysis_time = c(14, 20, 24))
library(gsDesign) library(gsDesign2) # Example 1 ---- # Only put in targeted events gs_info_ahr(event = c(30, 40, 50)) # Example 2 ---- # Only put in targeted analysis times gs_info_ahr(analysis_time = c(18, 27, 36)) # Example 3 ---- # Some analysis times after time at which targeted event accrue # Check that both Time >= input analysis_time and event >= input event gs_info_ahr(event = c(30, 40, 50), analysis_time = c(16, 19, 26)) gs_info_ahr(event = c(30, 40, 50), analysis_time = c(14, 20, 24))
Information and effect size for MaxCombo test
gs_info_combo( enroll_rate = define_enroll_rate(duration = c(2, 2, 10), rate = c(3, 6, 9)), fail_rate = define_fail_rate(duration = c(3, 100), fail_rate = log(2)/c(9, 18), hr = c(0.9, 0.6), dropout_rate = 0.001), ratio = 1, event = NULL, analysis_time = NULL, rho, gamma, tau = rep(-1, length(rho)), approx = "asymptotic" )
gs_info_combo( enroll_rate = define_enroll_rate(duration = c(2, 2, 10), rate = c(3, 6, 9)), fail_rate = define_fail_rate(duration = c(3, 100), fail_rate = log(2)/c(9, 18), hr = c(0.9, 0.6), dropout_rate = 0.001), ratio = 1, event = NULL, analysis_time = NULL, rho, gamma, tau = rep(-1, length(rho)), approx = "asymptotic" )
enroll_rate |
An |
fail_rate |
A |
ratio |
Experimental:Control randomization ratio (not yet implemented). |
event |
Targeted events at each analysis. |
analysis_time |
Minimum time of analysis. |
rho |
Weighting parameters. |
gamma |
Weighting parameters. |
tau |
Weighting parameters. |
approx |
Approximation method. |
A tibble with columns as test index, analysis index, analysis time, sample size, number of events, ahr, delta, sigma2, theta, and statistical information.
gs_info_combo(rho = c(0, 0.5), gamma = c(0.5, 0), analysis_time = c(12, 24))
gs_info_combo(rho = c(0, 0.5), gamma = c(0.5, 0), analysis_time = c(12, 24))
Information and effect size under risk difference
gs_info_rd( p_c = tibble::tibble(stratum = "All", rate = 0.2), p_e = tibble::tibble(stratum = "All", rate = 0.15), n = tibble::tibble(stratum = "All", n = c(100, 200, 300), analysis = 1:3), rd0 = 0, ratio = 1, weight = c("unstratified", "ss", "invar") )
gs_info_rd( p_c = tibble::tibble(stratum = "All", rate = 0.2), p_e = tibble::tibble(stratum = "All", rate = 0.15), n = tibble::tibble(stratum = "All", n = c(100, 200, 300), analysis = 1:3), rd0 = 0, ratio = 1, weight = c("unstratified", "ss", "invar") )
p_c |
Rate at the control group. |
p_e |
Rate at the experimental group. |
n |
Sample size. |
rd0 |
The risk difference under H0. |
ratio |
Experimental:Control randomization ratio. |
weight |
Weighting method, can be |
A tibble with columns as analysis index, sample size, risk difference, risk difference under null hypothesis, theta1 (standardized treatment effect under alternative hypothesis), theta0 (standardized treatment effect under null hypothesis), and statistical information.
# Example 1 ---- # unstratified case with H0: rd0 = 0 gs_info_rd( p_c = tibble::tibble(stratum = "All", rate = .15), p_e = tibble::tibble(stratum = "All", rate = .1), n = tibble::tibble(stratum = "All", n = c(100, 200, 300), analysis = 1:3), rd0 = 0, ratio = 1 ) # Example 2 ---- # unstratified case with H0: rd0 != 0 gs_info_rd( p_c = tibble::tibble(stratum = "All", rate = .2), p_e = tibble::tibble(stratum = "All", rate = .15), n = tibble::tibble(stratum = "All", n = c(100, 200, 300), analysis = 1:3), rd0 = 0.005, ratio = 1 ) # Example 3 ---- # stratified case under sample size weighting and H0: rd0 = 0 gs_info_rd( p_c = tibble::tibble(stratum = c("S1", "S2", "S3"), rate = c(.15, .2, .25)), p_e = tibble::tibble(stratum = c("S1", "S2", "S3"), rate = c(.1, .16, .19)), n = tibble::tibble( stratum = rep(c("S1", "S2", "S3"), each = 3), analysis = rep(1:3, 3), n = c(50, 100, 200, 40, 80, 160, 60, 120, 240) ), rd0 = 0, ratio = 1, weight = "ss" ) # Example 4 ---- # stratified case under inverse variance weighting and H0: rd0 = 0 gs_info_rd( p_c = tibble::tibble( stratum = c("S1", "S2", "S3"), rate = c(.15, .2, .25) ), p_e = tibble::tibble( stratum = c("S1", "S2", "S3"), rate = c(.1, .16, .19) ), n = tibble::tibble( stratum = rep(c("S1", "S2", "S3"), each = 3), analysis = rep(1:3, 3), n = c(50, 100, 200, 40, 80, 160, 60, 120, 240) ), rd0 = 0, ratio = 1, weight = "invar" ) # Example 5 ---- # stratified case under sample size weighting and H0: rd0 != 0 gs_info_rd( p_c = tibble::tibble( stratum = c("S1", "S2", "S3"), rate = c(.15, .2, .25) ), p_e = tibble::tibble( stratum = c("S1", "S2", "S3"), rate = c(.1, .16, .19) ), n = tibble::tibble( stratum = rep(c("S1", "S2", "S3"), each = 3), analysis = rep(1:3, 3), n = c(50, 100, 200, 40, 80, 160, 60, 120, 240) ), rd0 = 0.02, ratio = 1, weight = "ss" ) # Example 6 ---- # stratified case under inverse variance weighting and H0: rd0 != 0 gs_info_rd( p_c = tibble::tibble( stratum = c("S1", "S2", "S3"), rate = c(.15, .2, .25) ), p_e = tibble::tibble( stratum = c("S1", "S2", "S3"), rate = c(.1, .16, .19) ), n = tibble::tibble( stratum = rep(c("S1", "S2", "S3"), each = 3), analysis = rep(1:3, 3), n = c(50, 100, 200, 40, 80, 160, 60, 120, 240) ), rd0 = 0.02, ratio = 1, weight = "invar" ) # Example 7 ---- # stratified case under inverse variance weighting and H0: rd0 != 0 and # rd0 difference for different statum gs_info_rd( p_c = tibble::tibble( stratum = c("S1", "S2", "S3"), rate = c(.15, .2, .25) ), p_e = tibble::tibble( stratum = c("S1", "S2", "S3"), rate = c(.1, .16, .19) ), n = tibble::tibble( stratum = rep(c("S1", "S2", "S3"), each = 3), analysis = rep(1:3, 3), n = c(50, 100, 200, 40, 80, 160, 60, 120, 240) ), rd0 = tibble::tibble( stratum = c("S1", "S2", "S3"), rd0 = c(0.01, 0.02, 0.03) ), ratio = 1, weight = "invar" )
# Example 1 ---- # unstratified case with H0: rd0 = 0 gs_info_rd( p_c = tibble::tibble(stratum = "All", rate = .15), p_e = tibble::tibble(stratum = "All", rate = .1), n = tibble::tibble(stratum = "All", n = c(100, 200, 300), analysis = 1:3), rd0 = 0, ratio = 1 ) # Example 2 ---- # unstratified case with H0: rd0 != 0 gs_info_rd( p_c = tibble::tibble(stratum = "All", rate = .2), p_e = tibble::tibble(stratum = "All", rate = .15), n = tibble::tibble(stratum = "All", n = c(100, 200, 300), analysis = 1:3), rd0 = 0.005, ratio = 1 ) # Example 3 ---- # stratified case under sample size weighting and H0: rd0 = 0 gs_info_rd( p_c = tibble::tibble(stratum = c("S1", "S2", "S3"), rate = c(.15, .2, .25)), p_e = tibble::tibble(stratum = c("S1", "S2", "S3"), rate = c(.1, .16, .19)), n = tibble::tibble( stratum = rep(c("S1", "S2", "S3"), each = 3), analysis = rep(1:3, 3), n = c(50, 100, 200, 40, 80, 160, 60, 120, 240) ), rd0 = 0, ratio = 1, weight = "ss" ) # Example 4 ---- # stratified case under inverse variance weighting and H0: rd0 = 0 gs_info_rd( p_c = tibble::tibble( stratum = c("S1", "S2", "S3"), rate = c(.15, .2, .25) ), p_e = tibble::tibble( stratum = c("S1", "S2", "S3"), rate = c(.1, .16, .19) ), n = tibble::tibble( stratum = rep(c("S1", "S2", "S3"), each = 3), analysis = rep(1:3, 3), n = c(50, 100, 200, 40, 80, 160, 60, 120, 240) ), rd0 = 0, ratio = 1, weight = "invar" ) # Example 5 ---- # stratified case under sample size weighting and H0: rd0 != 0 gs_info_rd( p_c = tibble::tibble( stratum = c("S1", "S2", "S3"), rate = c(.15, .2, .25) ), p_e = tibble::tibble( stratum = c("S1", "S2", "S3"), rate = c(.1, .16, .19) ), n = tibble::tibble( stratum = rep(c("S1", "S2", "S3"), each = 3), analysis = rep(1:3, 3), n = c(50, 100, 200, 40, 80, 160, 60, 120, 240) ), rd0 = 0.02, ratio = 1, weight = "ss" ) # Example 6 ---- # stratified case under inverse variance weighting and H0: rd0 != 0 gs_info_rd( p_c = tibble::tibble( stratum = c("S1", "S2", "S3"), rate = c(.15, .2, .25) ), p_e = tibble::tibble( stratum = c("S1", "S2", "S3"), rate = c(.1, .16, .19) ), n = tibble::tibble( stratum = rep(c("S1", "S2", "S3"), each = 3), analysis = rep(1:3, 3), n = c(50, 100, 200, 40, 80, 160, 60, 120, 240) ), rd0 = 0.02, ratio = 1, weight = "invar" ) # Example 7 ---- # stratified case under inverse variance weighting and H0: rd0 != 0 and # rd0 difference for different statum gs_info_rd( p_c = tibble::tibble( stratum = c("S1", "S2", "S3"), rate = c(.15, .2, .25) ), p_e = tibble::tibble( stratum = c("S1", "S2", "S3"), rate = c(.1, .16, .19) ), n = tibble::tibble( stratum = rep(c("S1", "S2", "S3"), each = 3), analysis = rep(1:3, 3), n = c(50, 100, 200, 40, 80, 160, 60, 120, 240) ), rd0 = tibble::tibble( stratum = c("S1", "S2", "S3"), rd0 = c(0.01, 0.02, 0.03) ), ratio = 1, weight = "invar" )
Based on piecewise enrollment rate, failure rate, and dropout rates computes approximate information and effect size using an average hazard ratio model.
gs_info_wlr( enroll_rate = define_enroll_rate(duration = c(2, 2, 10), rate = c(3, 6, 9)), fail_rate = define_fail_rate(duration = c(3, 100), fail_rate = log(2)/c(9, 18), hr = c(0.9, 0.6), dropout_rate = 0.001), ratio = 1, event = NULL, analysis_time = NULL, weight = wlr_weight_fh, approx = "asymptotic", interval = c(0.01, 1000) )
gs_info_wlr( enroll_rate = define_enroll_rate(duration = c(2, 2, 10), rate = c(3, 6, 9)), fail_rate = define_fail_rate(duration = c(3, 100), fail_rate = log(2)/c(9, 18), hr = c(0.9, 0.6), dropout_rate = 0.001), ratio = 1, event = NULL, analysis_time = NULL, weight = wlr_weight_fh, approx = "asymptotic", interval = c(0.01, 1000) )
enroll_rate |
An |
fail_rate |
Failure and dropout rates. |
ratio |
Experimental:Control randomization ratio. |
event |
Targeted minimum events at each analysis. |
analysis_time |
Targeted minimum study duration at each analysis. |
weight |
Weight of weighted log rank test:
|
approx |
Approximate estimation method for Z statistics.
|
interval |
An interval that is presumed to include the time at which expected event count is equal to targeted event. |
The ahr()
function computes statistical information at targeted event times.
The expected_time()
function is used to get events and average HR at
targeted analysis_time
.
A tibble with columns Analysis, Time, N, Events, AHR, delta, sigma2,
theta, info, info0.
info
and info0
contain statistical information under H1, H0, respectively.
For analysis k
, Time[k]
is the maximum of analysis_time[k]
and the
expected time required to accrue the targeted event[k]
.
AHR
is the expected average hazard ratio at each analysis.
library(gsDesign2) # Set enrollment rates enroll_rate <- define_enroll_rate(duration = 12, rate = 500 / 12) # Set failure rates fail_rate <- define_fail_rate( duration = c(4, 100), fail_rate = log(2) / 15, # median survival 15 month hr = c(1, .6), dropout_rate = 0.001 ) # Set the targeted number of events and analysis time event <- c(30, 40, 50) analysis_time <- c(10, 24, 30) gs_info_wlr( enroll_rate = enroll_rate, fail_rate = fail_rate, event = event, analysis_time = analysis_time )
library(gsDesign2) # Set enrollment rates enroll_rate <- define_enroll_rate(duration = 12, rate = 500 / 12) # Set failure rates fail_rate <- define_fail_rate( duration = c(4, 100), fail_rate = log(2) / 15, # median survival 15 month hr = c(1, .6), dropout_rate = 0.001 ) # Set the targeted number of events and analysis time event <- c(30, 40, 50) analysis_time <- c(10, 24, 30) gs_info_wlr( enroll_rate = enroll_rate, fail_rate = fail_rate, event = event, analysis_time = analysis_time )
Group sequential design power using average hazard ratio under non-proportional hazards.
gs_power_ahr( enroll_rate = define_enroll_rate(duration = c(2, 2, 10), rate = c(3, 6, 9)), fail_rate = define_fail_rate(duration = c(3, 100), fail_rate = log(2)/c(9, 18), hr = c(0.9, 0.6), dropout_rate = rep(0.001, 2)), event = c(30, 40, 50), analysis_time = NULL, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025), lower = gs_spending_bound, lpar = list(sf = gsDesign::sfLDOF, total_spend = NULL), test_lower = TRUE, test_upper = TRUE, ratio = 1, binding = FALSE, info_scale = c("h0_h1_info", "h0_info", "h1_info"), r = 18, tol = 1e-06, interval = c(0.01, 1000), integer = FALSE )
gs_power_ahr( enroll_rate = define_enroll_rate(duration = c(2, 2, 10), rate = c(3, 6, 9)), fail_rate = define_fail_rate(duration = c(3, 100), fail_rate = log(2)/c(9, 18), hr = c(0.9, 0.6), dropout_rate = rep(0.001, 2)), event = c(30, 40, 50), analysis_time = NULL, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025), lower = gs_spending_bound, lpar = list(sf = gsDesign::sfLDOF, total_spend = NULL), test_lower = TRUE, test_upper = TRUE, ratio = 1, binding = FALSE, info_scale = c("h0_h1_info", "h0_info", "h1_info"), r = 18, tol = 1e-06, interval = c(0.01, 1000), integer = FALSE )
enroll_rate |
An |
fail_rate |
Failure and dropout rates. |
event |
Targeted event at each analysis. |
analysis_time |
Minimum time of analysis. |
upper |
Function to compute upper bound. |
upar |
Parameters passed to |
lower |
Function to compute lower bound. |
lpar |
Parameters passed to |
test_lower |
Indicator of which analyses should include an lower bound;
single value of |
test_upper |
Indicator of which analyses should include an upper
(efficacy) bound; single value of |
ratio |
Experimental:Control randomization ratio (not yet implemented). |
binding |
Indicator of whether futility bound is binding;
default of |
info_scale |
Information scale for calculation. Options are:
|
r |
Integer value controlling grid for numerical integration as in
Jennison and Turnbull (2000); default is 18, range is 1 to 80.
Larger values provide larger number of grid points and greater accuracy.
Normally, |
tol |
Tolerance parameter for boundary convergence (on Z-scale). |
interval |
An interval that is presumed to include the time at which expected event count is equal to targeted event. |
integer |
Logical value integer whether it is an integer design
(i.e., integer sample size and events) or not. This argument is commonly
used when creating integer design via |
Bound satisfy input upper bound specification in
upper
, upar
, and lower bound specification in lower
, lpar
.
ahr()
computes statistical information at targeted event times.
The expected_time()
function is used to get events and average HR at
targeted analysis_time
.
A tibble with columns analysis
, bound
, z
, probability
,
theta
, time
, ahr
, event
.
Contains a row for each analysis and each bound.
The contents of this section are shown in PDF user manual only.
library(gsDesign2) library(dplyr) # Example 1 ---- # The default output of `gs_power_ahr()` is driven by events, # i.e., `event = c(30, 40, 50)`, `analysis_time = NULL` gs_power_ahr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) # Example 2 ---- # 2-sided symmetric O'Brien-Fleming spending bound, driven by analysis time, # i.e., `event = NULL`, `analysis_time = c(12, 24, 36)` gs_power_ahr( analysis_time = c(12, 24, 36), event = NULL, binding = TRUE, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025), lower = gs_spending_bound, lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.025) ) # Example 3 ---- # 2-sided symmetric O'Brien-Fleming spending bound, driven by event, # i.e., `event = c(20, 50, 70)`, `analysis_time = NULL` gs_power_ahr( analysis_time = NULL, event = c(20, 50, 70), binding = TRUE, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025), lower = gs_spending_bound, lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.025) ) # Example 4 ---- # 2-sided symmetric O'Brien-Fleming spending bound, # driven by both `event` and `analysis_time`, i.e., # both `event` and `analysis_time` are not `NULL`, # then the analysis will driven by the maximal one, i.e., # Time = max(analysis_time, calculated Time for targeted event) # Events = max(events, calculated events for targeted analysis_time) gs_power_ahr( analysis_time = c(12, 24, 36), event = c(30, 40, 50), binding = TRUE, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025), lower = gs_spending_bound, lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.025) )
library(gsDesign2) library(dplyr) # Example 1 ---- # The default output of `gs_power_ahr()` is driven by events, # i.e., `event = c(30, 40, 50)`, `analysis_time = NULL` gs_power_ahr(lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.1)) # Example 2 ---- # 2-sided symmetric O'Brien-Fleming spending bound, driven by analysis time, # i.e., `event = NULL`, `analysis_time = c(12, 24, 36)` gs_power_ahr( analysis_time = c(12, 24, 36), event = NULL, binding = TRUE, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025), lower = gs_spending_bound, lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.025) ) # Example 3 ---- # 2-sided symmetric O'Brien-Fleming spending bound, driven by event, # i.e., `event = c(20, 50, 70)`, `analysis_time = NULL` gs_power_ahr( analysis_time = NULL, event = c(20, 50, 70), binding = TRUE, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025), lower = gs_spending_bound, lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.025) ) # Example 4 ---- # 2-sided symmetric O'Brien-Fleming spending bound, # driven by both `event` and `analysis_time`, i.e., # both `event` and `analysis_time` are not `NULL`, # then the analysis will driven by the maximal one, i.e., # Time = max(analysis_time, calculated Time for targeted event) # Events = max(events, calculated events for targeted analysis_time) gs_power_ahr( analysis_time = c(12, 24, 36), event = c(30, 40, 50), binding = TRUE, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025), lower = gs_spending_bound, lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.025) )
Group sequential design power using MaxCombo test under non-proportional hazards
gs_power_combo( enroll_rate = define_enroll_rate(duration = 12, rate = 500/12), fail_rate = define_fail_rate(duration = c(4, 100), fail_rate = log(2)/15, hr = c(1, 0.6), dropout_rate = 0.001), fh_test = rbind(data.frame(rho = 0, gamma = 0, tau = -1, test = 1, analysis = 1:3, analysis_time = c(12, 24, 36)), data.frame(rho = c(0, 0.5), gamma = 0.5, tau = -1, test = 2:3, analysis = 3, analysis_time = 36)), ratio = 1, binding = FALSE, upper = gs_b, upar = c(3, 2, 1), lower = gs_b, lpar = c(-1, 0, 1), algorithm = mvtnorm::GenzBretz(maxpts = 1e+05, abseps = 1e-05), ... )
gs_power_combo( enroll_rate = define_enroll_rate(duration = 12, rate = 500/12), fail_rate = define_fail_rate(duration = c(4, 100), fail_rate = log(2)/15, hr = c(1, 0.6), dropout_rate = 0.001), fh_test = rbind(data.frame(rho = 0, gamma = 0, tau = -1, test = 1, analysis = 1:3, analysis_time = c(12, 24, 36)), data.frame(rho = c(0, 0.5), gamma = 0.5, tau = -1, test = 2:3, analysis = 3, analysis_time = 36)), ratio = 1, binding = FALSE, upper = gs_b, upar = c(3, 2, 1), lower = gs_b, lpar = c(-1, 0, 1), algorithm = mvtnorm::GenzBretz(maxpts = 1e+05, abseps = 1e-05), ... )
enroll_rate |
Enrollment rates. |
fail_rate |
Failure and dropout rates. |
fh_test |
A data frame to summarize the test in each analysis. See examples for its data structure. |
ratio |
Experimental:Control randomization ratio (not yet implemented). |
binding |
Indicator of whether futility bound is binding;
default of |
upper |
Function to compute upper bound. |
upar |
Parameters passed to |
lower |
Function to compute lower bound. |
lpar |
Parameters passed to |
algorithm |
an object of class |
... |
Additional parameters passed to mvtnorm::pmvnorm. |
A list with input parameters, enrollment rate, analysis, and bound.
The contents of this section are shown in PDF user manual only.
library(dplyr) library(mvtnorm) library(gsDesign) library(gsDesign2) enroll_rate <- define_enroll_rate( duration = 12, rate = 500 / 12 ) fail_rate <- define_fail_rate( duration = c(4, 100), fail_rate = log(2) / 15, # median survival 15 month hr = c(1, .6), dropout_rate = 0.001 ) fh_test <- rbind( data.frame(rho = 0, gamma = 0, tau = -1, test = 1, analysis = 1:3, analysis_time = c(12, 24, 36)), data.frame(rho = c(0, 0.5), gamma = 0.5, tau = -1, test = 2:3, analysis = 3, analysis_time = 36) ) # Example 1 ---- # Minimal Information Fraction derived bound gs_power_combo( enroll_rate = enroll_rate, fail_rate = fail_rate, fh_test = fh_test, upper = gs_spending_combo, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025), lower = gs_spending_combo, lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.2) )
library(dplyr) library(mvtnorm) library(gsDesign) library(gsDesign2) enroll_rate <- define_enroll_rate( duration = 12, rate = 500 / 12 ) fail_rate <- define_fail_rate( duration = c(4, 100), fail_rate = log(2) / 15, # median survival 15 month hr = c(1, .6), dropout_rate = 0.001 ) fh_test <- rbind( data.frame(rho = 0, gamma = 0, tau = -1, test = 1, analysis = 1:3, analysis_time = c(12, 24, 36)), data.frame(rho = c(0, 0.5), gamma = 0.5, tau = -1, test = 2:3, analysis = 3, analysis_time = 36) ) # Example 1 ---- # Minimal Information Fraction derived bound gs_power_combo( enroll_rate = enroll_rate, fail_rate = fail_rate, fh_test = fh_test, upper = gs_spending_combo, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025), lower = gs_spending_combo, lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.2) )
Derives group sequential bounds and boundary crossing probabilities for a design. It allows a non-constant treatment effect over time, but also can be applied for the usual homogeneous effect size designs. It requires treatment effect and statistical information at each analysis as well as a method of deriving bounds, such as spending. The routine enables two things not available in the gsDesign package:
non-constant effect, 2) more flexibility in boundary selection.
For many applications, the non-proportional-hazards design function
gs_design_nph()
will be used; it calls this function.
Initial bound types supported are 1) spending bounds,
fixed bounds, and 3) Haybittle-Peto-like bounds.
The requirement is to have a boundary update method that can
each bound without knowledge of future bounds.
As an example, bounds based on conditional power that require
knowledge of all future bounds are not supported by this routine;
a more limited conditional power method will be demonstrated.
Boundary family designs Wang-Tsiatis designs including the
original (non-spending-function-based) O'Brien-Fleming and Pocock designs
are not supported by gs_power_npe()
.
gs_power_npe( theta = 0.1, theta0 = NULL, theta1 = NULL, info = 1, info0 = NULL, info1 = NULL, info_scale = c("h0_h1_info", "h0_info", "h1_info"), upper = gs_b, upar = qnorm(0.975), lower = gs_b, lpar = -Inf, test_upper = TRUE, test_lower = TRUE, binding = FALSE, r = 18, tol = 1e-06 )
gs_power_npe( theta = 0.1, theta0 = NULL, theta1 = NULL, info = 1, info0 = NULL, info1 = NULL, info_scale = c("h0_h1_info", "h0_info", "h1_info"), upper = gs_b, upar = qnorm(0.975), lower = gs_b, lpar = -Inf, test_upper = TRUE, test_lower = TRUE, binding = FALSE, r = 18, tol = 1e-06 )
theta |
Natural parameter for group sequential design representing expected incremental drift at all analyses; used for power calculation. |
theta0 |
Natural parameter for null hypothesis, if needed for upper bound computation. |
theta1 |
Natural parameter for alternate hypothesis, if needed for lower bound computation. |
info |
Statistical information at all analyses for input |
info0 |
Statistical information under null hypothesis,
if different than |
info1 |
Statistical information under hypothesis used for
futility bound calculation if different from
|
info_scale |
Information scale for calculation. Options are:
|
upper |
Function to compute upper bound. |
upar |
Parameters passed to |
lower |
Function to compare lower bound. |
lpar |
parameters passed to |
test_upper |
Indicator of which analyses should include
an upper (efficacy) bound;
single value of |
test_lower |
Indicator of which analyses should include a lower bound;
single value of |
binding |
Indicator of whether futility bound is binding;
default of |
r |
Integer value controlling grid for numerical integration as in
Jennison and Turnbull (2000); default is 18, range is 1 to 80.
Larger values provide larger number of grid points and greater accuracy.
Normally, |
tol |
Tolerance parameter for boundary convergence (on Z-scale). |
A tibble with columns as analysis index, bounds, z, crossing probability, theta (standardized treatment effect), theta1 (standardized treatment effect under alternative hypothesis), information fraction, and statistical information.
The contents of this section are shown in PDF user manual only.
library(gsDesign) library(gsDesign2) library(dplyr) # Default (single analysis; Type I error controlled) gs_power_npe(theta = 0) %>% filter(bound == "upper") # Fixed bound gs_power_npe( theta = c(.1, .2, .3), info = (1:3) * 40, upper = gs_b, upar = gsDesign::gsDesign(k = 3, sfu = gsDesign::sfLDOF)$upper$bound, lower = gs_b, lpar = c(-1, 0, 0) ) # Same fixed efficacy bounds, no futility bound (i.e., non-binding bound), null hypothesis gs_power_npe( theta = rep(0, 3), info = (1:3) * 40, upar = gsDesign::gsDesign(k = 3, sfu = gsDesign::sfLDOF)$upper$bound, lpar = rep(-Inf, 3) ) %>% filter(bound == "upper") # Fixed bound with futility only at analysis 1; efficacy only at analyses 2, 3 gs_power_npe( theta = c(.1, .2, .3), info = (1:3) * 40, upper = gs_b, upar = c(Inf, 3, 2), lower = gs_b, lpar = c(qnorm(.1), -Inf, -Inf) ) # Spending function bounds # Lower spending based on non-zero effect gs_power_npe( theta = c(.1, .2, .3), info = (1:3) * 40, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL), lower = gs_spending_bound, lpar = list(sf = gsDesign::sfHSD, total_spend = 0.1, param = -1, timing = NULL) ) # Same bounds, but power under different theta gs_power_npe( theta = c(.15, .25, .35), info = (1:3) * 40, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL), lower = gs_spending_bound, lpar = list(sf = gsDesign::sfHSD, total_spend = 0.1, param = -1, timing = NULL) ) # Two-sided symmetric spend, O'Brien-Fleming spending # Typically, 2-sided bounds are binding x <- gs_power_npe( theta = rep(0, 3), info = (1:3) * 40, binding = TRUE, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL), lower = gs_spending_bound, lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL) ) # Re-use these bounds under alternate hypothesis # Always use binding = TRUE for power calculations gs_power_npe( theta = c(.1, .2, .3), info = (1:3) * 40, binding = TRUE, upar = (x %>% filter(bound == "upper"))$z, lpar = -(x %>% filter(bound == "upper"))$z ) # Different values of `r` and `tol` lead to different numerical accuracy # Larger `r` and smaller `tol` give better accuracy, but leads to slow computation n_analysis <- 5 gs_power_npe( theta = rep(0.1, n_analysis), theta0 = NULL, theta1 = NULL, info = 1:n_analysis, info0 = 1:n_analysis, info1 = NULL, info_scale = "h0_info", upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL), lower = gs_b, lpar = -rep(Inf, n_analysis), test_upper = TRUE, test_lower = FALSE, binding = FALSE, # Try different combinations of (r, tol) with # r in 6, 18, 24, 30, 35, 40, 50, 60, 70, 80, 90, 100 # tol in 1e-6, 1e-12 r = 6, tol = 1e-6 )
library(gsDesign) library(gsDesign2) library(dplyr) # Default (single analysis; Type I error controlled) gs_power_npe(theta = 0) %>% filter(bound == "upper") # Fixed bound gs_power_npe( theta = c(.1, .2, .3), info = (1:3) * 40, upper = gs_b, upar = gsDesign::gsDesign(k = 3, sfu = gsDesign::sfLDOF)$upper$bound, lower = gs_b, lpar = c(-1, 0, 0) ) # Same fixed efficacy bounds, no futility bound (i.e., non-binding bound), null hypothesis gs_power_npe( theta = rep(0, 3), info = (1:3) * 40, upar = gsDesign::gsDesign(k = 3, sfu = gsDesign::sfLDOF)$upper$bound, lpar = rep(-Inf, 3) ) %>% filter(bound == "upper") # Fixed bound with futility only at analysis 1; efficacy only at analyses 2, 3 gs_power_npe( theta = c(.1, .2, .3), info = (1:3) * 40, upper = gs_b, upar = c(Inf, 3, 2), lower = gs_b, lpar = c(qnorm(.1), -Inf, -Inf) ) # Spending function bounds # Lower spending based on non-zero effect gs_power_npe( theta = c(.1, .2, .3), info = (1:3) * 40, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL), lower = gs_spending_bound, lpar = list(sf = gsDesign::sfHSD, total_spend = 0.1, param = -1, timing = NULL) ) # Same bounds, but power under different theta gs_power_npe( theta = c(.15, .25, .35), info = (1:3) * 40, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL), lower = gs_spending_bound, lpar = list(sf = gsDesign::sfHSD, total_spend = 0.1, param = -1, timing = NULL) ) # Two-sided symmetric spend, O'Brien-Fleming spending # Typically, 2-sided bounds are binding x <- gs_power_npe( theta = rep(0, 3), info = (1:3) * 40, binding = TRUE, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL), lower = gs_spending_bound, lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL) ) # Re-use these bounds under alternate hypothesis # Always use binding = TRUE for power calculations gs_power_npe( theta = c(.1, .2, .3), info = (1:3) * 40, binding = TRUE, upar = (x %>% filter(bound == "upper"))$z, lpar = -(x %>% filter(bound == "upper"))$z ) # Different values of `r` and `tol` lead to different numerical accuracy # Larger `r` and smaller `tol` give better accuracy, but leads to slow computation n_analysis <- 5 gs_power_npe( theta = rep(0.1, n_analysis), theta0 = NULL, theta1 = NULL, info = 1:n_analysis, info0 = 1:n_analysis, info1 = NULL, info_scale = "h0_info", upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL), lower = gs_b, lpar = -rep(Inf, n_analysis), test_upper = TRUE, test_lower = FALSE, binding = FALSE, # Try different combinations of (r, tol) with # r in 6, 18, 24, 30, 35, 40, 50, 60, 70, 80, 90, 100 # tol in 1e-6, 1e-12 r = 6, tol = 1e-6 )
Group sequential design power of binary outcome measuring in risk difference
gs_power_rd( p_c = tibble::tibble(stratum = "All", rate = 0.2), p_e = tibble::tibble(stratum = "All", rate = 0.15), n = tibble::tibble(stratum = "All", n = c(40, 50, 60), analysis = 1:3), rd0 = 0, ratio = 1, weight = c("unstratified", "ss", "invar"), upper = gs_b, lower = gs_b, upar = gsDesign(k = 3, test.type = 1, sfu = sfLDOF, sfupar = NULL)$upper$bound, lpar = c(qnorm(0.1), rep(-Inf, 2)), info_scale = c("h0_h1_info", "h0_info", "h1_info"), binding = FALSE, test_upper = TRUE, test_lower = TRUE, r = 18, tol = 1e-06 )
gs_power_rd( p_c = tibble::tibble(stratum = "All", rate = 0.2), p_e = tibble::tibble(stratum = "All", rate = 0.15), n = tibble::tibble(stratum = "All", n = c(40, 50, 60), analysis = 1:3), rd0 = 0, ratio = 1, weight = c("unstratified", "ss", "invar"), upper = gs_b, lower = gs_b, upar = gsDesign(k = 3, test.type = 1, sfu = sfLDOF, sfupar = NULL)$upper$bound, lpar = c(qnorm(0.1), rep(-Inf, 2)), info_scale = c("h0_h1_info", "h0_info", "h1_info"), binding = FALSE, test_upper = TRUE, test_lower = TRUE, r = 18, tol = 1e-06 )
p_c |
Rate at the control group. |
p_e |
Rate at the experimental group. |
n |
Sample size. |
rd0 |
Treatment effect under super-superiority designs, the default is 0. |
ratio |
Experimental:control randomization ratio. |
weight |
Weighting method, can be |
upper |
Function to compute upper bound. |
lower |
Function to compare lower bound. |
upar |
Parameters passed to |
lpar |
Parameters passed to |
info_scale |
Information scale for calculation. Options are:
|
binding |
Indicator of whether futility bound is binding;
default of |
test_upper |
Indicator of which analyses should include an upper
(efficacy) bound; single value of |
test_lower |
Indicator of which analyses should include a lower bound;
single value of |
r |
Integer value controlling grid for numerical integration as in
Jennison and Turnbull (2000); default is 18, range is 1 to 80.
Larger values provide larger number of grid points and greater accuracy.
Normally, |
tol |
Tolerance parameter for boundary convergence (on Z-scale). |
A list with input parameter, analysis, and bound.
# Example 1 ---- library(gsDesign) # unstratified case with H0: rd0 = 0 gs_power_rd( p_c = tibble::tibble( stratum = "All", rate = .2 ), p_e = tibble::tibble( stratum = "All", rate = .15 ), n = tibble::tibble( stratum = "All", n = c(20, 40, 60), analysis = 1:3 ), rd0 = 0, ratio = 1, upper = gs_b, lower = gs_b, upar = gsDesign(k = 3, test.type = 1, sfu = sfLDOF, sfupar = NULL)$upper$bound, lpar = c(qnorm(.1), rep(-Inf, 2)) ) # Example 2 ---- # unstratified case with H0: rd0 != 0 gs_power_rd( p_c = tibble::tibble( stratum = "All", rate = .2 ), p_e = tibble::tibble( stratum = "All", rate = .15 ), n = tibble::tibble( stratum = "All", n = c(20, 40, 60), analysis = 1:3 ), rd0 = 0.005, ratio = 1, upper = gs_b, lower = gs_b, upar = gsDesign(k = 3, test.type = 1, sfu = sfLDOF, sfupar = NULL)$upper$bound, lpar = c(qnorm(.1), rep(-Inf, 2)) ) # use spending function gs_power_rd( p_c = tibble::tibble( stratum = "All", rate = .2 ), p_e = tibble::tibble( stratum = "All", rate = .15 ), n = tibble::tibble( stratum = "All", n = c(20, 40, 60), analysis = 1:3 ), rd0 = 0.005, ratio = 1, upper = gs_spending_bound, lower = gs_b, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL), lpar = c(qnorm(.1), rep(-Inf, 2)) ) # Example 3 ---- # stratified case under sample size weighting and H0: rd0 = 0 gs_power_rd( p_c = tibble::tibble( stratum = c("S1", "S2", "S3"), rate = c(.15, .2, .25) ), p_e = tibble::tibble( stratum = c("S1", "S2", "S3"), rate = c(.1, .16, .19) ), n = tibble::tibble( stratum = rep(c("S1", "S2", "S3"), each = 3), analysis = rep(1:3, 3), n = c(10, 20, 24, 18, 26, 30, 10, 20, 24) ), rd0 = 0, ratio = 1, weight = "ss", upper = gs_b, lower = gs_b, upar = gsDesign(k = 3, test.type = 1, sfu = sfLDOF, sfupar = NULL)$upper$bound, lpar = c(qnorm(.1), rep(-Inf, 2)) ) # Example 4 ---- # stratified case under inverse variance weighting and H0: rd0 = 0 gs_power_rd( p_c = tibble::tibble( stratum = c("S1", "S2", "S3"), rate = c(.15, .2, .25) ), p_e = tibble::tibble( stratum = c("S1", "S2", "S3"), rate = c(.1, .16, .19) ), n = tibble::tibble( stratum = rep(c("S1", "S2", "S3"), each = 3), analysis = rep(1:3, 3), n = c(10, 20, 24, 18, 26, 30, 10, 20, 24) ), rd0 = 0, ratio = 1, weight = "invar", upper = gs_b, lower = gs_b, upar = gsDesign(k = 3, test.type = 1, sfu = sfLDOF, sfupar = NULL)$upper$bound, lpar = c(qnorm(.1), rep(-Inf, 2)) ) # Example 5 ---- # stratified case under sample size weighting and H0: rd0 != 0 gs_power_rd( p_c = tibble::tibble( stratum = c("S1", "S2", "S3"), rate = c(.15, .2, .25) ), p_e = tibble::tibble( stratum = c("S1", "S2", "S3"), rate = c(.1, .16, .19) ), n = tibble::tibble( stratum = rep(c("S1", "S2", "S3"), each = 3), analysis = rep(1:3, 3), n = c(10, 20, 24, 18, 26, 30, 10, 20, 24) ), rd0 = 0.02, ratio = 1, weight = "ss", upper = gs_b, lower = gs_b, upar = gsDesign(k = 3, test.type = 1, sfu = sfLDOF, sfupar = NULL)$upper$bound, lpar = c(qnorm(.1), rep(-Inf, 2)) ) # Example 6 ---- # stratified case under inverse variance weighting and H0: rd0 != 0 gs_power_rd( p_c = tibble::tibble( stratum = c("S1", "S2", "S3"), rate = c(.15, .2, .25) ), p_e = tibble::tibble( stratum = c("S1", "S2", "S3"), rate = c(.1, .16, .19) ), n = tibble::tibble( stratum = rep(c("S1", "S2", "S3"), each = 3), analysis = rep(1:3, 3), n = c(10, 20, 24, 18, 26, 30, 10, 20, 24) ), rd0 = 0.03, ratio = 1, weight = "invar", upper = gs_b, lower = gs_b, upar = gsDesign(k = 3, test.type = 1, sfu = sfLDOF, sfupar = NULL)$upper$bound, lpar = c(qnorm(.1), rep(-Inf, 2)) )
# Example 1 ---- library(gsDesign) # unstratified case with H0: rd0 = 0 gs_power_rd( p_c = tibble::tibble( stratum = "All", rate = .2 ), p_e = tibble::tibble( stratum = "All", rate = .15 ), n = tibble::tibble( stratum = "All", n = c(20, 40, 60), analysis = 1:3 ), rd0 = 0, ratio = 1, upper = gs_b, lower = gs_b, upar = gsDesign(k = 3, test.type = 1, sfu = sfLDOF, sfupar = NULL)$upper$bound, lpar = c(qnorm(.1), rep(-Inf, 2)) ) # Example 2 ---- # unstratified case with H0: rd0 != 0 gs_power_rd( p_c = tibble::tibble( stratum = "All", rate = .2 ), p_e = tibble::tibble( stratum = "All", rate = .15 ), n = tibble::tibble( stratum = "All", n = c(20, 40, 60), analysis = 1:3 ), rd0 = 0.005, ratio = 1, upper = gs_b, lower = gs_b, upar = gsDesign(k = 3, test.type = 1, sfu = sfLDOF, sfupar = NULL)$upper$bound, lpar = c(qnorm(.1), rep(-Inf, 2)) ) # use spending function gs_power_rd( p_c = tibble::tibble( stratum = "All", rate = .2 ), p_e = tibble::tibble( stratum = "All", rate = .15 ), n = tibble::tibble( stratum = "All", n = c(20, 40, 60), analysis = 1:3 ), rd0 = 0.005, ratio = 1, upper = gs_spending_bound, lower = gs_b, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL), lpar = c(qnorm(.1), rep(-Inf, 2)) ) # Example 3 ---- # stratified case under sample size weighting and H0: rd0 = 0 gs_power_rd( p_c = tibble::tibble( stratum = c("S1", "S2", "S3"), rate = c(.15, .2, .25) ), p_e = tibble::tibble( stratum = c("S1", "S2", "S3"), rate = c(.1, .16, .19) ), n = tibble::tibble( stratum = rep(c("S1", "S2", "S3"), each = 3), analysis = rep(1:3, 3), n = c(10, 20, 24, 18, 26, 30, 10, 20, 24) ), rd0 = 0, ratio = 1, weight = "ss", upper = gs_b, lower = gs_b, upar = gsDesign(k = 3, test.type = 1, sfu = sfLDOF, sfupar = NULL)$upper$bound, lpar = c(qnorm(.1), rep(-Inf, 2)) ) # Example 4 ---- # stratified case under inverse variance weighting and H0: rd0 = 0 gs_power_rd( p_c = tibble::tibble( stratum = c("S1", "S2", "S3"), rate = c(.15, .2, .25) ), p_e = tibble::tibble( stratum = c("S1", "S2", "S3"), rate = c(.1, .16, .19) ), n = tibble::tibble( stratum = rep(c("S1", "S2", "S3"), each = 3), analysis = rep(1:3, 3), n = c(10, 20, 24, 18, 26, 30, 10, 20, 24) ), rd0 = 0, ratio = 1, weight = "invar", upper = gs_b, lower = gs_b, upar = gsDesign(k = 3, test.type = 1, sfu = sfLDOF, sfupar = NULL)$upper$bound, lpar = c(qnorm(.1), rep(-Inf, 2)) ) # Example 5 ---- # stratified case under sample size weighting and H0: rd0 != 0 gs_power_rd( p_c = tibble::tibble( stratum = c("S1", "S2", "S3"), rate = c(.15, .2, .25) ), p_e = tibble::tibble( stratum = c("S1", "S2", "S3"), rate = c(.1, .16, .19) ), n = tibble::tibble( stratum = rep(c("S1", "S2", "S3"), each = 3), analysis = rep(1:3, 3), n = c(10, 20, 24, 18, 26, 30, 10, 20, 24) ), rd0 = 0.02, ratio = 1, weight = "ss", upper = gs_b, lower = gs_b, upar = gsDesign(k = 3, test.type = 1, sfu = sfLDOF, sfupar = NULL)$upper$bound, lpar = c(qnorm(.1), rep(-Inf, 2)) ) # Example 6 ---- # stratified case under inverse variance weighting and H0: rd0 != 0 gs_power_rd( p_c = tibble::tibble( stratum = c("S1", "S2", "S3"), rate = c(.15, .2, .25) ), p_e = tibble::tibble( stratum = c("S1", "S2", "S3"), rate = c(.1, .16, .19) ), n = tibble::tibble( stratum = rep(c("S1", "S2", "S3"), each = 3), analysis = rep(1:3, 3), n = c(10, 20, 24, 18, 26, 30, 10, 20, 24) ), rd0 = 0.03, ratio = 1, weight = "invar", upper = gs_b, lower = gs_b, upar = gsDesign(k = 3, test.type = 1, sfu = sfLDOF, sfupar = NULL)$upper$bound, lpar = c(qnorm(.1), rep(-Inf, 2)) )
Group sequential design power using weighted log rank test under non-proportional hazards
gs_power_wlr( enroll_rate = define_enroll_rate(duration = c(2, 2, 10), rate = c(3, 6, 9)), fail_rate = tibble(stratum = "All", duration = c(3, 100), fail_rate = log(2)/c(9, 18), hr = c(0.9, 0.6), dropout_rate = rep(0.001, 2)), event = c(30, 40, 50), analysis_time = NULL, binding = FALSE, upper = gs_spending_bound, lower = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025), lpar = list(sf = gsDesign::sfLDOF, total_spend = NULL), test_upper = TRUE, test_lower = TRUE, ratio = 1, weight = wlr_weight_fh, info_scale = c("h0_h1_info", "h0_info", "h1_info"), approx = "asymptotic", r = 18, tol = 1e-06, interval = c(0.01, 1000), integer = FALSE )
gs_power_wlr( enroll_rate = define_enroll_rate(duration = c(2, 2, 10), rate = c(3, 6, 9)), fail_rate = tibble(stratum = "All", duration = c(3, 100), fail_rate = log(2)/c(9, 18), hr = c(0.9, 0.6), dropout_rate = rep(0.001, 2)), event = c(30, 40, 50), analysis_time = NULL, binding = FALSE, upper = gs_spending_bound, lower = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025), lpar = list(sf = gsDesign::sfLDOF, total_spend = NULL), test_upper = TRUE, test_lower = TRUE, ratio = 1, weight = wlr_weight_fh, info_scale = c("h0_h1_info", "h0_info", "h1_info"), approx = "asymptotic", r = 18, tol = 1e-06, interval = c(0.01, 1000), integer = FALSE )
enroll_rate |
Enrollment rates. |
fail_rate |
Failure and dropout rates. |
event |
Targeted event at each analysis. |
analysis_time |
Minimum time of analysis. |
binding |
Indicator of whether futility bound is binding;
default of |
upper |
Function to compute upper bound. |
lower |
Function to compute lower bound. |
upar |
Parameters passed to |
lpar |
Parameters passed to |
test_upper |
Indicator of which analyses should include an upper
(efficacy) bound; single value of |
test_lower |
Indicator of which analyses should include an lower bound;
single value of |
ratio |
Experimental:Control randomization ratio (not yet implemented). |
weight |
Weight of weighted log rank test:
|
info_scale |
Information scale for calculation. Options are:
|
approx |
Approximate estimation method for Z statistics.
|
r |
Integer value controlling grid for numerical integration as in
Jennison and Turnbull (2000); default is 18, range is 1 to 80.
Larger values provide larger number of grid points and greater accuracy.
Normally, |
tol |
Tolerance parameter for boundary convergence (on Z-scale). |
interval |
An interval that is presumed to include the time at which expected event count is equal to targeted event. |
integer |
Logical value integer whether it is an integer design
(i.e., integer sample size and events) or not. This argument is commonly
used when creating integer design via |
A list with input parameters, enrollment rate, analysis, and bound.
The contents of this section are shown in PDF user manual only.
library(gsDesign) library(gsDesign2) # set enrollment rates enroll_rate <- define_enroll_rate(duration = 12, rate = 500 / 12) # set failure rates fail_rate <- define_fail_rate( duration = c(4, 100), fail_rate = log(2) / 15, # median survival 15 month hr = c(1, .6), dropout_rate = 0.001 ) # set the targeted number of events and analysis time target_events <- c(30, 40, 50) target_analysisTime <- c(10, 24, 30) # Example 1 ---- # fixed bounds and calculate the power for targeted number of events gs_power_wlr( enroll_rate = enroll_rate, fail_rate = fail_rate, event = target_events, analysis_time = NULL, upper = gs_b, upar = gsDesign( k = length(target_events), test.type = 1, n.I = target_events, maxn.IPlan = max(target_events), sfu = sfLDOF, sfupar = NULL )$upper$bound, lower = gs_b, lpar = c(qnorm(.1), rep(-Inf, 2)) ) # Example 2 ---- # fixed bounds and calculate the power for targeted analysis time gs_power_wlr( enroll_rate = enroll_rate, fail_rate = fail_rate, event = NULL, analysis_time = target_analysisTime, upper = gs_b, upar = gsDesign( k = length(target_events), test.type = 1, n.I = target_events, maxn.IPlan = max(target_events), sfu = sfLDOF, sfupar = NULL )$upper$bound, lower = gs_b, lpar = c(qnorm(.1), rep(-Inf, 2)) ) # Example 3 ---- # fixed bounds and calculate the power for targeted analysis time & number of events gs_power_wlr( enroll_rate = enroll_rate, fail_rate = fail_rate, event = target_events, analysis_time = target_analysisTime, upper = gs_b, upar = gsDesign( k = length(target_events), test.type = 1, n.I = target_events, maxn.IPlan = max(target_events), sfu = sfLDOF, sfupar = NULL )$upper$bound, lower = gs_b, lpar = c(qnorm(.1), rep(-Inf, 2)) ) # Example 4 ---- # spending bounds and calculate the power for targeted number of events gs_power_wlr( enroll_rate = enroll_rate, fail_rate = fail_rate, event = target_events, analysis_time = NULL, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025), lower = gs_spending_bound, lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.2) ) # Example 5 ---- # spending bounds and calculate the power for targeted analysis time gs_power_wlr( enroll_rate = enroll_rate, fail_rate = fail_rate, event = NULL, analysis_time = target_analysisTime, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025), lower = gs_spending_bound, lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.2) ) # Example 6 ---- # spending bounds and calculate the power for targeted analysis time & number of events gs_power_wlr( enroll_rate = enroll_rate, fail_rate = fail_rate, event = target_events, analysis_time = target_analysisTime, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025), lower = gs_spending_bound, lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.2) )
library(gsDesign) library(gsDesign2) # set enrollment rates enroll_rate <- define_enroll_rate(duration = 12, rate = 500 / 12) # set failure rates fail_rate <- define_fail_rate( duration = c(4, 100), fail_rate = log(2) / 15, # median survival 15 month hr = c(1, .6), dropout_rate = 0.001 ) # set the targeted number of events and analysis time target_events <- c(30, 40, 50) target_analysisTime <- c(10, 24, 30) # Example 1 ---- # fixed bounds and calculate the power for targeted number of events gs_power_wlr( enroll_rate = enroll_rate, fail_rate = fail_rate, event = target_events, analysis_time = NULL, upper = gs_b, upar = gsDesign( k = length(target_events), test.type = 1, n.I = target_events, maxn.IPlan = max(target_events), sfu = sfLDOF, sfupar = NULL )$upper$bound, lower = gs_b, lpar = c(qnorm(.1), rep(-Inf, 2)) ) # Example 2 ---- # fixed bounds and calculate the power for targeted analysis time gs_power_wlr( enroll_rate = enroll_rate, fail_rate = fail_rate, event = NULL, analysis_time = target_analysisTime, upper = gs_b, upar = gsDesign( k = length(target_events), test.type = 1, n.I = target_events, maxn.IPlan = max(target_events), sfu = sfLDOF, sfupar = NULL )$upper$bound, lower = gs_b, lpar = c(qnorm(.1), rep(-Inf, 2)) ) # Example 3 ---- # fixed bounds and calculate the power for targeted analysis time & number of events gs_power_wlr( enroll_rate = enroll_rate, fail_rate = fail_rate, event = target_events, analysis_time = target_analysisTime, upper = gs_b, upar = gsDesign( k = length(target_events), test.type = 1, n.I = target_events, maxn.IPlan = max(target_events), sfu = sfLDOF, sfupar = NULL )$upper$bound, lower = gs_b, lpar = c(qnorm(.1), rep(-Inf, 2)) ) # Example 4 ---- # spending bounds and calculate the power for targeted number of events gs_power_wlr( enroll_rate = enroll_rate, fail_rate = fail_rate, event = target_events, analysis_time = NULL, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025), lower = gs_spending_bound, lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.2) ) # Example 5 ---- # spending bounds and calculate the power for targeted analysis time gs_power_wlr( enroll_rate = enroll_rate, fail_rate = fail_rate, event = NULL, analysis_time = target_analysisTime, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025), lower = gs_spending_bound, lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.2) ) # Example 6 ---- # spending bounds and calculate the power for targeted analysis time & number of events gs_power_wlr( enroll_rate = enroll_rate, fail_rate = fail_rate, event = target_events, analysis_time = target_analysisTime, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025), lower = gs_spending_bound, lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.2) )
Computes one bound at a time based on spending under given distributional
assumptions. While user specifies gs_spending_bound()
for use with other
functions, it is not intended for use on its own.
Most important user specifications are made through a list provided to
functions using gs_spending_bound()
.
Function uses numerical integration and Newton-Raphson iteration to derive
an individual bound for a group sequential design that satisfies a
targeted boundary crossing probability. Algorithm is a simple extension of
that in Chapter 19 of Jennison and Turnbull (2000).
gs_spending_bound( k = 1, par = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL, max_info = NULL), hgm1 = NULL, theta = 0.1, info = 1:3, efficacy = TRUE, test_bound = TRUE, r = 18, tol = 1e-06 )
gs_spending_bound( k = 1, par = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL, max_info = NULL), hgm1 = NULL, theta = 0.1, info = 1:3, efficacy = TRUE, test_bound = TRUE, r = 18, tol = 1e-06 )
k |
Analysis for which bound is to be computed. |
par |
A list with the following items:
|
hgm1 |
Subdensity grid from |
theta |
Natural parameter used for lower bound only spending; represents average drift at each time of analysis at least up to analysis k; upper bound spending is always set under null hypothesis (theta = 0). |
info |
Statistical information at all analyses, at least up to analysis k. |
efficacy |
|
test_bound |
A logical vector of the same length as |
r |
Integer value controlling grid for numerical integration
as in Jennison and Turnbull (2000); default is 18, range is 1 to 80.
Larger values provide larger number of grid points and greater accuracy.
Normally |
tol |
Tolerance parameter for convergence (on Z-scale). |
Returns a numeric bound (possibly infinite) or, upon failure, generates an error message.
The contents of this section are shown in PDF user manual only.
Keaven Anderson [email protected]
Jennison C and Turnbull BW (2000), Group Sequential Methods with Applications to Clinical Trials. Boca Raton: Chapman and Hall.
gs_power_ahr( analysis_time = c(12, 24, 36), event = c(30, 40, 50), binding = TRUE, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL), lower = gs_spending_bound, lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL) )
gs_power_ahr( analysis_time = c(12, 24, 36), event = c(30, 40, 50), binding = TRUE, upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL), lower = gs_spending_bound, lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL) )
Derive spending bound for MaxCombo group sequential boundary
gs_spending_combo(par = NULL, info = NULL)
gs_spending_combo(par = NULL, info = NULL)
par |
A list with the following items:
|
info |
Statistical information at all analyses, at least up to analysis k. |
A vector of the alpha spending per analysis.
# alpha-spending par <- list(sf = gsDesign::sfLDOF, total_spend = 0.025) gs_spending_combo(par, info = 1:3 / 3) par <- list(sf = gsDesign::sfLDPocock, total_spend = 0.025) gs_spending_combo(par, info = 1:3 / 3) par <- list(sf = gsDesign::sfHSD, total_spend = 0.025, param = -40) gs_spending_combo(par, info = 1:3 / 3) # Kim-DeMets (power) Spending Function par <- list(sf = gsDesign::sfPower, total_spend = 0.025, param = 1.5) gs_spending_combo(par, info = 1:3 / 3) # Exponential Spending Function par <- list(sf = gsDesign::sfExponential, total_spend = 0.025, param = 1) gs_spending_combo(par, info = 1:3 / 3) # Two-parameter Spending Function Families par <- list(sf = gsDesign::sfLogistic, total_spend = 0.025, param = c(.1, .4, .01, .1)) gs_spending_combo(par, info = 1:3 / 3) par <- list(sf = gsDesign::sfBetaDist, total_spend = 0.025, param = c(.1, .4, .01, .1)) gs_spending_combo(par, info = 1:3 / 3) par <- list(sf = gsDesign::sfCauchy, total_spend = 0.025, param = c(.1, .4, .01, .1)) gs_spending_combo(par, info = 1:3 / 3) par <- list(sf = gsDesign::sfExtremeValue, total_spend = 0.025, param = c(.1, .4, .01, .1)) gs_spending_combo(par, info = 1:3 / 3) par <- list(sf = gsDesign::sfExtremeValue2, total_spend = 0.025, param = c(.1, .4, .01, .1)) gs_spending_combo(par, info = 1:3 / 3) par <- list(sf = gsDesign::sfNormal, total_spend = 0.025, param = c(.1, .4, .01, .1)) gs_spending_combo(par, info = 1:3 / 3) # t-distribution Spending Function par <- list(sf = gsDesign::sfTDist, total_spend = 0.025, param = c(-1, 1.5, 4)) gs_spending_combo(par, info = 1:3 / 3) # Piecewise Linear and Step Function Spending Functions par <- list(sf = gsDesign::sfLinear, total_spend = 0.025, param = c(.2, .4, .05, .2)) gs_spending_combo(par, info = 1:3 / 3) par <- list(sf = gsDesign::sfStep, total_spend = 0.025, param = c(1 / 3, 2 / 3, .1, .1)) gs_spending_combo(par, info = 1:3 / 3) # Pointwise Spending Function par <- list(sf = gsDesign::sfPoints, total_spend = 0.025, param = c(.25, .25)) gs_spending_combo(par, info = 1:3 / 3) # Truncated, trimmed and gapped spending functions par <- list(sf = gsDesign::sfTruncated, total_spend = 0.025, param = list(trange = c(.2, .8), sf = gsDesign::sfHSD, param = 1)) gs_spending_combo(par, info = 1:3 / 3) par <- list(sf = gsDesign::sfTrimmed, total_spend = 0.025, param = list(trange = c(.2, .8), sf = gsDesign::sfHSD, param = 1)) gs_spending_combo(par, info = 1:3 / 3) par <- list(sf = gsDesign::sfGapped, total_spend = 0.025, param = list(trange = c(.2, .8), sf = gsDesign::sfHSD, param = 1)) gs_spending_combo(par, info = 1:3 / 3) # Xi and Gallo conditional error spending functions par <- list(sf = gsDesign::sfXG1, total_spend = 0.025, param = 0.5) gs_spending_combo(par, info = 1:3 / 3) par <- list(sf = gsDesign::sfXG2, total_spend = 0.025, param = 0.14) gs_spending_combo(par, info = 1:3 / 3) par <- list(sf = gsDesign::sfXG3, total_spend = 0.025, param = 0.013) gs_spending_combo(par, info = 1:3 / 3) # beta-spending par <- list(sf = gsDesign::sfLDOF, total_spend = 0.2) gs_spending_combo(par, info = 1:3 / 3)
# alpha-spending par <- list(sf = gsDesign::sfLDOF, total_spend = 0.025) gs_spending_combo(par, info = 1:3 / 3) par <- list(sf = gsDesign::sfLDPocock, total_spend = 0.025) gs_spending_combo(par, info = 1:3 / 3) par <- list(sf = gsDesign::sfHSD, total_spend = 0.025, param = -40) gs_spending_combo(par, info = 1:3 / 3) # Kim-DeMets (power) Spending Function par <- list(sf = gsDesign::sfPower, total_spend = 0.025, param = 1.5) gs_spending_combo(par, info = 1:3 / 3) # Exponential Spending Function par <- list(sf = gsDesign::sfExponential, total_spend = 0.025, param = 1) gs_spending_combo(par, info = 1:3 / 3) # Two-parameter Spending Function Families par <- list(sf = gsDesign::sfLogistic, total_spend = 0.025, param = c(.1, .4, .01, .1)) gs_spending_combo(par, info = 1:3 / 3) par <- list(sf = gsDesign::sfBetaDist, total_spend = 0.025, param = c(.1, .4, .01, .1)) gs_spending_combo(par, info = 1:3 / 3) par <- list(sf = gsDesign::sfCauchy, total_spend = 0.025, param = c(.1, .4, .01, .1)) gs_spending_combo(par, info = 1:3 / 3) par <- list(sf = gsDesign::sfExtremeValue, total_spend = 0.025, param = c(.1, .4, .01, .1)) gs_spending_combo(par, info = 1:3 / 3) par <- list(sf = gsDesign::sfExtremeValue2, total_spend = 0.025, param = c(.1, .4, .01, .1)) gs_spending_combo(par, info = 1:3 / 3) par <- list(sf = gsDesign::sfNormal, total_spend = 0.025, param = c(.1, .4, .01, .1)) gs_spending_combo(par, info = 1:3 / 3) # t-distribution Spending Function par <- list(sf = gsDesign::sfTDist, total_spend = 0.025, param = c(-1, 1.5, 4)) gs_spending_combo(par, info = 1:3 / 3) # Piecewise Linear and Step Function Spending Functions par <- list(sf = gsDesign::sfLinear, total_spend = 0.025, param = c(.2, .4, .05, .2)) gs_spending_combo(par, info = 1:3 / 3) par <- list(sf = gsDesign::sfStep, total_spend = 0.025, param = c(1 / 3, 2 / 3, .1, .1)) gs_spending_combo(par, info = 1:3 / 3) # Pointwise Spending Function par <- list(sf = gsDesign::sfPoints, total_spend = 0.025, param = c(.25, .25)) gs_spending_combo(par, info = 1:3 / 3) # Truncated, trimmed and gapped spending functions par <- list(sf = gsDesign::sfTruncated, total_spend = 0.025, param = list(trange = c(.2, .8), sf = gsDesign::sfHSD, param = 1)) gs_spending_combo(par, info = 1:3 / 3) par <- list(sf = gsDesign::sfTrimmed, total_spend = 0.025, param = list(trange = c(.2, .8), sf = gsDesign::sfHSD, param = 1)) gs_spending_combo(par, info = 1:3 / 3) par <- list(sf = gsDesign::sfGapped, total_spend = 0.025, param = list(trange = c(.2, .8), sf = gsDesign::sfHSD, param = 1)) gs_spending_combo(par, info = 1:3 / 3) # Xi and Gallo conditional error spending functions par <- list(sf = gsDesign::sfXG1, total_spend = 0.025, param = 0.5) gs_spending_combo(par, info = 1:3 / 3) par <- list(sf = gsDesign::sfXG2, total_spend = 0.025, param = 0.14) gs_spending_combo(par, info = 1:3 / 3) par <- list(sf = gsDesign::sfXG3, total_spend = 0.025, param = 0.013) gs_spending_combo(par, info = 1:3 / 3) # beta-spending par <- list(sf = gsDesign::sfLDOF, total_spend = 0.2) gs_spending_combo(par, info = 1:3 / 3)
Group sequential design using average hazard ratio under non-proportional hazards
gs_update_ahr( x = NULL, alpha = NULL, ustime = NULL, lstime = NULL, observed_data = NULL )
gs_update_ahr( x = NULL, alpha = NULL, ustime = NULL, lstime = NULL, observed_data = NULL )
x |
A design created by either |
alpha |
Type I error for the updated design. |
ustime |
Default is NULL in which case upper bound spending time is determined by timing. Otherwise, this should be a vector of length k (total number of analyses) with the spending time at each analysis. |
lstime |
Default is NULL in which case lower bound spending time is determined by timing. Otherwise, this should be a vector of length k (total number of analyses) with the spending time at each analysis |
observed_data |
a list of observed datasets by analyses. |
A list with input parameters, enrollment rate, analysis, and bound.
library(gsDesign) library(gsDesign2) library(dplyr) alpha <- 0.025 beta <- 0.1 ratio <- 1 # Enrollment enroll_rate <- define_enroll_rate( duration = c(2, 2, 10), rate = (1:3) / 3) # Failure and dropout fail_rate <- define_fail_rate( duration = c(3, Inf), fail_rate = log(2) / 9, hr = c(1, 0.6), dropout_rate = .0001) # IA and FA analysis time analysis_time <- c(20, 36) # Randomization ratio ratio <- 1 # ------------------------------------------------- # # Example A: one-sided design (efficacy only) # ------------------------------------------------- # # Original design upper <- gs_spending_bound upar <- list(sf = sfLDOF, total_spend = alpha) x <- gs_design_ahr( enroll_rate = enroll_rate, fail_rate = fail_rate, alpha = alpha, beta = beta, ratio = ratio, info_scale = "h0_info", info_frac = NULL, analysis_time = c(20, 36), upper = gs_spending_bound, upar = upar, lower = gs_b, lpar = rep(-Inf, 2), test_upper = TRUE, test_lower = FALSE) |> to_integer() # Observed dataset at IA and FA set.seed(123) observed_data <- simtrial::sim_pw_surv( n = x$analysis$n[x$analysis$analysis == 2], stratum = data.frame(stratum = "All", p = 1), block = c(rep("control", 2), rep("experimental", 2)), enroll_rate = x$enroll_rate, fail_rate = (fail_rate |> simtrial::to_sim_pw_surv())$fail_rate, dropout_rate = (fail_rate |> simtrial::to_sim_pw_surv())$dropout_rate) observed_data_ia <- observed_data |> simtrial::cut_data_by_date(x$analysis$time[1]) observed_data_fa <- observed_data |> simtrial::cut_data_by_date(x$analysis$time[2]) observed_event_ia <- sum(observed_data_ia$event) observed_event_fa <- sum(observed_data_fa$event) planned_event_ia <- x$analysis$event[1] planned_event_fa <- x$analysis$event[2] # Example A1 ---- # IA spending = observed events / final planned events # the remaining alpha will be allocated to FA. ustime <- c(observed_event_ia / planned_event_fa, 1) gs_update_ahr( x = x, ustime = ustime, observed_data = list(observed_data_ia, observed_data_fa)) # Example A2 ---- # IA, FA spending = observed events / final planned events ustime <- c(observed_event_ia, observed_event_fa) / planned_event_fa gs_update_ahr( x = x, ustime = ustime, observed_data = list(observed_data_ia, observed_data_fa)) # Example A3 ---- # IA spending = min(observed events, planned events) / final planned events ustime <- c(min(observed_event_ia, planned_event_ia) / planned_event_fa, 1) gs_update_ahr( x = x, ustime = ustime, observed_data = list(observed_data_ia, observed_data_fa)) # Example A4 ---- # IA spending = min(observed events, planned events) / final planned events ustime <- c(min(observed_event_ia, planned_event_ia), min(observed_event_fa, planned_event_fa)) / planned_event_fa gs_update_ahr( x = x, ustime = ustime, observed_data = list(observed_data_ia, observed_data_fa)) # alpha is upadted to 0.05 gs_update_ahr( x = x, alpha = 0.05, ustime = ustime, observed_data = list(observed_data_ia, observed_data_fa)) # ------------------------------------------------- # # Example B: Two-sided asymmetric design, # beta-spending with non-binding lower bound # ------------------------------------------------- # # Original design x <- gs_design_ahr( enroll_rate = enroll_rate, fail_rate = fail_rate, alpha = alpha, beta = beta, ratio = ratio, info_scale = "h0_info", info_frac = NULL, analysis_time = c(20, 36), upper = gs_spending_bound, upar = list(sf = sfLDOF, total_spend = alpha), test_upper = TRUE, lower = gs_spending_bound, lpar = list(sf = sfLDOF, total_spend = beta), test_lower = c(TRUE, FALSE), binding = FALSE) |> to_integer() # Example B1 ---- # IA spending = observed events / final planned events # the remaining alpha will be allocated to FA. ustime <- c(observed_event_ia / planned_event_fa, 1) gs_update_ahr( x = x, ustime = ustime, lstime = ustime, observed_data = list(observed_data_ia, observed_data_fa)) # Example B2 ---- # IA, FA spending = observed events / final planned events ustime <- c(observed_event_ia, observed_event_fa) / planned_event_fa gs_update_ahr( x = x, ustime = ustime, lstime = ustime, observed_data = list(observed_data_ia, observed_data_fa)) # Example B3 ---- ustime <- c(min(observed_event_ia, planned_event_ia) / planned_event_fa, 1) gs_update_ahr( x = x, ustime = ustime, lstime = ustime, observed_data = list(observed_data_ia, observed_data_fa)) # Example B4 ---- # IA spending = min(observed events, planned events) / final planned events ustime <- c(min(observed_event_ia, planned_event_ia), min(observed_event_fa, planned_event_fa)) / planned_event_fa gs_update_ahr( x = x, ustime = ustime, lstime = ustime, observed_data = list(observed_data_ia, observed_data_fa)) # Example B5 ---- # alpha is updated to 0.05 ---- gs_update_ahr(x = x, alpha = 0.05) # Example B6 ---- # updated boundaries only when IA data is observed ustime <- c(observed_event_ia / planned_event_fa, 1) gs_update_ahr( x = x, ustime = ustime, lstime = ustime, observed_data = list(observed_data_ia, NULL)) # ------------------------------------------------- # # Example C: Two-sided asymmetric design, # with calendar spending for efficacy and futility bounds # beta-spending with non-binding lower bound # ------------------------------------------------- # # Original design x <- gs_design_ahr( enroll_rate = enroll_rate, fail_rate = fail_rate, alpha = alpha, beta = beta, ratio = ratio, info_scale = "h0_info", info_frac = NULL, analysis_time = c(20, 36), upper = gs_spending_bound, upar = list(sf = sfLDOF, total_spend = alpha, timing = c(20, 36) / 36), test_upper = TRUE, lower = gs_spending_bound, lpar = list(sf = sfLDOF, total_spend = beta, timing = c(20, 36) / 36), test_lower = c(TRUE, FALSE), binding = FALSE) |> to_integer() # Updated design due to potential change of multiplicity graph gs_update_ahr(x = x, alpha = 0.05)
library(gsDesign) library(gsDesign2) library(dplyr) alpha <- 0.025 beta <- 0.1 ratio <- 1 # Enrollment enroll_rate <- define_enroll_rate( duration = c(2, 2, 10), rate = (1:3) / 3) # Failure and dropout fail_rate <- define_fail_rate( duration = c(3, Inf), fail_rate = log(2) / 9, hr = c(1, 0.6), dropout_rate = .0001) # IA and FA analysis time analysis_time <- c(20, 36) # Randomization ratio ratio <- 1 # ------------------------------------------------- # # Example A: one-sided design (efficacy only) # ------------------------------------------------- # # Original design upper <- gs_spending_bound upar <- list(sf = sfLDOF, total_spend = alpha) x <- gs_design_ahr( enroll_rate = enroll_rate, fail_rate = fail_rate, alpha = alpha, beta = beta, ratio = ratio, info_scale = "h0_info", info_frac = NULL, analysis_time = c(20, 36), upper = gs_spending_bound, upar = upar, lower = gs_b, lpar = rep(-Inf, 2), test_upper = TRUE, test_lower = FALSE) |> to_integer() # Observed dataset at IA and FA set.seed(123) observed_data <- simtrial::sim_pw_surv( n = x$analysis$n[x$analysis$analysis == 2], stratum = data.frame(stratum = "All", p = 1), block = c(rep("control", 2), rep("experimental", 2)), enroll_rate = x$enroll_rate, fail_rate = (fail_rate |> simtrial::to_sim_pw_surv())$fail_rate, dropout_rate = (fail_rate |> simtrial::to_sim_pw_surv())$dropout_rate) observed_data_ia <- observed_data |> simtrial::cut_data_by_date(x$analysis$time[1]) observed_data_fa <- observed_data |> simtrial::cut_data_by_date(x$analysis$time[2]) observed_event_ia <- sum(observed_data_ia$event) observed_event_fa <- sum(observed_data_fa$event) planned_event_ia <- x$analysis$event[1] planned_event_fa <- x$analysis$event[2] # Example A1 ---- # IA spending = observed events / final planned events # the remaining alpha will be allocated to FA. ustime <- c(observed_event_ia / planned_event_fa, 1) gs_update_ahr( x = x, ustime = ustime, observed_data = list(observed_data_ia, observed_data_fa)) # Example A2 ---- # IA, FA spending = observed events / final planned events ustime <- c(observed_event_ia, observed_event_fa) / planned_event_fa gs_update_ahr( x = x, ustime = ustime, observed_data = list(observed_data_ia, observed_data_fa)) # Example A3 ---- # IA spending = min(observed events, planned events) / final planned events ustime <- c(min(observed_event_ia, planned_event_ia) / planned_event_fa, 1) gs_update_ahr( x = x, ustime = ustime, observed_data = list(observed_data_ia, observed_data_fa)) # Example A4 ---- # IA spending = min(observed events, planned events) / final planned events ustime <- c(min(observed_event_ia, planned_event_ia), min(observed_event_fa, planned_event_fa)) / planned_event_fa gs_update_ahr( x = x, ustime = ustime, observed_data = list(observed_data_ia, observed_data_fa)) # alpha is upadted to 0.05 gs_update_ahr( x = x, alpha = 0.05, ustime = ustime, observed_data = list(observed_data_ia, observed_data_fa)) # ------------------------------------------------- # # Example B: Two-sided asymmetric design, # beta-spending with non-binding lower bound # ------------------------------------------------- # # Original design x <- gs_design_ahr( enroll_rate = enroll_rate, fail_rate = fail_rate, alpha = alpha, beta = beta, ratio = ratio, info_scale = "h0_info", info_frac = NULL, analysis_time = c(20, 36), upper = gs_spending_bound, upar = list(sf = sfLDOF, total_spend = alpha), test_upper = TRUE, lower = gs_spending_bound, lpar = list(sf = sfLDOF, total_spend = beta), test_lower = c(TRUE, FALSE), binding = FALSE) |> to_integer() # Example B1 ---- # IA spending = observed events / final planned events # the remaining alpha will be allocated to FA. ustime <- c(observed_event_ia / planned_event_fa, 1) gs_update_ahr( x = x, ustime = ustime, lstime = ustime, observed_data = list(observed_data_ia, observed_data_fa)) # Example B2 ---- # IA, FA spending = observed events / final planned events ustime <- c(observed_event_ia, observed_event_fa) / planned_event_fa gs_update_ahr( x = x, ustime = ustime, lstime = ustime, observed_data = list(observed_data_ia, observed_data_fa)) # Example B3 ---- ustime <- c(min(observed_event_ia, planned_event_ia) / planned_event_fa, 1) gs_update_ahr( x = x, ustime = ustime, lstime = ustime, observed_data = list(observed_data_ia, observed_data_fa)) # Example B4 ---- # IA spending = min(observed events, planned events) / final planned events ustime <- c(min(observed_event_ia, planned_event_ia), min(observed_event_fa, planned_event_fa)) / planned_event_fa gs_update_ahr( x = x, ustime = ustime, lstime = ustime, observed_data = list(observed_data_ia, observed_data_fa)) # Example B5 ---- # alpha is updated to 0.05 ---- gs_update_ahr(x = x, alpha = 0.05) # Example B6 ---- # updated boundaries only when IA data is observed ustime <- c(observed_event_ia / planned_event_fa, 1) gs_update_ahr( x = x, ustime = ustime, lstime = ustime, observed_data = list(observed_data_ia, NULL)) # ------------------------------------------------- # # Example C: Two-sided asymmetric design, # with calendar spending for efficacy and futility bounds # beta-spending with non-binding lower bound # ------------------------------------------------- # # Original design x <- gs_design_ahr( enroll_rate = enroll_rate, fail_rate = fail_rate, alpha = alpha, beta = beta, ratio = ratio, info_scale = "h0_info", info_frac = NULL, analysis_time = c(20, 36), upper = gs_spending_bound, upar = list(sf = sfLDOF, total_spend = alpha, timing = c(20, 36) / 36), test_upper = TRUE, lower = gs_spending_bound, lpar = list(sf = sfLDOF, total_spend = beta, timing = c(20, 36) / 36), test_lower = c(TRUE, FALSE), binding = FALSE) |> to_integer() # Updated design due to potential change of multiplicity graph gs_update_ahr(x = x, alpha = 0.05)
Computes the cumulative distribution function (CDF) or survival rate for a piecewise exponential distribution.
ppwe(x, duration, rate, lower_tail = FALSE)
ppwe(x, duration, rate, lower_tail = FALSE)
x |
Times at which distribution is to be computed. |
duration |
A numeric vector of time duration. |
rate |
A numeric vector of event rate. |
lower_tail |
Indicator of whether lower ( |
Suppose is the failure rate in the interval
where
.
The cumulative hazard function at an arbitrary time
is then:
The survival at time is then
A vector with cumulative distribution function or survival values.
The contents of this section are shown in PDF user manual only.
# Plot a survival function with 2 different sets of time values # to demonstrate plot precision corresponding to input parameters. x1 <- seq(0, 10, 10 / pi) duration <- c(3, 3, 1) rate <- c(.2, .1, .005) survival <- ppwe( x = x1, duration = duration, rate = rate ) plot(x1, survival, type = "l", ylim = c(0, 1)) x2 <- seq(0, 10, .25) survival <- ppwe( x = x2, duration = duration, rate = rate ) lines(x2, survival, col = 2)
# Plot a survival function with 2 different sets of time values # to demonstrate plot precision corresponding to input parameters. x1 <- seq(0, 10, 10 / pi) duration <- c(3, 3, 1) rate <- c(.2, .1, .005) survival <- ppwe( x = x1, duration = duration, rate = rate ) plot(x1, survival, type = "l", ylim = c(0, 1)) x2 <- seq(0, 10, .25) survival <- ppwe( x = x2, duration = duration, rate = rate ) lines(x2, survival, col = 2)
Provides a geometric average hazard ratio under various non-proportional hazards assumptions for either single or multiple strata studies. The piecewise exponential distribution allows a simple method to specify a distribution and enrollment pattern where the enrollment, failure and dropout rates changes over time.
pw_info( enroll_rate = define_enroll_rate(duration = c(2, 2, 10), rate = c(3, 6, 9)), fail_rate = define_fail_rate(duration = c(3, 100), fail_rate = log(2)/c(9, 18), hr = c(0.9, 0.6), dropout_rate = 0.001), total_duration = 30, ratio = 1 )
pw_info( enroll_rate = define_enroll_rate(duration = c(2, 2, 10), rate = c(3, 6, 9)), fail_rate = define_fail_rate(duration = c(3, 100), fail_rate = log(2)/c(9, 18), hr = c(0.9, 0.6), dropout_rate = 0.001), total_duration = 30, ratio = 1 )
enroll_rate |
An |
fail_rate |
A |
total_duration |
Total follow-up from start of enrollment to data cutoff; this can be a single value or a vector of positive numbers. |
ratio |
Ratio of experimental to control randomization. |
A data frame with time
(from total_duration
), stratum
, t
,
hr
(hazard ratio), event
(expected number of events), info
(information under given scenarios), info0
(information under related
null hypothesis), and n
(sample size) for each value of total_duration
input
# Example: default pw_info() # Example: default with multiple analysis times (varying total_duration) pw_info(total_duration = c(15, 30)) # Stratified population enroll_rate <- define_enroll_rate( stratum = c(rep("Low", 2), rep("High", 3)), duration = c(2, 10, 4, 4, 8), rate = c(5, 10, 0, 3, 6) ) fail_rate <- define_fail_rate( stratum = c(rep("Low", 2), rep("High", 2)), duration = c(1, Inf, 1, Inf), fail_rate = c(.1, .2, .3, .4), dropout_rate = .001, hr = c(.9, .75, .8, .6) ) # Give results by change-points in the piecewise model ahr(enroll_rate = enroll_rate, fail_rate = fail_rate, total_duration = c(15, 30)) # Same example, give results by strata and time period pw_info(enroll_rate = enroll_rate, fail_rate = fail_rate, total_duration = c(15, 30))
# Example: default pw_info() # Example: default with multiple analysis times (varying total_duration) pw_info(total_duration = c(15, 30)) # Stratified population enroll_rate <- define_enroll_rate( stratum = c(rep("Low", 2), rep("High", 3)), duration = c(2, 10, 4, 4, 8), rate = c(5, 10, 0, 3, 6) ) fail_rate <- define_fail_rate( stratum = c(rep("Low", 2), rep("High", 2)), duration = c(1, Inf, 1, Inf), fail_rate = c(.1, .2, .3, .4), dropout_rate = .001, hr = c(.9, .75, .8, .6) ) # Give results by change-points in the piecewise model ahr(enroll_rate = enroll_rate, fail_rate = fail_rate, total_duration = c(15, 30)) # Same example, give results by strata and time period pw_info(enroll_rate = enroll_rate, fail_rate = fail_rate, total_duration = c(15, 30))
Converts a discrete set of points from an arbitrary survival distribution to a piecewise exponential approximation.
s2pwe(times, survival)
s2pwe(times, survival)
times |
Positive increasing times at which survival distribution is provided. |
survival |
Survival (1 - cumulative distribution function) at specified |
A tibble containing the duration and rate.
The contents of this section are shown in PDF user manual only.
# Example: arbitrary numbers s2pwe(1:9, (9:1) / 10) # Example: lognormal s2pwe(c(1:6, 9), plnorm(c(1:6, 9), meanlog = 0, sdlog = 2, lower.tail = FALSE))
# Example: arbitrary numbers s2pwe(1:9, (9:1) / 10) # Example: lognormal s2pwe(c(1:6, 9), plnorm(c(1:6, 9), meanlog = 0, sdlog = 2, lower.tail = FALSE))
Summary for fixed design or group sequential design objects
## S3 method for class 'fixed_design' summary(object, ...) ## S3 method for class 'gs_design' summary( object, analysis_vars = NULL, analysis_decimals = NULL, col_vars = NULL, col_decimals = NULL, bound_names = c("Efficacy", "Futility"), ... )
## S3 method for class 'fixed_design' summary(object, ...) ## S3 method for class 'gs_design' summary( object, analysis_vars = NULL, analysis_decimals = NULL, col_vars = NULL, col_decimals = NULL, bound_names = c("Efficacy", "Futility"), ... )
object |
A design object returned by fixed_design_xxx() and gs_design_xxx(). |
... |
Additional parameters (not used). |
analysis_vars |
The variables to be put at the summary header of each analysis. |
analysis_decimals |
The displayed number of digits of |
col_vars |
The variables to be displayed. |
col_decimals |
The decimals to be displayed for the displayed variables in |
bound_names |
Names for bounds; default is |
A summary table (data frame).
library(dplyr) # 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, hr = c(1, .6), dropout_rate = .001 ) # 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 # AHR ---- # under fixed power fixed_design_ahr( alpha = alpha, power = 1 - beta, enroll_rate = enroll_rate, fail_rate = fail_rate, study_duration = study_duration, ratio = ratio ) %>% summary() # FH ---- # under fixed power fixed_design_fh( alpha = alpha, power = 1 - beta, enroll_rate = enroll_rate, fail_rate = fail_rate, study_duration = study_duration, ratio = ratio ) %>% summary() # Design parameters ---- library(gsDesign) library(gsDesign2) library(dplyr) # enrollment/failure rates enroll_rate <- define_enroll_rate( stratum = "All", duration = 12, rate = 1 ) fail_rate <- define_fail_rate( duration = c(4, 100), fail_rate = log(2) / 12, hr = c(1, .6), dropout_rate = .001 ) # Information fraction info_frac <- (1:3) / 3 # Analysis times in months; first 2 will be ignored as info_frac will not be achieved analysis_time <- c(.01, .02, 36) # Experimental / Control randomization ratio ratio <- 1 # 1-sided Type I error alpha <- 0.025 # Type II error (1 - power) beta <- .1 # Upper bound upper <- gs_spending_bound upar <- list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL) # Lower bound lower <- gs_spending_bound lpar <- list(sf = gsDesign::sfHSD, total_spend = 0.1, param = 0, timing = NULL) # weight function in WLR wgt00 <- function(x, arm0, arm1) { wlr_weight_fh(x, arm0, arm1, rho = 0, gamma = 0) } wgt05 <- function(x, arm0, arm1) { wlr_weight_fh(x, arm0, arm1, rho = 0, gamma = .5) } # test in COMBO fh_test <- rbind( data.frame(rho = 0, gamma = 0, tau = -1, test = 1, analysis = 1:3, analysis_time = c(12, 24, 36)), data.frame(rho = c(0, 0.5), gamma = 0.5, tau = -1, test = 2:3, analysis = 3, analysis_time = 36) ) # Example 1 ---- x_ahr <- gs_design_ahr( enroll_rate = enroll_rate, fail_rate = fail_rate, info_frac = info_frac, # Information fraction analysis_time = analysis_time, ratio = ratio, alpha = alpha, beta = beta, upper = upper, upar = upar, lower = lower, lpar = lpar ) x_ahr %>% summary() # Customize the digits to display x_ahr %>% summary(analysis_vars = c("time", "event", "info_frac"), analysis_decimals = c(1, 0, 2)) # Customize the labels of the crossing probability x_ahr %>% summary(bound_names = c("A is better", "B is better")) # Customize the variables to be summarized for each analysis x_ahr %>% summary(analysis_vars = c("n", "event"), analysis_decimals = c(1, 1)) # Customize the digits for the columns x_ahr %>% summary(col_decimals = c(z = 4)) # Customize the columns to display x_ahr %>% summary(col_vars = c("z", "~hr at bound", "nominal p")) # Customize columns and digits x_ahr %>% summary(col_vars = c("z", "~hr at bound", "nominal p"), col_decimals = c(4, 2, 2)) # Example 2 ---- x_wlr <- gs_design_wlr( enroll_rate = enroll_rate, fail_rate = fail_rate, weight = wgt05, info_frac = NULL, analysis_time = sort(unique(x_ahr$analysis$time)), ratio = ratio, alpha = alpha, beta = beta, upper = upper, upar = upar, lower = lower, lpar = lpar ) x_wlr %>% summary() # Maxcombo ---- x_combo <- gs_design_combo( ratio = 1, alpha = 0.025, beta = 0.2, enroll_rate = define_enroll_rate(duration = 12, rate = 500 / 12), fail_rate = tibble::tibble( stratum = "All", duration = c(4, 100), fail_rate = log(2) / 15, hr = c(1, .6), dropout_rate = .001 ), fh_test = fh_test, upper = gs_spending_combo, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025), lower = gs_spending_combo, lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.2) ) x_combo %>% summary() # Risk difference ---- gs_design_rd( p_c = tibble::tibble(stratum = "All", rate = .2), p_e = tibble::tibble(stratum = "All", rate = .15), info_frac = c(0.7, 1), rd0 = 0, alpha = .025, beta = .1, ratio = 1, stratum_prev = NULL, weight = "unstratified", upper = gs_b, lower = gs_b, upar = gsDesign::gsDesign( k = 3, test.type = 1, sfu = gsDesign::sfLDOF, sfupar = NULL )$upper$bound, lpar = c(qnorm(.1), rep(-Inf, 2)) ) %>% summary()
library(dplyr) # 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, hr = c(1, .6), dropout_rate = .001 ) # 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 # AHR ---- # under fixed power fixed_design_ahr( alpha = alpha, power = 1 - beta, enroll_rate = enroll_rate, fail_rate = fail_rate, study_duration = study_duration, ratio = ratio ) %>% summary() # FH ---- # under fixed power fixed_design_fh( alpha = alpha, power = 1 - beta, enroll_rate = enroll_rate, fail_rate = fail_rate, study_duration = study_duration, ratio = ratio ) %>% summary() # Design parameters ---- library(gsDesign) library(gsDesign2) library(dplyr) # enrollment/failure rates enroll_rate <- define_enroll_rate( stratum = "All", duration = 12, rate = 1 ) fail_rate <- define_fail_rate( duration = c(4, 100), fail_rate = log(2) / 12, hr = c(1, .6), dropout_rate = .001 ) # Information fraction info_frac <- (1:3) / 3 # Analysis times in months; first 2 will be ignored as info_frac will not be achieved analysis_time <- c(.01, .02, 36) # Experimental / Control randomization ratio ratio <- 1 # 1-sided Type I error alpha <- 0.025 # Type II error (1 - power) beta <- .1 # Upper bound upper <- gs_spending_bound upar <- list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = NULL) # Lower bound lower <- gs_spending_bound lpar <- list(sf = gsDesign::sfHSD, total_spend = 0.1, param = 0, timing = NULL) # weight function in WLR wgt00 <- function(x, arm0, arm1) { wlr_weight_fh(x, arm0, arm1, rho = 0, gamma = 0) } wgt05 <- function(x, arm0, arm1) { wlr_weight_fh(x, arm0, arm1, rho = 0, gamma = .5) } # test in COMBO fh_test <- rbind( data.frame(rho = 0, gamma = 0, tau = -1, test = 1, analysis = 1:3, analysis_time = c(12, 24, 36)), data.frame(rho = c(0, 0.5), gamma = 0.5, tau = -1, test = 2:3, analysis = 3, analysis_time = 36) ) # Example 1 ---- x_ahr <- gs_design_ahr( enroll_rate = enroll_rate, fail_rate = fail_rate, info_frac = info_frac, # Information fraction analysis_time = analysis_time, ratio = ratio, alpha = alpha, beta = beta, upper = upper, upar = upar, lower = lower, lpar = lpar ) x_ahr %>% summary() # Customize the digits to display x_ahr %>% summary(analysis_vars = c("time", "event", "info_frac"), analysis_decimals = c(1, 0, 2)) # Customize the labels of the crossing probability x_ahr %>% summary(bound_names = c("A is better", "B is better")) # Customize the variables to be summarized for each analysis x_ahr %>% summary(analysis_vars = c("n", "event"), analysis_decimals = c(1, 1)) # Customize the digits for the columns x_ahr %>% summary(col_decimals = c(z = 4)) # Customize the columns to display x_ahr %>% summary(col_vars = c("z", "~hr at bound", "nominal p")) # Customize columns and digits x_ahr %>% summary(col_vars = c("z", "~hr at bound", "nominal p"), col_decimals = c(4, 2, 2)) # Example 2 ---- x_wlr <- gs_design_wlr( enroll_rate = enroll_rate, fail_rate = fail_rate, weight = wgt05, info_frac = NULL, analysis_time = sort(unique(x_ahr$analysis$time)), ratio = ratio, alpha = alpha, beta = beta, upper = upper, upar = upar, lower = lower, lpar = lpar ) x_wlr %>% summary() # Maxcombo ---- x_combo <- gs_design_combo( ratio = 1, alpha = 0.025, beta = 0.2, enroll_rate = define_enroll_rate(duration = 12, rate = 500 / 12), fail_rate = tibble::tibble( stratum = "All", duration = c(4, 100), fail_rate = log(2) / 15, hr = c(1, .6), dropout_rate = .001 ), fh_test = fh_test, upper = gs_spending_combo, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025), lower = gs_spending_combo, lpar = list(sf = gsDesign::sfLDOF, total_spend = 0.2) ) x_combo %>% summary() # Risk difference ---- gs_design_rd( p_c = tibble::tibble(stratum = "All", rate = .2), p_e = tibble::tibble(stratum = "All", rate = .15), info_frac = c(0.7, 1), rd0 = 0, alpha = .025, beta = .1, ratio = 1, stratum_prev = NULL, weight = "unstratified", upper = gs_b, lower = gs_b, upar = gsDesign::gsDesign( k = 3, test.type = 1, sfu = gsDesign::sfLDOF, sfupar = NULL )$upper$bound, lpar = c(qnorm(.1), rep(-Inf, 2)) ) %>% summary()
Round sample size and events
to_integer(x, ...) ## S3 method for class 'fixed_design' to_integer(x, round_up_final = TRUE, ratio = x$input$ratio, ...) ## S3 method for class 'gs_design' to_integer(x, round_up_final = TRUE, ratio = x$input$ratio, ...)
to_integer(x, ...) ## S3 method for class 'fixed_design' to_integer(x, round_up_final = TRUE, ratio = x$input$ratio, ...) ## S3 method for class 'gs_design' to_integer(x, round_up_final = TRUE, ratio = x$input$ratio, ...)
x |
An object returned by fixed_design_xxx() and gs_design_xxx(). |
... |
Additional parameters (not used). |
round_up_final |
Events at final analysis is rounded up if |
ratio |
Positive integer for randomization ratio (experimental:control). A positive integer will result in rounded sample size, which is a multiple of (ratio + 1). A positive non-integer will result in round sample size, which may not be a multiple of (ratio + 1). A negative number will result in an error. |
For the sample size of the fixed design:
When ratio
is a positive integer, the sample size is rounded up to a multiple of ratio + 1
if round_up_final = TRUE
, and just rounded to a multiple of ratio + 1
if round_up_final = FALSE
.
When ratio
is a positive non-integer, the sample size is rounded up if round_up_final = TRUE
,
(may not be a multiple of ratio + 1
), and just rounded if round_up_final = FALSE
(may not be a multiple of ratio + 1
).
Note the default ratio
is taken from x$input$ratio
.
For the number of events of the fixed design:
If the continuous event is very close to an integer within 0.01 differences, say 100.001 or 99.999, then the integer events is 100.
Otherwise, round up if round_up_final = TRUE
and round if round_up_final = FALSE
.
For the sample size of group sequential designs:
When ratio
is a positive integer, the final sample size is rounded to a multiple of ratio + 1
.
For 1:1 randomization (experimental:control), set ratio = 1
to round to an even sample size.
For 2:1 randomization, set ratio = 2
to round to a multiple of 3.
For 3:2 randomization, set ratio = 4
to round to a multiple of 5.
Note that for the final analysis, the sample size is rounded up to the nearest multiple of ratio + 1
if round_up_final = TRUE
.
If round_up_final = FALSE
, the final sample size is rounded to the nearest multiple of ratio + 1
.
When ratio
is positive non-integer, the final sample size MAY NOT be rounded to a multiple of ratio + 1
.
The final sample size is rounded up if round_up_final = TRUE
.
Otherwise, it is just rounded.
For the events of group sequential designs:
For events at interim analysis, it is rounded.
For events at final analysis:
If the continuous event is very close to an integer within 0.01 differences, say 100.001 or 99.999, then the integer events is 100.
Otherwise, final events is rounded up if round_up_final = TRUE
and rounded if round_up_final = FALSE
.
A list similar to the output of fixed_design_xxx() and gs_design_xxx(), except the sample size is an integer.
library(dplyr) library(gsDesign2) # Average hazard ratio x <- fixed_design_ahr( alpha = .025, power = .9, enroll_rate = define_enroll_rate(duration = 18, rate = 1), fail_rate = define_fail_rate( duration = c(4, 100), fail_rate = log(2) / 12, hr = c(1, .6), dropout_rate = .001 ), study_duration = 36 ) x |> to_integer() |> summary() # FH x <- fixed_design_fh( alpha = 0.025, power = 0.9, enroll_rate = define_enroll_rate(duration = 18, rate = 20), fail_rate = define_fail_rate( duration = c(4, 100), fail_rate = log(2) / 12, hr = c(1, .6), dropout_rate = .001 ), rho = 0.5, gamma = 0.5, study_duration = 36, ratio = 1 ) x |> to_integer() |> summary() # MB x <- fixed_design_mb( alpha = 0.025, power = 0.9, enroll_rate = define_enroll_rate(duration = 18, rate = 20), fail_rate = define_fail_rate( duration = c(4, 100), fail_rate = log(2) / 12, hr = c(1, .6), dropout_rate = .001 ), tau = 4, study_duration = 36, ratio = 1 ) x |> to_integer() |> summary() # Example 1: Information fraction based spending gs_design_ahr( analysis_time = c(18, 30), upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL), lower = gs_b, lpar = c(-Inf, -Inf) ) |> to_integer() |> summary() gs_design_wlr( analysis_time = c(18, 30), upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL), lower = gs_b, lpar = c(-Inf, -Inf) ) |> to_integer() |> summary() gs_design_rd( p_c = tibble::tibble(stratum = c("A", "B"), rate = c(.2, .3)), p_e = tibble::tibble(stratum = c("A", "B"), rate = c(.15, .27)), weight = "ss", stratum_prev = tibble::tibble(stratum = c("A", "B"), prevalence = c(.4, .6)), info_frac = c(0.7, 1), upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL), lower = gs_b, lpar = c(-Inf, -Inf) ) |> to_integer() |> summary() # Example 2: Calendar based spending x <- gs_design_ahr( upper = gs_spending_bound, analysis_time = c(18, 30), upar = list( sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = c(18, 30) / 30 ), lower = gs_b, lpar = c(-Inf, -Inf) ) |> to_integer() # The IA nominal p-value is the same as the IA alpha spending x$bound$`nominal p`[1] gsDesign::sfLDOF(alpha = 0.025, t = 18 / 30)$spend
library(dplyr) library(gsDesign2) # Average hazard ratio x <- fixed_design_ahr( alpha = .025, power = .9, enroll_rate = define_enroll_rate(duration = 18, rate = 1), fail_rate = define_fail_rate( duration = c(4, 100), fail_rate = log(2) / 12, hr = c(1, .6), dropout_rate = .001 ), study_duration = 36 ) x |> to_integer() |> summary() # FH x <- fixed_design_fh( alpha = 0.025, power = 0.9, enroll_rate = define_enroll_rate(duration = 18, rate = 20), fail_rate = define_fail_rate( duration = c(4, 100), fail_rate = log(2) / 12, hr = c(1, .6), dropout_rate = .001 ), rho = 0.5, gamma = 0.5, study_duration = 36, ratio = 1 ) x |> to_integer() |> summary() # MB x <- fixed_design_mb( alpha = 0.025, power = 0.9, enroll_rate = define_enroll_rate(duration = 18, rate = 20), fail_rate = define_fail_rate( duration = c(4, 100), fail_rate = log(2) / 12, hr = c(1, .6), dropout_rate = .001 ), tau = 4, study_duration = 36, ratio = 1 ) x |> to_integer() |> summary() # Example 1: Information fraction based spending gs_design_ahr( analysis_time = c(18, 30), upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL), lower = gs_b, lpar = c(-Inf, -Inf) ) |> to_integer() |> summary() gs_design_wlr( analysis_time = c(18, 30), upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL), lower = gs_b, lpar = c(-Inf, -Inf) ) |> to_integer() |> summary() gs_design_rd( p_c = tibble::tibble(stratum = c("A", "B"), rate = c(.2, .3)), p_e = tibble::tibble(stratum = c("A", "B"), rate = c(.15, .27)), weight = "ss", stratum_prev = tibble::tibble(stratum = c("A", "B"), prevalence = c(.4, .6)), info_frac = c(0.7, 1), upper = gs_spending_bound, upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL), lower = gs_b, lpar = c(-Inf, -Inf) ) |> to_integer() |> summary() # Example 2: Calendar based spending x <- gs_design_ahr( upper = gs_spending_bound, analysis_time = c(18, 30), upar = list( sf = gsDesign::sfLDOF, total_spend = 0.025, param = NULL, timing = c(18, 30) / 30 ), lower = gs_b, lpar = c(-Inf, -Inf) ) |> to_integer() # The IA nominal p-value is the same as the IA alpha spending x$bound$`nominal p`[1] gsDesign::sfLDOF(alpha = 0.025, t = 18 / 30)$spend
wlr_weight_fh
is Fleming-Harrington, FH(rho, gamma) weight function.
wlr_weight_1
is constant for log rank test.
wlr_weight_power
is Gehan-Breslow and Tarone-Ware weight function.
wlr_weight_mb
is Magirr (2021) weight function.
wlr_weight_fh(x, arm0, arm1, rho = 0, gamma = 0, tau = NULL) wlr_weight_1(x, arm0, arm1) wlr_weight_n(x, arm0, arm1, power = 1) wlr_weight_mb(x, arm0, arm1, tau = NULL, w_max = Inf)
wlr_weight_fh(x, arm0, arm1, rho = 0, gamma = 0, tau = NULL) wlr_weight_1(x, arm0, arm1) wlr_weight_n(x, arm0, arm1, power = 1) wlr_weight_mb(x, arm0, arm1, tau = NULL, w_max = Inf)
x |
A vector of numeric values. |
arm0 |
An |
arm1 |
An |
rho |
A scalar parameter that controls the type of test. |
gamma |
A scalar parameter that controls the type of test. |
tau |
A scalar parameter of the cut-off time for modest weighted log rank test. |
power |
A scalar parameter that controls the power of the weight function. |
w_max |
A scalar parameter of the cut-off weight for modest weighted log rank test. |
A vector of weights.
A vector of weights.
A vector of weights.
A vector of weights.
The contents of this section are shown in PDF user manual only.
enroll_rate <- define_enroll_rate( duration = c(2, 2, 10), rate = c(3, 6, 9) ) fail_rate <- define_fail_rate( duration = c(3, 100), fail_rate = log(2) / c(9, 18), hr = c(.9, .6), dropout_rate = .001 ) gs_arm <- gs_create_arm(enroll_rate, fail_rate, ratio = 1) arm0 <- gs_arm$arm0 arm1 <- gs_arm$arm1 wlr_weight_fh(1:3, arm0, arm1, rho = 0, gamma = 0, tau = NULL) enroll_rate <- define_enroll_rate( duration = c(2, 2, 10), rate = c(3, 6, 9) ) fail_rate <- define_fail_rate( duration = c(3, 100), fail_rate = log(2) / c(9, 18), hr = c(.9, .6), dropout_rate = .001 ) gs_arm <- gs_create_arm(enroll_rate, fail_rate, ratio = 1) arm0 <- gs_arm$arm0 arm1 <- gs_arm$arm1 wlr_weight_1(1:3, arm0, arm1) enroll_rate <- define_enroll_rate( duration = c(2, 2, 10), rate = c(3, 6, 9) ) fail_rate <- define_fail_rate( duration = c(3, 100), fail_rate = log(2) / c(9, 18), hr = c(.9, .6), dropout_rate = .001 ) gs_arm <- gs_create_arm(enroll_rate, fail_rate, ratio = 1) arm0 <- gs_arm$arm0 arm1 <- gs_arm$arm1 wlr_weight_n(1:3, arm0, arm1, power = 2) enroll_rate <- define_enroll_rate( duration = c(2, 2, 10), rate = c(3, 6, 9) ) fail_rate <- define_fail_rate( duration = c(3, 100), fail_rate = log(2) / c(9, 18), hr = c(.9, .6), dropout_rate = .001 ) gs_arm <- gs_create_arm(enroll_rate, fail_rate, ratio = 1) arm0 <- gs_arm$arm0 arm1 <- gs_arm$arm1 wlr_weight_mb(1:3, arm0, arm1, tau = -1, w_max = 1.2)
enroll_rate <- define_enroll_rate( duration = c(2, 2, 10), rate = c(3, 6, 9) ) fail_rate <- define_fail_rate( duration = c(3, 100), fail_rate = log(2) / c(9, 18), hr = c(.9, .6), dropout_rate = .001 ) gs_arm <- gs_create_arm(enroll_rate, fail_rate, ratio = 1) arm0 <- gs_arm$arm0 arm1 <- gs_arm$arm1 wlr_weight_fh(1:3, arm0, arm1, rho = 0, gamma = 0, tau = NULL) enroll_rate <- define_enroll_rate( duration = c(2, 2, 10), rate = c(3, 6, 9) ) fail_rate <- define_fail_rate( duration = c(3, 100), fail_rate = log(2) / c(9, 18), hr = c(.9, .6), dropout_rate = .001 ) gs_arm <- gs_create_arm(enroll_rate, fail_rate, ratio = 1) arm0 <- gs_arm$arm0 arm1 <- gs_arm$arm1 wlr_weight_1(1:3, arm0, arm1) enroll_rate <- define_enroll_rate( duration = c(2, 2, 10), rate = c(3, 6, 9) ) fail_rate <- define_fail_rate( duration = c(3, 100), fail_rate = log(2) / c(9, 18), hr = c(.9, .6), dropout_rate = .001 ) gs_arm <- gs_create_arm(enroll_rate, fail_rate, ratio = 1) arm0 <- gs_arm$arm0 arm1 <- gs_arm$arm1 wlr_weight_n(1:3, arm0, arm1, power = 2) enroll_rate <- define_enroll_rate( duration = c(2, 2, 10), rate = c(3, 6, 9) ) fail_rate <- define_fail_rate( duration = c(3, 100), fail_rate = log(2) / c(9, 18), hr = c(.9, .6), dropout_rate = .001 ) gs_arm <- gs_create_arm(enroll_rate, fail_rate, ratio = 1) arm0 <- gs_arm$arm0 arm1 <- gs_arm$arm1 wlr_weight_mb(1:3, arm0, arm1, tau = -1, w_max = 1.2)