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.
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|
#> ----------------------------------------------------------------------------------The summary table contains four key sections:
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|
#> ----------------------------------------------------------------------------------boundMTD = TRUE: Ensures selected
MTD’s isotonic estimate is below the de-escalation boundaryn_earlystop_rule = "with_stay": Stops
trial when dose stays at n_earlystop thresholdFor 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|
#> ----------------------------------------------------------------------------------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|
#> ------------------------------------------------------------------------------------------------------------------------------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.1Display 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|
#> ----------------------------------------------------------------------------------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 |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
#> 100Compare 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.3simFastBOIN 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
Use variable cohort sizes:
The package tracks why each trial terminated:
"max_cohorts_reached": Normal completion"n_earlystop_with_stay": Converged at sample size
limit"n_earlystop_simple": Reached sample size limit (simple
rule)"lowest_dose_too_toxic": Safety stopping at lowest
dose"lowest_dose_eliminated": Lowest dose eliminated during
trial"max_sample_size_reached": Maximum total patients
reachedLiu, 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.
?sim_boin - Main simulation function?sim_boin_multi - Multi-scenario simulation?get_boin_boundary - BOIN boundary calculation?get_boin_decision - Decision table generation