Free examples and use-cases:   rpact vignettes
rpact: Confirmatory Adaptive Clinical Trial Design and Analysis

# Summary

This R Markdown document provides example code for the the definition of the most commonly used group sequential boundaries in rpact.

# 1 Introduction

In rpact, sample size calculation for a group sequential trial proceeds by following the same two steps regardless of whether the endpoint is a continuous, binary, or a time-to-event endpoint:

1. Define the (abstract) group sequential boundaries of the design using the function getDesignGroupSequential().
2. Calculate sample size for the endpoint of interest by feeding the abstract boundaries from step 1. into specific functions for the endpoint of interest. This step uses functions such as getSampleSizeMeans() (for continuous endpoints), getSampleSizeRates() (for binary endpoints), and getSampleSizeSurvival() (for survival endpoints).

The mathematical rationale for this two-step approach is that all group sequential trials, regardless of the chosen endpoint type, rely on the fact that the $$z$$-scores at different interim stages follow the same “canonical joint multivariate distribution” (at least asymptotically).

This document covers the more abstract first step, Step 2 is not covered in this document but it is covered in the separate endpoint-specific R Markdown files for continuous, binary, and time to event endpoints. Of note, step 1 can be omitted for trials without interim analyses.

These examples are not intended to replace the official rpact documentation and help pages but rather to supplement them.

In general, rpact supports both one-sided and two-sided group sequential designs. If futility boundaries are specified, however, only one-sided tests are permitted. For simplicity, it is often preferred to use one-sided tests for group sequential designs (typically, with $$\alpha = 0.025$$).

library(rpact)
packageVersion("rpact") # version should be version 2.0.5 or later
## [1] '3.3.2'

# 2 Designs with efficacy interim analyses

## 2.1 O’Brien & Fleming type $$\alpha$$-spending

Example:

• Interim analyses at information fractions 33%, 67%, and 100% ( informationRates = c(0.33, 0.67, 1) ). [Note: For equally spaced interim analyses, one can also specify the maximum number of stages (kMax, including the final analysis) instead of the informationRates.]
• Lan & DeMets $$\alpha$$-spending approximation to the O’Brien & Fleming boundaries (typeOfDesign = "asOF")
• $$\alpha$$-spending approaches allow for flexible timing of interim analyses and corresponding adjustment of boundaries.
design <- getDesignGroupSequential(
sided = 1, alpha = 0.025,
informationRates = c(0.33, 0.67, 1), typeOfDesign = "asOF"
)

## 2.2 Standard O’Brien & Fleming boundaries

The originally published O’Brien & Fleming boundaries are obtained via typeOfDesign = "OF" which is also the default (therefore, if you do not specify typeOfDesign, this type is selected). Note that strict Type I error control is only guaranteed for standard boundaries without $$\alpha$$-spending if the pre-defined interim schedule (i.e., the information fractions at which interim analyses are conducted) is exactly adhered to.

design <- getDesignGroupSequential(
sided = 1, alpha = 0.025,
informationRates = c(0.33, 0.67, 1), typeOfDesign = "OF"
)

## 2.3 Standard Pocock and Haybittle & Peto boundaries

Pocock (typeOfDesign = "P" for constant boundaries over the stages, typeOfDesign = "asP" for corresponding $$\alpha$$-spending version) or Haybittle & Peto (typeOfDesign = "HP") boundaries (reject at interim if $$z$$-value exceeds 3) is obtained with, for example,

design <- getDesignGroupSequential(
sided = 1, alpha = 0.025,
informationRates = c(0.33, 0.67, 1), typeOfDesign = "P"
)

## 2.4 Other pre-defined boundaries

• Kim & DeMets $$\alpha$$-spending (typeOfDesign = "asKD) with parameter gammaA (power function: gammaA = 1 is linear spending, gammaA = 2 quadratic)
• Hwang, Shi & DeCani $$\alpha$$-spending (typeOfDesign = "asHSD") with parameter gammaA (for details, see Wassmer & Brannath 2016, p. 76)
• Standard Wang & Tsiatis Delta classes (typeOfDesign = "WT") and (typeOfDesign = "WToptimum")
# Quadratic Kim & DeMets alpha-spending
design <- getDesignGroupSequential(
sided = 1, alpha = 0.025,
informationRates = c(0.33, 0.67, 1), typeOfDesign = "asKD", gammaA = 2
)

## 2.5 User-defined $$\alpha$$-spending functions

User-defined $$\alpha$$-spending functions (typeOfDesign = "asUser") can be obtained via the argument userAlphaSpending which must contain a numeric vector with elements $$0< \alpha_1 < \ldots < \alpha_{kMax} = \alpha$$ that define the values of the cumulative alpha-spending function at each interim analysis.

# Example: User-defined alpha-spending function which is very conservative at
# first interim (spend alpha = 0.001), conservative at second (spend an additional
# alpha = 0.01, i.e., total cumulative alpha spent is 0.011 up to second interim),
# and spends the remaining alpha at the final analysis (i.e., cumulative
# alpha = 0.025)
design <- getDesignGroupSequential(
sided = 1, alpha = 0.025,
informationRates = c(0.33, 0.67, 1),
typeOfDesign = "asUser",
userAlphaSpending = c(0.001, 0.01 + 0.001, 0.025)
)
# $stageLevels below extract local significance levels across interim analyses. # Note that the local significance level is exactly 0.001 at the first # interim, but slightly >0.01 at the second interim because the design # exploits correlations between interim analyses. design$stageLevels
## [1] 0.00100000 0.01052883 0.02004781

# 3 Designs with efficacy and futility interim analyses

## 3.1 Futility boundaries at interims manually defined on $$z$$-scale

• The argument futilityBounds contains a vector of futility bounds (on the $$z$$-value scale) for each interim (but not the final analysis).
• A futility bound of $$z = 0$$ corresponds to an estimated treatment effect of zero or “null”, i.e., in this case futility stopping is recommended if the treatment effect estimate at the interim analysis is zero or “goes in the wrong direction”. Futility bounds of $$z = -\infty$$ (which are numerically equivalent to $$z = -6$$) correspond to no futility stopping at an interim.
• Due to the design of rpact, it is not possible to directly define futility boundaries on the treatment effect scale. If this is desired, one would need to manually convert the treatment effect scale to the $$z$$-scale or, alternatively, experiment by varying the boundaries on the $$z$$-scale until this implies the targeted critical values on the treatment effect scale. (Critical values on treatment effect scales are routinely provided by sample size functions for different endpoint types such as getSampleSizeMeans() (for continuous endpoints), getSampleSizeRates() (for binary endpoints), and getSampleSizeSurvival() (for survival endpoints). Please see the R Markdown files for these endpoint types for further details.)
• By default, all futility boundaries are non-binding (bindingFutility = FALSE). Binding futility boundaries (bindingFutility = TRUE) are not recommended although they are provided for the sake of completeness.
# Example: non-binding futility boundary at each interim in case
# estimated treatment effect is null or goes in "the wrong direction"
design <- getDesignGroupSequential(
sided = 1, alpha = 0.025,
informationRates = c(0.33, 0.67, 1), typeOfDesign = "asOF",
futilityBounds = c(0, 0), bindingFutility = FALSE
)

## 3.2 Formal $$\beta$$-spending and Pampallona & Tsiatis approach

Formal $$\beta$$-spending functions are defined in the same way as for $$\alpha$$-spending functions, e.g., a Pocock type $$\beta$$-spending can be specified as typeBetaSpending = "bsP" and beta needs to be specified, the default is beta = 0.20.

# Example: beta-spending function approach with O'Brien & Fleming alpha-spending
# function and Pocock beta-spending function
design <- getDesignGroupSequential(
sided = 1, alpha = 0.025, beta = 0.1,
typeOfDesign = "asOF",
typeBetaSpending = "bsP"
)

Another way to formally derive futility bounds is through the Pampallona and Tsiatis approach. This is through defining typeBetaSpending = "PT", and the specification of two parameters, deltaPT1 (shape of decision regions for rejecting the null) and deltaPT0 (shape of shifted decision regions for rejecting the alternative), for example

# Example: beta-spending function approach with O'Brien & Fleming boundaries for
# rejecting the null and Pocock boundaries for rejecting H1
design <- getDesignGroupSequential(
sided = 1, alpha = 0.025, beta = 0.1,
typeOfDesign = "PT",
deltaPT1 = 0, deltaPT0 = 0.5
)

Note that both the $$\beta$$-spending as well as the Pampallona & Tsiatis approach can be selected to be one-sided or two-sided, the bounds for rejecting the alternative to be binding (bindingFutility = TRUE) or non-binding (bindingFutility = FALSE).

# 4 Designs with futility interim analyses only

Such designs can be implemented by using a user-defined $$\alpha$$-spending function which spends all of the Type I error at the final analysis. Note that such designs do not allow stopping for efficacy regardless how persuasive the effect is.

# Example: non-binding futility boundary using an O'Brien & Fleming type
# beta spending function. No early stopping for efficacy (i.e., all alpha</