The hardware and bandwidth for this mirror is donated by METANET, the Webhosting and Full Service-Cloud Provider.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]metanet.ch.

Introduction to simFastBOIN

Gosuke Homma

2025-12-11

Overview

simFastBOIN provides fast and efficient simulation tools for Bayesian Optimal Interval (BOIN) designs in Phase I clinical trials. The package enables researchers to evaluate operating characteristics and design performance across different dose-toxicity scenarios.

Key Features

Installation

# Install from GitHub
devtools::install_github("gosukehommaEX/simFastBOIN")

Basic Usage

library(simFastBOIN)

Running a Basic BOIN Simulation

The most basic simulation requires only a few parameters:

# Define design parameters
target <- 0.30  # Target DLT rate (30%)
p_true <- c(0.10, 0.25, 0.40, 0.55, 0.70)  # True toxicity probabilities

# Run simulation (progress messages suppressed)
result <- sim_boin(
  n_trials = 1000,
  target = target,
  p_true = p_true,
  n_cohort = 10,
  cohort_size = 3,
  seed = 123
)

# Display results
print(result$summary)
#> |         Metric|       DL1|       DL2|       DL3|       DL4|       DL5|Total/No MTD|
#> ---------------------------------------------------------------------------------- 
#> |   True Tox (%)|      10.0|      25.0|      40.0|      55.0|      70.0|          |
#> |    MTD Sel (%)|      10.8|      52.4|      33.8|       2.8|       0.1|       0.1|
#> |        Avg Pts|       6.8|      11.9|       7.7|       1.8|       0.1|      28.4|
#> |       Avg DLTs|       0.7|       3.0|       3.1|       1.0|       0.1|       7.9|
#> ----------------------------------------------------------------------------------

Understanding the Output

The summary table contains four key sections:

  1. True Toxicity (%): The actual DLT rate at each dose
  2. MTD Selected (%): Percentage of trials selecting each dose as MTD
  3. Participants Treated (mean): Average patient enrollment at each dose
  4. Participants w/ DLTs (mean): Average DLT counts at each dose

BOIN Standard Implementation

For BOIN standard compliance, use the following recommended settings:

result_standard <- sim_boin(
  n_trials = 1000,
  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
  seed = 123
)

print(result_standard$summary, scenario_name = "BOIN Standard")
#> Scenario: BOIN Standard
#> 
#> |         Metric|       DL1|       DL2|       DL3|       DL4|       DL5|Total/No MTD|
#> ---------------------------------------------------------------------------------- 
#> |   True Tox (%)|      10.0|      25.0|      40.0|      55.0|      70.0|          |
#> |    MTD Sel (%)|      17.0|      55.8|      25.8|       1.2|       0.1|       0.1|
#> |        Avg Pts|       6.8|      11.9|       7.7|       1.8|       0.1|      28.4|
#> |       Avg DLTs|       0.7|       3.0|       3.1|       1.0|       0.1|       7.9|
#> ----------------------------------------------------------------------------------

Key Parameters

Safety Features

Extra Safety Stopping

For scenarios with high toxicity uncertainty:

result_safe <- sim_boin(
  n_trials = 1000,
  target = 0.30,
  p_true = c(0.05, 0.10, 0.20, 0.30, 0.45),
  n_cohort = 10,
  cohort_size = 3,
  extrasafe = TRUE,  # Safety monitoring at lowest dose
  offset = 0.05,     # Safety cutoff adjustment
  seed = 123
)

print(result_safe$summary, scenario_name = "With Extra Safety")
#> Scenario: With Extra Safety
#> 
#> |         Metric|       DL1|       DL2|       DL3|       DL4|       DL5|Total/No MTD|
#> ---------------------------------------------------------------------------------- 
#> |   True Tox (%)|       5.0|      10.0|      20.0|      30.0|      45.0|          |
#> |    MTD Sel (%)|       0.3|       5.1|      26.7|      48.4|      18.8|       0.7|
#> |        Avg Pts|       3.7|       5.4|       8.1|       8.2|       4.0|      29.5|
#> |       Avg DLTs|       0.2|       0.5|       1.6|       2.4|       1.8|       6.6|
#> ----------------------------------------------------------------------------------

Maximum Conservatism

Combining all safety features:

result_conservative <- sim_boin(
  n_trials = 1000,
  target = 0.30,
  p_true = seq(0.05, 0.45, by = 0.05),
  n_cohort = 20,
  cohort_size = 3,
  extrasafe = TRUE,
  boundMTD = TRUE,
  n_earlystop_rule = "with_stay",
  seed = 123
)

print(result_conservative$summary, scenario_name = "Maximum Conservatism")
#> Scenario: Maximum Conservatism
#> 
#> |         Metric|       DL1|       DL2|       DL3|       DL4|       DL5|       DL6|       DL7|       DL8|       DL9|Total/No MTD|
#> ------------------------------------------------------------------------------------------------------------------------------ 
#> |   True Tox (%)|       5.0|      10.0|      15.0|      20.0|      25.0|      30.0|      35.0|      40.0|      45.0|          |
#> |    MTD Sel (%)|       0.3|       2.0|       7.0|      22.0|      25.5|      23.1|      13.0|       5.5|       0.9|       0.7|
#> |        Avg Pts|       3.7|       4.8|       6.2|       8.6|       8.8|       7.1|       4.3|       1.8|       0.4|      45.8|
#> |       Avg DLTs|       0.2|       0.5|       0.9|       1.7|       2.2|       2.1|       1.5|       0.7|       0.2|      10.1|
#> ------------------------------------------------------------------------------------------------------------------------------

Multi-Scenario Simulations

Evaluate multiple dose-toxicity scenarios simultaneously:

# Define multiple scenarios
scenarios <- list(
  list(name = "Scenario 1: MTD at DL3", 
       p_true = c(0.05, 0.10, 0.20, 0.30, 0.45)),
  list(name = "Scenario 2: MTD at DL4", 
       p_true = c(0.10, 0.15, 0.25, 0.30, 0.45)),
  list(name = "Scenario 3: All doses safe", 
       p_true = c(0.05, 0.10, 0.15, 0.20, 0.25))
)

# Run multi-scenario simulation
result_multi <- sim_boin_multi(
  scenarios = scenarios,
  target = 0.30,
  n_trials = 1000,
  n_cohort = 10,
  cohort_size = 3,
  seed = 123
)
# Display aggregated results
print(result_multi)
#>                    Scenario         Item DL1  DL2  DL3  DL4  DL5 Total/No MTD
#>      Scenario 1: MTD at DL3 True Tox (%)   5   10   20   30   45             
#>                              MTD Sel (%) 0.2    5 27.9 48.4 18.4          0.1
#>                                  Avg Pts 3.9  5.5  8.2  8.1    4         29.7
#>                                 Avg DLTs 0.2  0.5  1.6  2.4  1.8          6.6
#>      Scenario 2: MTD at DL4 True Tox (%)  10   15   25   30   45             
#>                              MTD Sel (%)   2 12.6 32.6 37.4 15.2          0.2
#>                                  Avg Pts 4.8  6.9  8.5    6  3.2         29.3
#>                                 Avg DLTs 0.5    1  2.1  1.8  1.4          6.8
#>  Scenario 3: All doses safe True Tox (%)   5   10   15   20   25             
#>                              MTD Sel (%) 0.8  2.3 12.2 22.6 62.1            0
#>                                  Avg Pts 3.7  4.9  6.2  6.3  8.7         29.8
#>                                 Avg DLTs 0.2  0.5  0.9  1.3  2.2          5.1

Output Formatting Options

Percentage Format

Display values as percentages instead of absolute numbers:

print(result$summary, percent = TRUE)
#> |         Metric|       DL1|       DL2|       DL3|       DL4|       DL5|Total/No MTD|
#> ---------------------------------------------------------------------------------- 
#> |   True Tox (%)|      10.0|      25.0|      40.0|      55.0|      70.0|          |
#> |    MTD Sel (%)|      10.8|      52.4|      33.8|       2.8|       0.1|       0.1|
#> |    Avg Pts (%)|      24.0|      41.9|      27.2|       6.5|       0.5|      28.4|
#> |   Avg DLTs (%)|       8.6|      38.1|      39.0|      13.2|       1.1|       7.9|
#> ----------------------------------------------------------------------------------

Markdown Table Format

For R Markdown documents:

print(result$summary, kable = TRUE, kable_format = "pipe")
#> 
#> 
#> |Item         |DL1  |DL2  |DL3  |DL4 |DL5 |Total/No MTD |
#> |:------------|:----|:----|:----|:---|:---|:------------|
#> |True Tox (%) |10   |25   |40   |55  |70  |             |
#> |MTD Sel (%)  |10.8 |52.4 |33.8 |2.8 |0.1 |0.1          |
#> |Avg Pts      |6.8  |11.9 |7.7  |1.8 |0.1 |28.4         |
#> |Avg DLTs     |0.7  |3    |3.1  |1   |0.1 |7.9          |

HTML Format

For web-based reports:

print(result$summary, kable = TRUE, kable_format = "html")

Accessing Detailed Results

When return_details = TRUE, you can access trial-level information:

result_detailed <- sim_boin(
  n_trials = 100,
  target = 0.30,
  p_true = c(0.10, 0.25, 0.40, 0.55, 0.70),
  n_cohort = 10,
  cohort_size = 3,
  return_details = TRUE,
  seed = 123
)

# Check first trial
trial_1 <- result_detailed$detailed_results[[1]]
cat("Trial 1 MTD:", trial_1$mtd, "\n")
#> Trial 1 MTD: 2
cat("Trial 1 stopping reason:", trial_1$reason, "\n")
#> Trial 1 stopping reason: trial_completed

# Summary of stopping reasons
stopping_reasons <- table(sapply(result_detailed$detailed_results, 
                                function(x) x$reason))
print(stopping_reasons)
#> 
#> trial_completed 
#>             100

Design Comparison

Compare different safety configurations:

# Baseline
result_baseline <- 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,
  seed = 123
)

# With boundMTD
result_boundMTD <- 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,
  boundMTD = TRUE,
  seed = 123
)

# Create comparison
comparison <- data.frame(
  Setting = c("Baseline", "boundMTD"),
  Avg_Patients = c(
    result_baseline$summary$avg_total_n_pts,
    result_boundMTD$summary$avg_total_n_pts
  ),
  MTD_Selection_at_DL4 = c(
    result_baseline$summary$mtd_selection_percent[4],
    result_boundMTD$summary$mtd_selection_percent[4]
  )
)

print(comparison)
#>    Setting Avg_Patients MTD_Selection_at_DL4
#> 1 Baseline       40.842                 52.5
#> 2 boundMTD       40.842                 52.3

Performance Benchmarking

simFastBOIN is optimized for speed:

# Benchmark with 10,000 trials
system.time({
  result_large <- sim_boin(
    n_trials = 10000,
    target = 0.30,
    p_true = seq(0.05, 0.45, by = 0.05),
    n_cohort = 48,
    cohort_size = 3,
    seed = 123
  )
})

Typical performance: - 1,000 trials: ~0.02 seconds - 10,000 trials: ~0.25 seconds - 100,000 trials: ~2.7 seconds

Advanced Features

Custom Cohort Sizes

Use variable cohort sizes:

result_variable <- sim_boin(
  n_trials = 1000,
  target = 0.30,
  p_true = c(0.10, 0.25, 0.40, 0.55, 0.70),
  n_cohort = 10,
  cohort_size = c(1, 3, 3, 3, 3, 3, 3, 3, 3, 3),  # First cohort: 1 patient
  seed = 123
)

Titration Phase

Enable accelerated dose escalation:

result_titration <- sim_boin(
  n_trials = 1000,
  target = 0.30,
  p_true = c(0.05, 0.10, 0.20, 0.30, 0.45),
  n_cohort = 20,
  cohort_size = 3,
  titration = TRUE,  # Enable titration phase
  seed = 123
)

Stopping Reasons

The package tracks why each trial terminated:

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.

See Also

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.