Skip to contents

Enables systematic, dependency-aware scenario exploration for group sequential designs created by gsDesign. gsDesignTune is built for design space evaluation (ranking, filtering, Pareto trade-offs) rather than claiming a single “optimal design”. With a focus on user experience, correctness, and speed, it supports off-the-shelf parallel processing with progress tracking, caching, and reproducible reporting.

Installation

You can install gsDesignTune from CRAN:

install.packages("gsDesignTune")

Or try the development version from GitHub:

# install.packages("pak")
pak::pak("nanxstats/gsDesignTune")

Features

  • Drop-in workflow: replace gsDesign()/gsSurv()/gsSurvCalendar() with gsDesignTune()/gsSurvTune()/gsSurvCalendarTune(), then $run().
  • Dependency-aware tuning: express design parameter dependency relationships precisely, for example, spending functions and their spending parameters.
  • Grid and random search over candidate sets, with vector-valued arguments treated atomically.
  • Parallel evaluation via {future} / {future.apply} with progress via {progressr}. Use any {future} backend that fits your infrastructure.
  • Reproducible and auditable results: per-configuration warnings/errors and reconstructable underlying call.
  • Optional caching of design objects to disk and HTML reporting via {rmarkdown}.

Quick start

Evaluate time-to-event designs:

library(gsDesign)
library(gsDesignTune)
library(future)

plan(multisession, workers = 2)

job <- gsSurvTune(
  k = 3,
  test.type = 4,
  alpha = 0.025,
  beta = 0.10,
  timing = tune_values(list(c(0.33, 0.67, 1), c(0.5, 0.75, 1))),
  hr = tune_seq(0.55, 0.75, length_out = 5),
  upper = SpendingFamily$new(
    SpendingSpec$new(sfLDOF, par = tune_fixed(0)),
    SpendingSpec$new(sfHSD, par = tune_seq(-4, 4, length_out = 9))
  ),
  lower = SpendingSpec$new(sfLDOF, par = tune_fixed(0)),
  lambdaC = log(2) / 6,
  eta = 0.01,
  gamma = c(2.5, 5, 7.5, 10),
  R = c(2, 2, 2, 6),
  T = 18,
  minfup = 6,
  ratio = 1
)

job$run(strategy = "grid", parallel = TRUE, seed = 1, cache_dir = "gstune_cache")

res <- job$results()

job$table(n = 10)
Config ID Upper bound Upper parameter Timing HR Final events Final total N Power Upper Z (IA1) Lower Z (IA1)
1 sfLDOF 0 0.33, 0.67, 1 0.55 124 222 0.9 3.73 -0.719
2 sfLDOF 0 0.33, 0.67, 1 0.6 170 296 0.9 3.73 -0.719
3 sfLDOF 0 0.33, 0.67, 1 0.65 240 406 0.9 3.73 -0.719
4 sfLDOF 0 0.33, 0.67, 1 0.7 350 580 0.9 3.73 -0.719
5 sfLDOF 0 0.33, 0.67, 1 0.75 538 874 0.9 3.73 -0.719
6 sfLDOF 0 0.5, 0.75, 1 0.55 127 226 0.9 2.96 0.332
7 sfLDOF 0 0.5, 0.75, 1 0.6 174 302 0.9 2.96 0.332
8 sfLDOF 0 0.5, 0.75, 1 0.65 245 414 0.9 2.96 0.332
9 sfLDOF 0 0.5, 0.75, 1 0.7 357 592 0.9 2.96 0.332
10 sfLDOF 0 0.5, 0.75, 1 0.75 549 892 0.9 2.96 0.332
job$best("final_events", direction = "min") |>
  job$table(n = 10)
Config ID Upper bound Upper parameter Timing HR Final events Final total N Power Upper Z (IA1) Lower Z (IA1)
1 sfLDOF 0 0.33, 0.67, 1 0.55 124 222 0.9 3.73 -0.719
11 sfHSD -4 0.33, 0.67, 1 0.55 125 222 0.9 3.02 -0.716
21 sfHSD -3 0.33, 0.67, 1 0.55 126 224 0.9 2.85 -0.707
6 sfLDOF 0 0.5, 0.75, 1 0.55 127 226 0.9 2.96 0.332
16 sfHSD -4 0.5, 0.75, 1 0.55 127 226 0.9 2.75 0.332
31 sfHSD -2 0.33, 0.67, 1 0.55 128 228 0.9 2.68 -0.692
26 sfHSD -3 0.5, 0.75, 1 0.55 128 228 0.9 2.61 0.344
36 sfHSD -2 0.5, 0.75, 1 0.55 130 232 0.9 2.47 0.361
41 sfHSD -1 0.33, 0.67, 1 0.55 131 232 0.9 2.53 -0.67
46 sfHSD -1 0.5, 0.75, 1 0.55 133 236 0.9 2.35 0.387
job$pareto(
  metrics = c("final_events", "upper_z1"),
  directions = c("min", "min")
) |> job$table(n = 10)
Config ID Upper bound Upper parameter Timing Final events Final total N Power Upper Z (IA1) Lower Z (IA1)
1 sfLDOF 0 0.33, 0.67, 1 124 222 0.9 3.73 -0.719
11 sfHSD -4 0.33, 0.67, 1 125 222 0.9 3.02 -0.716
16 sfHSD -4 0.5, 0.75, 1 127 226 0.9 2.75 0.332
21 sfHSD -3 0.33, 0.67, 1 126 224 0.9 2.85 -0.707
26 sfHSD -3 0.5, 0.75, 1 128 228 0.9 2.61 0.344
31 sfHSD -2 0.33, 0.67, 1 128 228 0.9 2.68 -0.692
36 sfHSD -2 0.5, 0.75, 1 130 232 0.9 2.47 0.361
46 sfHSD -1 0.5, 0.75, 1 133 236 0.9 2.35 0.387
56 sfHSD 0 0.5, 0.75, 1 137 244 0.9 2.24 0.423
66 sfHSD 1 0.5, 0.75, 1 142 254 0.9 2.16 0.47
job$plot(metric = "final_events", x = "hr", color = "upper_fun")

job$report("gstune_report.html")

Tune specifications

  • tune_fixed(x): explicit fixed value (useful inside dependencies)
  • tune_values(list(...)): explicit candidates (supports vector-valued candidates)
  • tune_seq(from, to, length_out), tune_int(from, to, by)
  • tune_choice(...): categorical choices
  • tune_dep(depends_on, map): dependent mapping for any argument

See vignettes for end-to-end examples, spending function tuning, and parallel + reproducible reporting.