# 2024-02-22: Converted `example("sim_gs_n")` to tests from commit 306de0d
enroll_rampup_duration <- 4 # duration for enrollment ramp up
enroll_duration <- 16 # total enrollment duration
delay_effect_duration <- 3 # delay treatment effect in months
median_ctrl <- 9 # survival median of the control arm
median_exp <- c(9, 14) # survival median of the experimental arm
ratio <- 1 # randomization ratio (exp:ctrl)
# The 1st interim analysis will occur at the later of the following 3 conditions:
# - At least 20 months have passed since the start of the study
# - At least 20 months have elapsed after enrolling 200/400 subjects, with a
# However, if events accumulation is slow, we will wait for a maximum of 24 months.
# The 2nd interim analysis will occur at the later of the following 3 conditions:
# - At least 32 months have passed since the start of the study
# However, if events accumulation is slow, we will wait for a maximum of 34 months.
# The final analysis will occur at the later of the following 2 conditions:
# - At least 45 months have passed since the start of the study
cut <- list(ia1 = ia1_cut, ia2 = ia2_cut, fa = fa_cut)
parameter = rep("FH(rho=0, gamma=0)", 9L),
expect_equal(observed, expected, ignore_attr = TRUE)
test_that("regular logrank test parallel", {
test_that("weighted logrank test by FH(0, 0.5)", {
parameter = rep("FH(rho=0, gamma=0.5)", 9L),
test_that("weighted logrank test by MB(3)", {
parameter = rep("MB(delay = 3, max_weight = Inf)", 9L),
test_that("weighted logrank test by early zero (6)", {
parameter = rep("Xu 2017 with first 6 months of 0 weights", 9L),
test_that("WLR with fh(0, 0.5) test at IA1, WLR with mb(6, Inf) at IA2, and milestone test at FA", {
ia1_test <- create_test(wlr, weight = fh(rho = 0, gamma = 0.5))
ia2_test <- create_test(wlr, weight = mb(delay = 6, w_max = Inf))
fa_test <- create_test(milestone, ms_time = 10, test_type = "naive")
test = list(ia1 = ia1_test, ia2 = ia2_test, fa = fa_test),
method = rep(c("WLR", "WLR", "milestone"), 3),
parameter = rep(c("FH(rho=0, gamma=0.5)", "MB(delay = 6, max_weight = Inf)", "10"), 3),
test_that("MaxCombo (WLR-FH(0,0) + WLR-FH(0, 0.5))", {
test_that("sim_gs_n() accepts different tests per cutting", {
wlr_cut1 <- create_test(wlr, weight = fh(rho = 0, gamma = 0))
wlr_cut2 <- create_test(wlr, weight = fh(rho = 0, gamma = 0.5))
wlr_cut3 <- create_test(wlr, weight = fh(rho = 0.5, gamma = 0))
test = list(wlr_cut1, wlr_cut2, wlr_cut3),
parameter = rep(c("FH(rho=0, gamma=0)", "FH(rho=0, gamma=0.5)", "FH(rho=0.5, gamma=0)"), 3),
attr(expected, "method") <- unique(observed$parameter[observed$sim_id == 1])
test_that("sim_gs_n() requires a test for each cutting", {
"If you want to run different tests at each cutting"
test_that("sim_gs_n() can combine wlr(), rmst(), and milestone() tests", {
test_cut1 <- create_test(wlr, weight = fh(rho = 0, gamma = 0))
test_cut2 <- create_test(rmst, tau = 20)
test_cut3 <- create_test(milestone, ms_time = 10, test_type = "naive")
test = list(test_cut1, test_cut2, test_cut3),
method = rep(c("WLR", "RMST", "milestone"), 3),
test_that("convert_list_to_df_w_list_cols() is robust to diverse input", {
test_that("create_cut() can accept variables as arguments", {
enroll_rate <- gsDesign2::define_enroll_rate(duration = c(2, 2, 8),
fail_rate <- gsDesign2::define_fail_rate(duration = c(4, Inf),
upar <- list(sf = gsDesign::sfLDOF, total_spend = alpha)
lpar <- list(sf = gsDesign::sfLDOF, total_spend = beta)
x <- gsDesign2::gs_design_ahr(enroll_rate = enroll_rate, fail_rate = fail_rate,
alpha = alpha, beta = beta, ratio = ratio,
info_frac = info_frac, analysis_time = analysis_time,
upper = upper, upar = upar, test_upper = test_upper,
lower = lower, lpar = lpar, test_lower = test_lower,
binding = binding) |> gsDesign2::to_integer()
ia_cut <- simtrial::create_cut(planned_calendar_time = x$analysis$time[1])
fa_cut <- simtrial::create_cut(planned_calendar_time = x$analysis$time[2])
# Must run the parallel version first for 2 reasons:
# 1. In order to reproduce the bug that inspired this test, the cutting
# functions must not have been evaluated prior to running them in parallel
# 2. In order to avoid an R CMD check NOTE about detritus in the temp
# directory, need to run `future::plan("sequential")` to shut down parallel
weight = simtrial::fh(rho = 0, gamma = 0))
test_that("Updating bounds changes the simulation results", {
x <- gsDesign2::gs_design_ahr(analysis_time = 1:3*12) |>
cut = list(ia1 = create_cut(planned_calendar_time = x$analysis$time[1]),
ia2 = create_cut(planned_calendar_time = x$analysis$time[2]),
fa = create_cut(planned_calendar_time = x$analysis$time[3])),
expect_equal(run1, run2[, colnames(run1)], ignore_attr = TRUE)
observed <- run2[, c("planned_upper_bound", "planned_lower_bound",
test_that("sim_gs_n() can update bounds even when some are missing", {
upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025),
lpar = list(sf = gsDesign::sfHSD, param = -4, total_spend = 0.01),