Group sequential design methods for interim analyses, alpha spending, and futility stopping. Use when designing trials with interim looks or implementing spending functions.
/plugin marketplace add choxos/ClinicalTrialAgent/plugin install choxos-clinical-trial-simulation-plugins-clinical-trial-simulation@choxos/ClinicalTrialAgentThis skill inherits all available tools. When active, it can use any tool Claude has access to.
A group sequential design allows for:
Information fraction at analysis k:
I_k / I_K = (events at analysis k) / (total planned events)
For time-to-event trials, information ≈ number of events.
The key constraint: Σ α_k ≤ α (overall Type I error)
Spending functions distribute alpha across analyses.
Properties:
Formula:
α*(t) = 2 - 2Φ(z_{α/2} / √t)
When to Use:
Properties:
Formula:
α*(t) = α × log(1 + (e-1)t)
When to Use:
Properties:
Formula:
α*(t) = α × (1 - e^{-γt}) / (1 - e^{-γ})
When to Use:
| Function | Early Spending | Final Power | Early Stopping |
|---|---|---|---|
| OBF | Low | High | Difficult |
| Pocock | High | Lower | Easier |
| HSD(γ=-4) | Low | High | Difficult |
| HSD(γ=1) | High | Lower | Easier |
Similar to alpha-spending, but for Type II error:
β*(t) = spending function × β
# Interim Analysis 1
ia1_cut <- create_cut(
planned_calendar_time = 20, # Minimum 20 months
target_event_overall = 100, # Target 100 events
max_extension_for_target_event = 24, # Wait up to 24 months for events
min_n_overall = 200, # At least 200 enrolled
min_followup = 12 # 12 months minimum follow-up
)
# Interim Analysis 2
ia2_cut <- create_cut(
planned_calendar_time = 32,
target_event_overall = 200,
max_extension_for_target_event = 34,
min_time_after_previous_analysis = 10 # At least 10 months after IA1
)
# Final Analysis
fa_cut <- create_cut(
planned_calendar_time = 45,
target_event_overall = 350
)
library(simtrial)
library(gsDesign2)
# Define enrollment
enroll_rate <- define_enroll_rate(
duration = c(4, 12),
rate = c(10, 30)
)
# Define failure rates
fail_rate <- define_fail_rate(
duration = c(3, 100),
fail_rate = log(2)/9,
hr = c(1, 0.6),
dropout_rate = 0.001
)
# Run simulation
results <- sim_gs_n(
n_sim = 1000,
sample_size = 400,
enroll_rate = enroll_rate,
fail_rate = fail_rate,
test = wlr,
cut = list(ia1 = ia1_cut, ia2 = ia2_cut, fa = fa_cut),
weight = fh(rho = 0, gamma = 0)
)
library(gsDesign2)
# Design with gsDesign2
design <- gs_design_ahr(
enroll_rate = define_enroll_rate(duration = c(4, 12), rate = c(10, 30)),
fail_rate = define_fail_rate(
duration = c(3, 100),
fail_rate = log(2)/9,
hr = c(1, 0.6),
dropout_rate = 0.001
),
alpha = 0.025,
beta = 0.1,
analysis_time = c(24, 36, 48),
upper = gs_spending_bound,
upar = list(sf = gsDesign::sfLDOF, total_spend = 0.025),
lower = gs_spending_bound,
lpar = list(sf = gsDesign::sfHSD, param = -4, total_spend = 0.1)
) |> to_integer()
# Simulate with design object
sim_results <- sim_gs_n(
n_sim = 1000,
sample_size = max(design$analysis$n),
enroll_rate = design$enroll_rate,
fail_rate = design$fail_rate,
test = wlr,
cut = NULL, # Auto-generated from design
original_design = design,
weight = fh(rho = 0, gamma = 0)
)
When using original_design, sim_gs_n() can compute updated bounds:
# Results include planned and updated bounds
results <- sim_gs_n(
# ... parameters ...
original_design = design,
ia_alpha_spending = "min_planned_actual", # Conservative
fa_alpha_spending = "full_alpha" # Spend full alpha at FA
)
# Output includes:
# - planned_upper_bound, planned_lower_bound
# - updated_upper_bound, updated_lower_bound
Alpha Spending Options:
| ia_alpha_spending | Description |
|---|---|
| "min_planned_actual" | Conservative: min of planned and actual |
| "actual" | Spend based on actual information |
| fa_alpha_spending | Description |
|---|---|
| "full_alpha" | Spend remaining alpha at final |
| "info_frac" | Spend based on information fraction |
# Different tests at each analysis
ia1_test <- create_test(wlr, weight = fh(rho = 0, gamma = 0))
ia2_test <- create_test(wlr, weight = fh(rho = 0, gamma = 0.5))
fa_test <- create_test(wlr, weight = mb(delay = 6, w_max = Inf))
results <- sim_gs_n(
n_sim = 1000,
sample_size = 400,
enroll_rate = enroll_rate,
fail_rate = fail_rate,
test = list(ia1 = ia1_test, ia2 = ia2_test, fa = fa_test),
cut = list(ia1 = ia1_cut, ia2 = ia2_cut, fa = fa_cut)
)
# IA at 50% information, FA at 100%
ia_cut <- create_cut(target_event_overall = 150) # 50%
fa_cut <- create_cut(target_event_overall = 300) # 100%
sim_gs_n(
n_sim = 1000,
sample_size = 400,
test = wlr,
cut = list(ia = ia_cut, fa = fa_cut),
weight = fh(0, 0)
)
# Standard 33%, 67%, 100% information
ia1_cut <- create_cut(target_event_overall = 100)
ia2_cut <- create_cut(target_event_overall = 200)
fa_cut <- create_cut(target_event_overall = 300)
# Events-based but with minimum calendar time
ia_cut <- create_cut(
target_event_overall = 150,
planned_calendar_time = 18, # At least 18 months
max_extension_for_target_event = 24 # Max 24 months
)
# Summarize simulation results
results_summary <- results |>
group_by(analysis) |>
summarise(
mean_events = mean(event),
mean_z = mean(z),
power = mean(z < qnorm(0.025)), # One-sided
.groups = "drop"
)
plan("multisession") for large simulationsThis skill should be used when the user asks about libraries, frameworks, API references, or needs code examples. Activates for setup questions, code generation involving libraries, or mentions of specific frameworks like React, Vue, Next.js, Prisma, Supabase, etc.
Applies Anthropic's official brand colors and typography to any sort of artifact that may benefit from having Anthropic's look-and-feel. Use it when brand colors or style guidelines, visual formatting, or company design standards apply.
Creating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems. Create original algorithmic art rather than copying existing artists' work to avoid copyright violations.