simFastBOIN

Fast Bayesian Optimal Interval Design for Phase I Dose-Finding Trials


License
MIT

Documentation

simFastBOIN

R-CMD-check CRAN status Lifecycle: stable License: MIT CRAN downloads Monthly downloads

Fast and efficient simulation tools for Bayesian Optimal Interval (BOIN) designs in Phase I clinical trials.

Overview

simFastBOIN provides comprehensive functions for simulating Phase I dose-finding trials using the BOIN design methodology. The package enables researchers to evaluate operating characteristics and design performance across different dose-toxicity scenarios, essential for protocol development and regulatory submissions.

Key Features:

  • High Performance: Vectorized implementation and optimized algorithms
  • BOIN Compatible: Results match BOIN package within <0.5% across all scenarios
  • User-Friendly: Simplified API with automatic decision table generation
  • Flexible: Multiple safety stopping rules and customizable design parameters
  • Multi-Scenario Support: Evaluate multiple dose-toxicity scenarios simultaneously
  • Conservative MTD Selection: Optional boundMTD constraint for enhanced safety
  • Publication-Ready Output: Professional table formatting with HTML, LaTeX, and Markdown options

Installation

You can install the development version from GitHub:

# Install if not already installed
# install.packages("devtools")
devtools::install_github("gosukehommaEX/simFastBOIN")

Quick Start

Basic Usage

library(simFastBOIN)

# Define design parameters
target <- 0.30  # Target DLT rate (30%)
p_true <- seq(0.05, 0.45, by = 0.05)  # True toxicity probabilities

# Run simulation (runs silently by default)
result <- sim_boin(
  n_trials = 10000,
  target = target,
  p_true = p_true,
  n_cohort = 20,
  cohort_size = 3,
  seed = 123
)

# Display results
print(result$summary)

# To see progress messages, use verbose = TRUE
result_verbose <- sim_boin(
  n_trials = 10000,
  target = target,
  p_true = p_true,
  n_cohort = 20,
  cohort_size = 3,
  verbose = TRUE,  # Show progress
  seed = 123
)

Enhanced Output Formatting

# Display with percentages instead of absolute numbers
print(result$summary, percent = TRUE)

# Display in Markdown pipe format for R Markdown documents
print(result$summary, kable = TRUE, kable_format = "pipe")

# LaTeX format for publication
print(result$summary, kable = TRUE, kable_format = "latex", scenario_name = "My Scenario")

# HTML format for web display
print(result$summary, kable = TRUE, kable_format = "html")

Multi-Scenario Simulations

# Define multiple dose-toxicity scenarios
scenarios <- list(
  list(name = "Scenario 1: Linear Increase",
       p_true = c(0.05, 0.10, 0.15, 0.20, 0.25, 0.30, 0.35, 0.40, 0.45)),
  list(name = "Scenario 2: Steep Early",
       p_true = c(0.01, 0.025, 0.05, 0.075, 0.10, 0.125, 0.15, 0.20, 0.30)),
  list(name = "Scenario 3: Plateau",
       p_true = c(0.15, 0.20, 0.25, 0.30, 0.45, 0.50, 0.50, 0.50, 0.50))
)

# Run simulations across all scenarios
result <- sim_boin_multi(
  scenarios = scenarios,
  target = 0.30,
  n_trials = 10000,
  n_cohort = 48,
  cohort_size = 3,
  seed = 123
)

# View aggregated results
print(result)

# View as HTML table
print(result, kable = TRUE, kable_format = "html")

# Access scenario-specific results
result$results_by_scenario[["Scenario 1: Linear Increase"]]

Main Functions

Simulation

  • sim_boin(): Run BOIN trial simulations with automatic decision table generation

    • Automatically generates BOIN boundaries and decision tables
    • Optional safety stopping rules (extrasafe, boundMTD)
    • Flexible stopping criteria (n_earlystop_rule)
    • Returns detailed trial-level results and summary statistics
  • sim_boin_multi(): Run simulations across multiple scenarios

    • Orchestrates sim_boin() for each scenario automatically
    • Aggregates results into a unified comparison table
    • Ideal for protocol development evaluating multiple dose-toxicity relationships

Design Setup

  • get_boin_boundary(): Calculate BOIN interval boundaries (lambda_e, lambda_d)
  • get_boin_decision(): Generate decision table for dose escalation/de-escalation
  • get_boin_stopping_boundaries(): Generate safety stopping boundaries

MTD Selection

  • isotonic_regression(): Apply isotonic regression to estimate dose-toxicity curve
  • select_mtd(): Select MTD with optional boundMTD constraint

Utilities

  • print.boin_summary(): Print formatted summary tables with flexible options
  • print.boin_multi_summary(): Print multi-scenario summary tables

Performance

simFastBOIN uses vectorized operations and efficient algorithms for superior performance:

Benchmark (5 doses, 20 cohorts, cohort_size=3, all safety features enabled):

Number of Trials simFastBOIN BOIN Package Speedup
1,000 0.02 sec 0.63 sec 31.5x
10,000 0.17 sec 6.74 sec 39.6x
100,000 2.0 sec 80.2 sec 40.1x

Results validated against the BOIN package using comprehensive test scenarios. All operating characteristics (MTD selection rates, sample sizes, toxicity counts) matched within <0.5%.

BOIN Package Compatibility

simFastBOIN produces results identical to the original BOIN package while offering significantly improved performance. This makes it ideal as a drop-in replacement for large-scale simulations where speed is critical.

Validation Against BOIN Package

Comprehensive validation was conducted comparing simFastBOIN with BOIN::get.oc() across multiple configurations:

Test Design:

  • Test Scenarios: 5 dose-toxicity scenarios (5 doses each)

    • scenario1: c(0.05, 0.10, 0.20, 0.30, 0.45) - MTD at dose 4
    • scenario2: c(0.30, 0.40, 0.50, 0.60, 0.70) - All doses ≥ target
    • scenario3: c(0.05, 0.10, 0.15, 0.20, 0.25) - All doses < target
    • scenario4: c(0.15, 0.30, 0.45, 0.60, 0.75) - MTD at dose 2
    • scenario5: c(0.01, 0.03, 0.08, 0.15, 0.30) - MTD at dose 5
  • Parameter Combinations: 8 configurations per scenario

    • extrasafe = TRUE/FALSE
    • boundMTD = TRUE/FALSE
    • titration = TRUE/FALSE
  • Total Configurations: 40 (5 scenarios × 8 parameter combinations)

  • Trials per Configuration: 10,000

Validation Results:

Metric Match Rate Maximum Difference
PCS (MTD Selection %) 100% (40/40) 1.29%
Avg Patients per Dose 100% (40/40) 0.29 patients
Avg DLTs per Dose 100% (40/40) 0.10 DLTs
No MTD Selection Rate 100% (40/40) 0.76%

Conclusion: All 40 configurations showed perfect metric match (all_match = TRUE) with simFastBOIN and BOIN package results. Maximum differences across all metrics were well within acceptable tolerance levels, confirming full compatibility.

Implementation Details

  • Results validated across all scenario types (favorable, unfavorable, balanced)
  • Testing included all major design options:
    • Safety stopping rules (extrasafe TRUE/FALSE)
    • MTD selection constraints (boundMTD TRUE/FALSE)
    • Titration phase options (titration TRUE/FALSE)
  • Same random number generation (when seed is fixed)
  • Full compatibility with BOIN methodology

Features

1. boundMTD: Conservative MTD Selection

The boundMTD option provides an additional safety constraint during MTD selection:

# Without boundMTD: may select doses near toxicity boundary
result1 <- sim_boin(
  n_trials = 1000,
  target = 0.30,
  p_true = c(0.10, 0.20, 0.28, 0.36, 0.50, 0.65),
  n_cohort = 20,
  cohort_size = 3,
  boundMTD = FALSE,
  seed = 123
)

# With boundMTD: more conservative selection
result2 <- sim_boin(
  n_trials = 1000,
  target = 0.30,
  p_true = c(0.10, 0.20, 0.28, 0.36, 0.50, 0.65),
  n_cohort = 20,
  cohort_size = 3,
  boundMTD = TRUE,
  seed = 123
)

Selected MTD must have isotonic-estimated toxicity rate below the de-escalation boundary (lambda_d), preventing selection of doses too close to overly toxic doses.

2. n_earlystop_rule: Stopping Criteria

Two stopping rules are available:

"simple" (Backward Compatible)

  • Stop when sample size at current dose reaches n_earlystop
  • Faster trials, fewer patients

"with_stay" (BOIN Standard)

  • Stop when sample size reaches n_earlystop AND next decision is "Stay"
  • Ensures algorithm convergence before stopping
  • More thorough dose evaluation
# Simple rule: Stop immediately at n_earlystop
result_simple <- sim_boin(
  n_trials = 1000,
  target = 0.30,
  p_true = c(0.05, 0.10, 0.20, 0.30, 0.45, 0.60),
  n_cohort = 20,
  cohort_size = 3,
  n_earlystop_rule = "simple",
  seed = 123
)

# With stay: Wait for convergence
result_with_stay <- sim_boin(
  n_trials = 1000,
  target = 0.30,
  p_true = c(0.05, 0.10, 0.20, 0.30, 0.45, 0.60),
  n_cohort = 20,
  cohort_size = 3,
  n_earlystop_rule = "with_stay",
  seed = 123
)

3. extrasafe: Safety Stopping at Lowest Dose

Additional safety rule to stop the entire trial if the lowest dose is overly toxic:

result <- sim_boin(
  n_trials = 10000,
  target = 0.30,
  p_true = seq(0.05, 0.45, by = 0.05),
  n_cohort = 48,
  cohort_size = 3,
  extrasafe = TRUE,   # Enable safety stopping
  offset = 0.05,      # Cutoff = cutoff_eli - offset
  seed = 123
)

4. Output Formatting

Multiple output format options for different use cases:

# Plain text (default)
print(result$summary)

# With percentages
print(result$summary, percent = TRUE)

# Markdown pipe format (for RMarkdown)
print(result$summary, kable = TRUE, kable_format = "pipe")

# LaTeX format (for publications)
print(result$summary, kable = TRUE, kable_format = "latex")

# HTML format (for web display)
print(result$summary, kable = TRUE, kable_format = "html")

# Simple format (minimal formatting)
print(result$summary, kable = TRUE, kable_format = "simple")

# Combine options
print(result$summary, scenario_name = "My Analysis", percent = TRUE, kable = TRUE)

BOIN Standard Implementation

Recommended settings for BOIN standard compliance:

result <- sim_boin(
  n_trials = 10000,
  target = 0.30,
  p_true = c(0.10, 0.25, 0.40, 0.55, 0.70),
  n_cohort = 10,
  cohort_size = 3,
  boundMTD = TRUE,              # Conservative MTD selection
  n_earlystop_rule = "with_stay",  # Stop when converged
  extrasafe = TRUE,             # Safety monitoring
  seed = 123
)

print(result$summary, scenario_name = "BOIN Standard")

Complete Workflow Example

library(simFastBOIN)

# Step 1: Define scenario
target <- 0.30
p_true <- c(0.05, 0.10, 0.15, 0.20, 0.25, 0.30, 0.35, 0.40, 0.45)

# Step 2: Run simulation
result <- sim_boin(
  n_trials = 10000,
  target = target,
  p_true = p_true,
  n_cohort = 48,
  cohort_size = 3,
  boundMTD = TRUE,
  n_earlystop_rule = "with_stay",
  extrasafe = TRUE,
  return_details = TRUE,  # Enable detailed trial-level results
  seed = 123
)

# Step 3: Display results
print(result$summary, scenario_name = "Primary Analysis")

# Step 4: Export for RMarkdown
print(result$summary, kable = TRUE, kable_format = "pipe")

# Step 5: Check stopping reasons
table(sapply(result$detailed_results, function(x) x$reason))

Stopping Reasons

The package tracks why each trial terminated:

  • "trial_completed": Normal completion
  • "n_earlystop_reached": Reached sample size limit (simple rule)
  • "n_earlystop_with_stay": Converged at sample size limit (with_stay rule)
  • "lowest_dose_too_toxic": Safety stopping at lowest dose (extrasafe)
  • "lowest_dose_eliminated": Lowest dose eliminated during trial
  • "no_dose_below_lambda_d": No dose satisfies boundMTD constraint
  • "max_cohorts_reached": Maximum number of cohorts completed

References

Liu, S. and Yuan, Y. (2015). Bayesian Optimal Interval Designs for Phase I Clinical Trials. Journal of the Royal Statistical Society: Series C, 64, 507–523.

Version History

See NEWS.md for detailed version history and changelog.

License

MIT © Gosuke Homma