--- title: "Late-onset toxicity with the TITE-BOIN design" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Late-onset toxicity with the TITE-BOIN design} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r setup, include = FALSE} knitr::opts_chunk$set(collapse = TRUE, comment = "#>") library(simFastBOIN) ``` ## Why a time-to-event design The BOIN design needs every patient's outcome before the next cohort is dosed. When toxicity can appear late in a long assessment window, or patients arrive faster than they can be assessed, that means repeatedly suspending accrual. The time-to-event BOIN (TITE-BOIN) design treats new patients while earlier ones are still being followed, and uses the follow-up time of these pending patients. Two ways of doing so are available through `method`: the single mean imputation of Yuan et al. (2018), the default, and the effective sample size of Lin and Yuan (2020). ## The decision table The decision table now depends on three counts, the patients treated, the DLTs observed and the patients pending, and in some states on the standardized total follow-up time (STFT) of the pending patients, their total follow-up divided by the length of the window. The table for a target of 0.2 is Table 1 of Yuan et al. (2018), which the package reproduces entry by entry. ```{r} tite <- tite_boin_decision_table(target = 0.2, max_n = 15) print(tite, cohort_size = 3) ``` The table is a data frame, so a single state can be looked up. With nine patients, one DLT and four pending, the dose is escalated once STFT reaches 2.15. In the trial example of Yuan et al. (2018) the four pending patients had been followed for 75, 60, 45 and 30 days of a 90 day window, an STFT of 2.33, and the dose was escalated. ```{r} tite[tite$n == 9 & tite$n_tox == 1 & tite$n_pending == 4, ] ``` The same table as a figure, here for nine patients. Each cell is a pair of pending patients and DLTs; a cell whose decision depends on the follow-up shows the boundaries, the one after `>=` for escalation and the one after `<=` for de-escalation. ```{r tite-plot, fig.width = 7, fig.height = 6, eval = requireNamespace("ggplot2", quietly = TRUE)} plot(tite, n = 9) ``` Under the effective sample size the boundaries refer to ESS, the number of patients who have completed the assessment plus STFT, and escalation waits until two patients at the dose have completed it. ```{r} print(tite_boin_decision_table(target = 0.3, max_n = 9, method = "ess"), cohort_size = 3) ``` ## Operating characteristics `sim_tite_boin()` simulates the design with patients arriving over time. It needs the length of the assessment window and the accrual rate, in the same unit of time, and reports the trial duration and the suspensions of accrual in addition to the summaries of `sim_boin()`. ```{r} oc_tite <- sim_tite_boin( target = 0.30, p_true = c(0.05, 0.15, 0.30, 0.45, 0.60), n_cohort = 10, cohort_size = 3, window = 3, accrual_rate = 2, n_trials = 2000, seed = 123 ) oc_tite ``` Faster accrual shortens the trial, at the price of more frequent suspensions. ```{r} by_rate <- sapply(c(0.5, 1, 2, 4), function(rate) { oc <- sim_tite_boin(target = 0.30, p_true = c(0.05, 0.15, 0.30, 0.45, 0.60), n_cohort = 10, cohort_size = 3, window = 3, accrual_rate = rate, n_trials = 1000, seed = 1) c(accrual_rate = rate, selected_dose_3 = oc$sel_percent[["DL3"]], duration = oc$duration_mean, suspensions = oc$avg_n_suspensions) }) round(t(by_rate), 2) ``` ## Agreement with the BOIN design When no patient is ever pending at a decision, the time-to-event design is the BOIN design, and the simulation engine reproduces `sim_boin()` exactly. With arrivals one unit of time apart and a window of half a unit, every patient has completed the assessment before the next one arrives. ```{r} no_pending <- sim_tite_boin(target = 0.30, p_true = c(0.05, 0.15, 0.30, 0.45, 0.60), n_cohort = 10, cohort_size = 3, window = 0.5, accrual_rate = 1, accrual = "fixed", n_trials = 1000, seed = 7) plain_boin <- sim_boin(target = 0.30, p_true = c(0.05, 0.15, 0.30, 0.45, 0.60), n_cohort = 10, cohort_size = 3, n_trials = 1000, seed = 7) identical(no_pending$sel_percent, plain_boin$sel_percent) identical(no_pending$n_pts_dose, plain_boin$n_pts_dose) ``` ## 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. Yuan, Y., Lin, R., Li, D., Nie, L. and Warren, K. E. (2018). Time-to-Event Bayesian Optimal Interval Design to Accelerate Phase I Trials. *Clinical Cancer Research*, 24(20), 4921-4930. Lin, R. and Yuan, Y. (2020). Time-to-Event Model-Assisted Designs for Dose-Finding Trials with Delayed Toxicity. *Biostatistics*, 21(4), 807-824.