
<!-- README.md is generated from README.Rmd. Please edit that file -->

# gsDesignTune

<!-- badges: start -->

[![R-CMD-check](https://github.com/nanxstats/gsDesignTune/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/nanxstats/gsDesignTune/actions/workflows/R-CMD-check.yaml)
![CRAN status](https://www.r-pkg.org/badges/version/gsDesignTune)
<!-- badges: end -->

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 the development version of gsDesignTune from GitHub
with:

``` r
# 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:

``` r
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()
head(res)

job$best("final_events", direction = "min")
job$pareto(metrics = c("final_events", "upper_z1"), directions = c("min", "min"))

job$plot(metric = "final_events", x = "hr", color = "upper_fun")
```

<img src="man/figures/README-example-1.svg" alt="" width="100%" style="display: block; margin: auto;" />

``` r
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.
