Learn R Programming

gsDesign2 (version 1.1.8)

gs_update_ahr: Group sequential design using average hazard ratio under non-proportional hazards

Description

Group sequential design using average hazard ratio under non-proportional hazards

Usage

gs_update_ahr(
  x = NULL,
  alpha = NULL,
  ustime = NULL,
  lstime = NULL,
  event_tbl = NULL
)

Value

A list with input parameters, enrollment rate, failure rate, analysis, and bound.

Arguments

x

A design created by either gs_design_ahr() or gs_power_ahr().

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.

event_tbl

A data frame with two columns: (1) analysis and (2) event, which represents the events observed at each analysis per piecewise interval. This can be defined via the pw_observed_event() function or manually entered. For example, consider a scenario with two intervals in the piecewise model: the first interval lasts 6 months with a hazard ratio (HR) of 1, and the second interval follows with an HR of 0.6. The data frame event_tbl = data.frame(analysis = c(1, 1, 2, 2), event = c(30, 100, 30, 200)) indicates that 30 events were observed during the delayed effect period, 130 events were observed at the IA, and 230 events were observed at the FA.

Examples

Run this code
library(gsDesign)
library(gsDesign2)

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

# ------------------------------------------------- #
# 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()

planned_event_ia <- x$analysis$event[1]
planned_event_fa <- x$analysis$event[2]


# Updated design with 190 events observed at IA,
# where 50 events observed during the delayed effect.
# IA spending = observed events / final planned events, the remaining alpha will be allocated to FA.
gs_update_ahr(
  x = x,
  ustime = c(190 / planned_event_fa, 1),
  lstime = c(190 / planned_event_fa, 1),
  event_tbl = data.frame(analysis = c(1, 1),
                         event = c(50, 140)))

# Updated design with 190 events observed at IA, and 300 events observed at FA,
# where 50 events observed during the delayed effect.
# IA spending = observed events / final planned events, the remaining alpha will be allocated to FA.
gs_update_ahr(
  x = x,
  ustime = c(190 / planned_event_fa, 1),
  lstime = c(190 / planned_event_fa, 1),
  event_tbl = data.frame(analysis = c(1, 1, 2, 2),
                         event = c(50, 140, 50, 250)))

# Updated design with 190 events observed at IA, and 300 events observed at FA,
# where 50 events observed during the delayed effect.
# IA spending = minimal of planned and actual information fraction spending
gs_update_ahr(
  x = x,
  ustime = c(min(190, planned_event_ia) / planned_event_fa, 1),
  lstime = c(min(190, planned_event_ia) / planned_event_fa, 1),
  event_tbl = data.frame(analysis = c(1, 1, 2, 2),
                         event = c(50, 140, 50, 250)))

# Alpha is updated to 0.05
gs_update_ahr(x = x, alpha = 0.05)

# ------------------------------------------------- #
# Two-sided asymmetric stratified design,
# beta-spending with non-binding lower bound
# ------------------------------------------------- #
enroll_rate <- define_enroll_rate(stratum = c("A", "B"), duration = c(12, 12), rate = c(1, 1))

# We assumme there are 2 strata, "A" and "B".
# For each stratum, there are delayed effect for the first 3 months.
# After the delayed effect, the HR is 0.8 for stratum A and 0.5 for stratum B.
fail_rate <- define_fail_rate(stratum = c("A", "A", "B", "B"),
                              duration = c(3, Inf, 3, Inf),
                              fail_rate = log(2) / c(9, 9, 9, 15),
                              hr = c(1, 0.8, 1, 0.5),
                              dropout_rate = rep(0.001, 4))

# The original design assumes there are 2 IAs and 1 FA cutting by calendar time.
# The efficacy testing is conducted at IA2 and FA.
# The futility testing is conducted at IA1.
x <- gs_design_ahr(enroll_rate = enroll_rate,
                  fail_rate = fail_rate,
                  alpha = 0.0125,
                  beta = 0.1,
                  analysis = c(20, 28, 36),
                  upper = "gs_spending_bound",
                  upar = list(sf = "sfLDOF", total_spend = 0.0125),
                  lower = "gs_spending_bound",
                  lpar = list(sf = "sfHSD", total_spend = 0.1, param = -8),
                  test_upper = c(FALSE, TRUE, TRUE),
                  test_lower = c(TRUE, FALSE, FALSE)) |> to_integer()

# At time of analysis
# For IA1,
# - There are 70 events observed during the delayed effect period for stratum A.
# - There are 150 events observed after the delayed effect period for stratum A.
# - There are 75 events observed during the delayed effect period for stratum B.
# - There are 90 events observed after the delayed effect period for stratum B.
# For IA2,
# - There are 75 events observed during the delayed effect period for stratum A.
# - There are 210 events observed after the delayed effect period for stratum A.
# - There are 76 events observed during the delayed effect period for stratum B.
# - There are 136 events observed after the delayed effect period for stratum B.
# For FA,
# - There are 77 events observed during the delayed effect period for stratum A.
# - There are 245 events observed after the delayed effect period for stratum A.
# - There are 77 events observed during the delayed effect period for stratum B.
# - There are 170 events observed after the delayed effect period for stratum B.
event_tbl <- data.frame(analysis = c(1, 1, 1, 1,
                                    2, 2, 2, 2,
                                    3, 3, 3, 3),
                       stratum = c("A", "A", "B", "B", # IA1
                                   "A", "A", "B", "B", # IA2
                                   "A", "A", "B", "B"),# FA
                                 # event per interval per stratum at IA1
                       event = c(70, 150, 75, 90,
                                 # event per interval per stratum at IA2
                                 75, 210, 76, 136,
                                 # event per interval per stratum at FA
                                 77, 245, 77, 170))
observed_event <- (event_tbl |> dplyr::group_by(analysis) |> dplyr::summarize(x = sum(event)))$x

ustime <- pmin(x$analysis$event,
               observed_event) / x$analysis$event[3]
ustime[3] <- 1
lstime <- ustime

xu <- gs_update_ahr(x = x,
                    alpha = 0.015,
                    ustime = ustime,
                    lstime = lstime,
                    event_tbl = event_tbl
                    )

Run the code above in your browser using DataLab