Evaluate data from oncology dose finding using a joint BLRM
scenario_jointBLRM.Rd
Evaluates data scenarios consisting of observations of one or more monotherapy or two-drug combination therapy dose-finding trials and computes posterior toxicities for a trial of interest and a set of doses of interest.
For an introduction to the use of this function, see the introduction vignette:
vignette("intro_jointBLRM", package = "decider")
.
If multiple scenarios need to be evaluated, consider using the function
scenario_list_jointBLRM()
instead, which is a parallelized wrapper that processes a list of data scenarios
within the same setting via scenario_jointBLRM()
.
A description of the underlying model and methods are given in the section Details.
Usage
scenario_jointBLRM(
data=NULL,
historical.data=NULL,
doses.of.interest,
dose.ref1,
dose.ref2,
trials.of.interest,
types.of.interest=NULL,
esc.rule=c("ewoc", "loss", "dynamic.loss"),
dosing.intervals = c(0.16, 0.33, 0.6),
ewoc.threshold = 0.25,
loss.weights = c(1, 0, 1, 2),
dynamic.weights = rbind(c(0.32, 0, 0.32, 0.36),
c(0.29, 0, 0.31, 0.4),
c(0.27, 0, 0.33, 0.4),
c(0.2, 0, 0.3, 0.5)
),
prior.mu = list(mu_a1 = c(logit(0.33), 2),
mu_b1 = c(0, 1),
mu_a2 = c(logit(0.33), 2),
mu_b2 = c(0, 1),
mu_eta = c(0, 1.121)
),
prior.tau = list(tau_a1 = c(log(0.25), log(2)/1.96),
tau_b1 = c(log(0.125), log(2)/1.96),
tau_a2 = c(log(0.25), log(2)/1.96),
tau_b2 = c(log(0.125), log(2)/1.96),
tau_eta = c(log(0.125), log(2)/1.96)
),
saturating = FALSE,
probs = c(0.025, 0.5, 0.975),
iter = 26000,
warmup = 1000,
refresh = 0,
adapt_delta = 0.8,
max_treedepth = 15,
chains = 4,
digits = 5,
seed=sample.int(.Machine$integer.max, 1),
path = NULL,
file.name = NULL,
plot.decisions = FALSE,
plot.combi.heatmap = TRUE,
plot.int.probs.loss = FALSE,
plot.return = FALSE,
plot.file.format = "pdf",
plot.width,
plot.height,
plot.unit,
output.scen.config = FALSE
)
Arguments
- data
List that contains the data scenario to be evaluated. Can be
NULL
if the prior shall be computed. The data list should have the following named entries, all of which need to be vectors of the same length (length should be the number of cohorts in the data):data$dose1
Numeric vector, each entry must be non-negative. Entry \(i\) should provide the dose level of compound 1 administered to cohort \(i\) in the data. Use0
orNA
to state that compound 1 was not used during treatment of a cohort. Note: For each cohort, eitherdata$dose1
ordata$dose2
must be positive.data$dose2
Numeric vector, each entry must be non-negative. Entry \(i\) should provide the dose level of compound 2 administered to cohort \(i\) in the data. Use0
orNA
to state that compound 2 was not used during treatment of a cohort. Note: For each cohort, eitherdata$dose1
ordata$dose2
must be positive.data$n.pat
Numeric vector, each entry must be a non-negative integer. Entry \(i\) should provide the number of patients in cohort \(i\) in the data.0
is interpreted as the cohort not having been treated yet. Ifdata
contains solely cohorts with 0 patients, the function will sample from the prior.data$n.dlt
Numeric vector, each entry must be a non-negative integer. Entry \(i\) should provide the number of DLTs in cohort \(i\) in the data. In particular, the values need to be smaller or equal to the patient number of the corresponding cohort.data$trial
Numeric or character vector. The entries should be trial names, i.e. indicators for the trial to which the cohort belongs. These can either be numbers or strings (both will be converted to numbers internally). Note: As mixed vectors of numbers and strings will be converted to strings, entries such as1
and"1"
will be interpreted as the same trial.
- historical.data
Optional named list, must have the same structure as
data
. It is equivalent to include observations asdata
orhistorical.data
, the latter is included solely for convenience. Trial names across data and historical data must be consistent, in the sense that observations with the same entries indata$trial
, respectivelyhistorical.data$trial
are interpreted to belong to the same trial.Note that the argument is only included for convenience, as it allows to perform multiple inferences using the same set of historical data with changing new data, without having to include the non-changing (historical) observations in the data argument.
- doses.of.interest
Numeric matrix with two rows and non-negative entries. Each column gives a dose combination of interest, where the first row provides the dose level of compound 1, the second row of compound 2.
NA
entries will be interpreted as "dose was not administered", i.e. are internally converted to0
. Setting both doses to zero in one column is not a valid dose combination and will throw an error.- dose.ref1
Numeric, must be positive. Reference dose for compound 1.
- dose.ref2
Numeric, must be positive. Reference dose for compound 2.
- trials.of.interest
Optional vector of numerical or character trial numbers/names, for which the posterior is to be computed. If missing, all trials included in the
data
argument are used instead, or, if there are no trials in thedata
andhistorical.data
, the priors for the doses of interest are computed. Trial names should be consistent with the numbers given in thedata
argument. If trial names are included that do not have observations in thedata
argument, the predictive DLT probabilities (based on a MAP approach) will be computed instead for these trials (i.e., the posterior for these trials will only depend on the data observed in other trials).- types.of.interest
Optional character vector with one entry for each entry of
trials.of.interest
which specifies the trial type of the corresponding trial of interest. Supported trial types are"mono1"
,"mono2"
,"combi"
, and"all"
. Iftypes.of.interest
is not provided, the trial types are inferred from the data given for the trial. If the type is neither specified by the user nor uniquely inferable from the data (e.g. trials which are not included in the data yet, or trials including observations from multiple types), the trial type is implicitly set to"all"
.The available trial types specify which of the dose levels from
doses.of.interest
are included in the summary for the corresponding trial of interest. More specifically, if the type of a trial of interest is......
"mono1"
: Only doses of interest for which the second compound is0
are included in the summary and (if activated) plots....
"mono2"
: Only doses of interest for which the fist compound is0
are included in the summary and (if activated) plots....
"combi"
: Only doses of interest for which none of the compound is0
are included in the summary and (if activated) plots....
"all"
: All doses of interest are included in the summary. If plots are activated, a plot is generated for each trial type detected within the doses of interest.
If the type is
"all"
and the escalation rule is"dynamic.loss"
, the dynamic Bayes risk (expected loss) is computed based on the reference dose of the trial type corresponding to the type of trial of interest. That is, if e.g. mono 1 and combination doses are included in the doses of interest and the type is"all"
, the dynamic Bayes risk will select for each dose whether it needs to use mono reference doses or the reference dose combination.- esc.rule
Optional character. Can be either
"ewoc"
,"loss"
,"dynamic"
or"dynamic.loss"
, where the latter two are treated synonymously. Note: If"loss"
or"dynamic.loss"
are chosen, the parameterdosing.intervals
needs to contain three entries, otherwise it can either have two or three entries. Ifesc.rule
is"ewoc"
, at most the first two entries ofdosing.intervals
are used. See the section Details for a description of the available methods.- dosing.intervals
Optional numeric with 1, 2, or 3 ascending positive entries. Must have three entries when the
esc.rule
is set to"loss"
,"dynamic.loss"
, or"dynamic"
, otherwise (i.e. whenesc.rule
is"ewoc"
) lengths 1, 2, or 3 are permitted.
If dosing interval has only one entry (requires thatesc.rule
is"ewoc"
), the entry is interpreted as the boundary between DLT rates considered as target dosing and overdosing, i.e., no underdosing interval is considered in this case. Otherwise (including the default), entries 1 and 2 are interpreted as lower and upper boundary of the target dosing interval. A third entry is ignored whenesc.rule
is"ewoc"
, and for other values ofesc.rule
required as boundary between the dosing intervals containing the excessive and unacceptable DLT rates. The argumentdosing.intervals
defaults toc(0.16, 0.33, 0.6)
, which corresponds to using \([0.16, 0.33)\) as target interval, and \([0.33,0.6)\) as excessive toxicity interval for loss escalation. Ifdosing.intervals
has only one entry, sayx
, the computation is equivalent to setting the argument toc(0, x)
, but the output tables and plots will be formatted slightly differently to reflect that the underdosing interval is not considered in this case.- ewoc.threshold
Optional numeric between 0 and 1. Overdosing thresholds for EWOC plots. Defaults to 0.25.
- loss.weights
Optional numerical vector with four entries (which can be arbitrary numbers), the default is
c(1,0,1,2)
. Specifies the interval weights/penalties that are used for static loss escalation. This is only needed whenesc.rule
is"loss"
, and the parameter is ignored otherwise. More precisely,loss.weights[1]
is the weight of the underdosing interval,loss.weights[2]
the weight of the target dosing interval,loss.weights[3]
the weight of the excessively toxic dosing interval, andloss.weights[4]
is the weight of the unacceptably toxic dosing interval. See the Details section below for explanations regarding the methodology.- dynamic.weights
Optional numerical matrix with four rows and four columns, and arbitrary numbers as entries. Specifies the interval weights/penalties that are used for dynamic loss escalation. This is only needed when
esc.rule
is"dynamic"
or"dynamic.loss"
, and the parameter is ignored otherwise. Each row ofdynamic.weights
specifies one of the static loss weight vectors that are interpolated during dynamic loss escalation. See the Details section below for explanations regarding the methodology.More precisely,
dynamic.weights[1, ]
is the static weight vector that is weighted by the reference probability of underdosing,dynamic.weights[2, ]
is the static weight vector that is weighted by the reference probability of target dosing,dynamic.weights[3, ]
is the static weight vector that is weighted by the reference probability of excessively toxic dosing, anddynamic.weights[4, ]
is the static weight vector that is weighted by the reference probability of unacceptably toxic dosing. The default value fordynamic.weights
is a matrix with the following four rows (in order):c(0.32, 0, 0.32, 0.36)
,c(0.29, 0, 0.31, 0.40)
,c(0.27, 0, 0.33, 0.40)
,c(0.20, 0, 0.30, 0.50)
.
- prior.mu
Optional list that gives the prior distribution for the hyper means \(\mu\). The list must have named entries, which all need to be numeric vectors of length 2:
prior.mu$mu_a1
Numeric with length two, defaults toc(logit(0.33), 2)
. Specifies mean and SD of the hypermean \(\mu_{\alpha_1}\) of the parameter \(log(\alpha_1)\) in the BLRM. The second entry must therefore be positive. See the Details section below for more detail.prior.mu$mu_b1
Numeric with length two, defaults toc(0, 1)
. Specifies mean and SD of the hypermean \(\mu_{\beta_1}\) of the parameter \(log(\beta_1)\) in the BLRM. The second entry must therefore be positive. See the Details section below for more detail.prior.mu$mu_a2
Numeric with length two, defaults toc(logit(0.33), 2)
. Specifies mean and SD of the hypermean \(\mu_{\alpha_2}\) of the parameter \(log(\alpha_2)\) in the BLRM. The second entry must therefore be positive. See the Details section below for more detail.prior.mu$mu_b2
Numeric with length two, defaults toc(0, 1)
. Specifies mean and SD of the hypermean \(\mu_{\beta_2}\) of the parameter \(log(\beta_2)\) in the BLRM. The second entry must therefore be positive. See the Details section below for more detail.prior.mu$mu_eta
Numeric with length two, defaults toc(0, 1.121)
. Specifies mean and SD of the hypermean \(\mu_{\eta}\) of the parameter \(\eta\) in the BLRM. The second entry must therefore be positive. See the Details section below for more detail.
- prior.tau
Optional list that gives the prior distribution for the between-trial heterogeneities (hyper SD) \(\tau\). The list must have named entries, which all need to be numeric vectors of length 2:
prior.tau$tau_a1
Numeric with length two, defaults toc(log(0.25), log(2)/1.96)
. Specifies mean and SD on log-scale of the heterogeneity \(\tau_{\alpha_1}\) of the parameter \(log(\alpha_1)\) in the BLRM. The second entry must therefore be positive. See the Details section below for more detail.prior.tau$tau_b1
Numeric with length two, defaults toc(log(0.125), log(2)/1.96)
. Specifies mean and SD on log-scale of the heterogeneity \(\tau_{\beta_1}\) of the parameter \(log(\beta_1)\) in the BLRM. The second entry must therefore be positive. See the Details section below for more detail.prior.tau$tau_a2
Numeric with length two, defaults toc(log(0.25), log(2)/1.96)
. Specifies mean and SD on log-scale of the heterogeneity \(\tau_{\alpha_2}\) of the parameter \(log(\alpha_2)\) in the BLRM. The second entry must therefore be positive. See the Details section below for more detail.prior.tau$tau_b2
Numeric with length two, defaults toc(log(0.125), log(2)/1.96)
. Specifies mean and SD on log-scale of the heterogeneity \(\tau_{\beta_2}\) of the parameter \(log(\beta_2)\) in the BLRM. The second entry must therefore be positive. See the Details section below for more detail.prior.tau$tau_eta
Numeric with length two, defaults toc(log(0.125), log(2)/1.96)
. Specifies mean and SD on log-scale of the heterogeneity \(\tau_{\eta}\) of the parameter \(\eta\) in the BLRM. The second entry must therefore be positive. See the Details section below for more detail.
- saturating
Optional logical, defaults to
FALSE
. IfTRUE
, the BLRM will be using a saturating interaction term as described inOncoBayes2::blrm_formula_saturating()
. Also refer to the Details section below.- probs
Optional numeric with arbitrary entries between 0 and 1. Provides the levels for the quantiles displayed in the output. Defaults to
c(0.025, 0.5, 0.975)
.- iter
Optional integer, number of total MCMC iterations per chain. Defaults to 26000. Note: Number of warmup iterations is counted towards
iter
, i.e. of theiter
many iterations, the firstwarmup
many samples are not saved.- warmup
Optional integer, number of warmup iterations discarded from total MCMC iterations per chain. Defaults to
1000
. Note: Number of warmup iterations is counted towardsiter
, i.e. of theiter
many iterations, the firstwarmup
many samples are not saved. Refer torstan::sampling()
from therstan-package
package for details.- refresh
Optional integer. Given to Stan's
refresh
argument forrstan::sampling()
, defaults to0
. A positive value indicates that updates on sampling progress are printed everyrefresh
many iterations. Set this to 0 to avoid output from Stan. Refer torstan::sampling()
from therstan-package
package for details.- adapt_delta
Optional numeric between 0.6 and 1, default is 0.8. Given to Stan's
rstan::sampling()
method in thecontrol
argument of Stan. Translates to target Metropolis acceptance probability during Hamiltonian Monte Carlo, respectively NUTS. Can be used to influence thestepsize
Stan uses for leapfrog steps during the NUTS algorithm. Seerstan::sampling()
,rstan-package
for details. Note: One can increase the value of this parameter in order to reduce the number of Stan warnings on "divergent transition". Larger values than 0.95 will slow down sampling. The function will not permit to setadapt_delta
to values below 0.6 (therstan-package
default).- max_treedepth
Optional integer, defaults to 15. Should not be lower than 10. This is a parameter of the NUTS algorithm. Roughly speaking, NUTS constructs a search tree when generating a new proposal, until a stopping criterion (the NUTS criterion) is satisfied or, alternatively, until the maximum depth of the search tree is reached (to avoid endless looping). The argument
max_treedepth
allows to control the latter. The maximum treedepth will also automatically constrain the maximum number of leapfrog steps, and should therefore not be below 10. See alsorstan::sampling()
for details onmax_treedepth
. Note: The maximum treedepth should usually not be reached during sampling, otherwise Stan will print a warning. In this case, it is recommended to increase its value.- chains
Optional integer. Number of Markov chains constructed by Stan. Defaults to 4.
- digits
Optional positive integer that specified the number of digits used in the outputs. Defaults to 5.
- seed
Optional positive integer that specifies the seed to be used for the simulation. The default is
sample.int(.Machine$integer.max, 1)
. Note that reproducibility can only be obtained when the function is executed on exactly the same computing architecture, using identical software versions (e.g. of the compiler, Stan, and R), and the same input specifications. This is due to the internal use ofrstan-package
for MCMC sampling, which is only reproducible under these restrictions (refer to the Stan reference manual fromrstan-package
's homepage for more detail).- path
Optional character that specified the path to save the resulting output files. If
NULL
(the default), no output is written (but still returned to R). Otherwise, it is checked whetherpath
specifies a directory, and, if yes, all output is saved there.- file.name
Optional name for the output file. If
NULL
or missing, no output is saved (and also if no valid path is given). Results are only returned to R in this case. Note that plots will not be returned to R unless the additional argumentplot.return
is specified.- plot.decisions
Optional logical, defaults to
FALSE
. IfTRUE
, plots of escalation decisions according to the specified escalation rule are created. Ifplot.decisions
isTRUE
, it is recommended to supply a writablepath
and validfile.name
, as plots will by default only be saved and not returned to R. Plots are only returned to R if the additional argumentplot.return
is specified. In particular, ifplot.decisions
isTRUE
andplot.return
isFALSE
, the plots will not be accessible unless a validfile.name
is given to enable saving the plots.Depending on the value of
esc.rule
, the following plots are created:If
esc.rule=="ewoc"
, a diagram of the posterior probabilities that the DLT rate lies in the underdosing, target dosing and overdosing intervals is created, which indicates the boundary given inewoc.threshold
with red color coding (and, therefore, implicitly the decision of EWOC-based dose escalation rules). For trials of types"mono1"
and"mono2"
(cf. argumenttypes.of.interest
), a bar plot is created, and for trials of type"combi"
, either a heatmap of the overdosing probabilities can be created (if the value ofplot.combi.heatmap
isTRUE
) or alternatively a bar plot in the same fashion as monotherapy trials.If
esc.rule=="loss"
, a diagram of the expected loss (Bayes risk) based on the weight choice inloss.weights
is created. Further, the argumentplot.int.probs.loss
can be used to additionally create plots for the underdosing, target dosing and overdosing intervals. For trials of types"mono1"
and"mono2"
(cf. argumenttypes.of.interest
), a bar plot is created, and for trials of type"combi"
, either a heatmap of the expected loss can be created (ifplot.combi.heatmap==TRUE
) or alternatively a bar plot in the same fashion as monotherapy trials.If
esc.rule=="dynamic.loss"
, a diagram of the expected dynamic loss (dynamic Bayes risk) based on the weight choice indynamic.weights
is created. Further, the argumentplot.int.probs.loss
can be used to additionally create plots for the underdosing, target dosing and overdosing intervals. For trials of types"mono1"
and"mono2"
(cf. argumenttypes.of.interest
), a bar plot is created, and for trials of type"combi"
, either a heatmap of the expected dynamic loss can be created (ifplot.combi.heatmap==TRUE
) or alternatively a bar plot in the same fashion as monotherapy trials.
- plot.combi.heatmap
Optional logical, defaults to
TRUE
. If the value isTRUE
, combination therapy plots are created as heatmaps instead of bar plots. This affects all escalation rules.- plot.int.probs.loss
Optional logical, defaults to
FALSE
. Only has an effect ifesc.rule
is either"loss"
or"dynamic.loss"
. In this case, if the value isTRUE
, additional plots will be created that display the interval probabilities to complement the (always created) plots that display the resulting expected loss.- plot.return
Optional logical, defaults to
FALSE
. If set toTRUE
, the functions return the created plots to R in the result list. In this case, the result list will have an additional entry,...$plots
, which contains the posterior plots as a named list. The returned plots will be given as a list ofggplot2::ggplot()
objects, which can be displayed in R via theggplot2::plot.ggplot
method. Refer to the documentation of theggplot2-package
package for further detail.- plot.file.format
Optional character, defaults to
"pdf"
. Can either be"pdf"
,"jpeg"
or"png"
. Specifies the file format of the created output plots (if plots are saved). Note that"pdf"
will usegrDevices::cairo_pdf()
.- plot.width
Optional numerical value or vector, can have length 1 or 3 and must have positive entries. Provides the width of the output plots measured in the unit given in
plot.unit
. Ifplot.width
is a single value, all plots will use the same width. Otherwise, ifplot.width
has length 3, the entryplot.width[1]
is used as width for plots for trials of type"mono1"
, whileplot.width[2]
is used for trials of type"mono2"
andplot.width[3]
for trials of type"combi."
.plot.width
has only an effect if all of the parametersplot.unit
,plot.width
, andplot.height
are defined. In this case, The output plots will be created with the specified width and length (interpreted in the given unit of measurement). If one of these parameters is missing, the default device size is used.- plot.height
Optional numerical value or vector, can have length 1 or 3 and must have positive entries. Provides the height of the output plots measured in the unit given in
plot.unit
. Ifplot.height
is a single value, all plots will use the same height. Otherwise, ifplot.height
has length 3, the entryplot.height[1]
is used as height for plots for trials of type"mono1"
, whileplot.height[2]
is used for trials of type"mono2"
andplot.height[3]
for trials of type"combi."
.plot.height
has only an effect if all of the parametersplot.unit
,plot.width
, andplot.height
are defined. In this case, The output plots will be created with the specified width and length (interpreted in the given unit of measurement). If one of these parameters is missing, the default device size is used.- plot.unit
Optional character string, can be "in", "cm", or "mm". Provides the unit of measurements for
plot.width
andplot.height
. Has only an effect if all of the parametersplot.unit
,plot.width
, andplot.height
are defined. In this case, The output plots will be created with the specified width and length (interpreted in the given unit of measurement). If one of these parameters is missing, the default device size is used.- output.scen.config
Optional logical, defaults to
FALSE
. IfTRUE
, the results will contain the necessary specifications of the evaluated scenario, i.e., the data scenario, priors, escalation rule specification, and seed. Otherwise, only the posterior summaries are returned.
Value
List. The output list will have an entry for each trial of interest that provides a summary of the posterior toxicities. If output.scen.config
is TRUE
, additional entries that give the input data are included.
If plot.return
and plot.decisions
are both TRUE
, an additional entry is created that holds a list of all
output plots as ggplot2::ggplot
objects.
More precisely, the following list entries are always generated:
$trial-[...]
Here,[...]
denotes the given trial name intrials.of.interest
. The entry gives a matrix that lists summary statistics and interval probabilities based on the posterior of the DLT rate of each of the doses of interest for a trial. Additionally, if loss escalation is active, the expected loss of each dose is listed.
If additionally output.scen.config
is active, there will be the following
additional entries:
$data
Input data used to fit the joint BLRM. Includes all cohorts from bothdata
andhistorical.data
in a merged data matrix.$prior
Contains the specified (hyper-)prior distribution used by the joint BLRM.$configuration
Contains the remaining configurations, e.g. seed and escalation rule.$'Stan options'
Contains the arguments given to Stan, e.g. number of MCMC iterations and chains.
If the additional plot list is generated, there will be an entry:
$plots
List that contains the output plots asggplot2::ggplot
objects. There will be one entry for each trial, namely$plots$trial-[...]
Here,[...]
denotes the trial name of one of the trials of interest. The entry for a trial is either a singleggplot2::ggplot
object or a list of such objects. The number of entries is determined by the remaining specifications for plots. E.g., if loss escalation is performed, there can be either just a plot of the expected loss for each dose, or additionally a second plot with the usual interval probabilities. Similarly, if the trial of interest is of type"all"
, there will be up to 3 plots, one for each trial type for which dose levels are included (mono 1, mono 2, combination).
Details
The joint BLRM is defined according to (Neuenschwander et al., 2014 and 2016). It allows to perform Bayesian logistic regression to estimate the dose-toxicity relationship of two different monotherapies and combination therapy with these compounds in a joint model, which includes a hierarchical prior for robust borrowing across trials. The following gives a brief introduction to the model, for more detail refer to the references provided at the end of this documentation page.
Model specification
The model assumes, first of all, that treatment with a dose or dose combination \(d\) is during trial \(j\) governed by its toxicity parameter \(\pi_j(d)\), so that $$r|\pi_j(d) \sim Binomial(n, \pi_j(d))$$ for the number of DLTs, \(r\), observed after treating a cohort of \(n\) patients at dose \(d\) during trial \(j\). The toxicity is then modeled based on the type of treatment. If \(d_i\) is a dose of compound \(i\), it is assumed that $$logit(\pi_j(d)) = log(\alpha_{ij}) + \beta_{ij}\cdot log\left(\frac{d_i}{d^*_i}\right)$$ for unknown parameters \(\alpha_{ij}>0\) and \(\beta_{ij}>0\) dependent on the trial \(j\) and compound \(i\). Moreover, \(d^*_i\) denotes a fixed reference dose for compound \(i\).
Further, if \(d=(d_1, d_2)\) is a dose combination of compounds 1 and 2, write \(\pi_j(d_i)\) for their toxicity according to the monotherapy model, and define the interaction-free toxicity in trial \(j\) as $$\pi_{0j}(d_1, d_2) = \pi_j(d_1) + \pi_j(d_2) - \pi_j(d_1)\cdot \pi_j(d_2).$$ Based on this, an additional interaction parameter, \(\eta_j\), is introduced, and the combination therapy toxicity with interaction is modeled as $$logit(\pi_j(d_1, d_2)) = logit(\pi_{0j}(d_1, d_2)) + \eta_j \cdot \frac{d_1}{d^*_1} \cdot \frac{d_2}{d^*_2}.$$ This concludes the definition of the likelihood of the model. In the following, we denote the interaction term as the function $$ g(\eta, d_1, d_2) = \eta \cdot \frac{d_1}{d^*_1} \cdot \frac{d_2}{d^*_2}.$$ This is the so-called linear (on logit scale) interaction term.
Saturating interaction term
Another possibility for modeling the interaction is the so-called
saturating interaction term, which was proposed by the authors of the
OncoBayes2
package,
cf. OncoBayes2::blrm_formula_saturating()
.
This interaction model involves an additional scaling factor in dependence of the dose, with the aim of
addressing potentially problematic behavior of the linear interaction model in case
of large dose levels. More specifically, if one has \(\eta<0\) and considers the
limit \(d_i\rightarrow \infty\), it holds
$$
g(\eta, d_1, d_2) \rightarrow -\infty
$$
and, consequently, \(\pi_j(d_1, d_2) \rightarrow 0\). Although this seems to
be mostly affecting doses larger than the reference dose, this property may not
be considered realistic, so that one may want to use modified models that
do not show this behavior. For this aim, the functions in the decider
package allow to use a
saturating interaction term instead, which follows the ideas from
OncoBayes2::blrm_formula_saturating()
,
to avoid the aforementioned phenomenon.
The saturating interaction term is based on the usual interaction term, but includes an additional scaling factor in dependence of the dose level, which ensures a finite limit when letting \(d\rightarrow \infty\). More precisely, the linear interaction term,\(g(\eta, d_1, d_2)\), is exchanged with the saturating term $$ \tilde g (\eta, d_1, d_2) = g(\eta, d_1, d_2) \cdot \frac{2}{1+\frac{d_1}{d^*_1} \cdot \frac{d_2}{d^*_2}} $$ The scaling factor is defined so that whenever \(d_i=d^*_i\) for both \(i\), the saturating interaction term is equal to the usual interaction term, while it holds \(\tilde g (\eta, d_1, d_2)\rightarrow 2\eta\) for \(d_i\rightarrow \infty\).
Prior structure and prior choice
Regarding the prior configuration of the joint BLRM, denote by $$\theta_j=(log(\alpha_{1j}), log(\beta_{1j}), log(\alpha_{2j}), log(\beta_{2j}), \eta_j)$$ the trial-specific parameter vector for trial \(j\). For the general hierarchical prior assume that $$\theta_j|\mu,\Sigma \sim Normal_5(\mu, \Sigma)$$ for a shared hyper mean vector \(\mu\) and a shared hyper covariance matrix \(\Sigma\), with entries $$\mu=(\mu_1, \mu_2, \mu_3, \mu_4, \mu_5)$$ and $$\Sigma = (\Sigma_{kl})$$ for \(k=1,...,5\), \(l=1,...,5\). The entries \(\Sigma_{kl}\) are defined as $$\Sigma_{kk}=\tau_k\cdot\tau_k$$ on the diagonal, and as $$\Sigma_{kl}=\rho_{kl}\cdot\tau_k\cdot\tau_l$$ for \(k\) not equal to \(l\). Here, \(\rho_{kl}\) are the correlation coefficients of parameters \(k\) and \(l\), and \(\tau_k\) the standard deviations of their respective parameters. As the \(\tau_k\) control the standard deviation across the parameters of different trials, these parameters are referred to as between-trial heterogeneities.
Regarding the prior for the model, it suffices to specify the distributions of \(\mu_k\), \(\tau_k\) and \(\rho_{kl}\).
As a simplification, it is further assumed that all entries of \(\theta_j\) are uncorrelated, except for \(log(\alpha_{ij})\)
and \(log(\beta_{ij})\) (i.e., the parameters belonging to the same monotherapy compound).
That is, \(\rho_{kl}=0\) for all \(kl\), except for \(\rho_{12}\) and \(\rho_{34}\).
As hyperprior distribution of the correlations, the two remaining correlation coefficients \(\rho_{12}\) and \(\rho_{34}\)
are assumed to follow \(Uniform(-1, 1)\) distributions. Note that this cannot be changed in the functions scenario_jointBLRM()
,
sim_jointBLRM()
, and fit_jointBLRM()
.
For the hyper means \(\mu_k\), it is assumed that
$$\mu_k \sim Normal(m_{\mu_k}, s_{\mu_k}^2)$$
for fixed mean \(m_{\mu_k}\) and standard deviation \(s_{\mu_k}\). These values are specified in the prior.mu
argument of scenario_jointBLRM()
and sim_jointBLRM()
.
For simplicity, the entries of the list prior.mu
are vectors of length two, which contain the fixed mean \(m_{\mu_k}\)
and fixed SD \(s_{\mu_k}\). These entries are named for their corresponding parameters, as given in the following overview. For reasons of
readability, we will use the corresponding parameter names as subscript by writing e.g. \(\mu_{\alpha_1}\) for the hypermean of \(log(\alpha_1)\).
This is summarized in the following table.
Entry | mu_a1 | mu_b1 | mu_a2 | mu_b2 | mu_eta |
Parameter | \(log(\alpha_{1j})\) | \(log(\beta_{1j})\) | \(log(\alpha_{2j})\) | \(log(\beta_{2j})\) | \(\eta_j\) |
Hyper Mean | \(\mu_1=\mu_{\alpha_1}\) | \(\mu_2=\mu_{\beta_1}\) | \(\mu_3=\mu_{\alpha_2}\) | \(\mu_4==\mu_{\beta_2}\) | \(\mu_{\eta}\) |
For the hyper SDs \(\tau_k\), it is assumed that
$$\tau_k \sim logNormal(m_{\tau_k}, s_{\tau_k}^2)$$
for fixed mean \(m_{\tau_k}\) and standard deviation \(s_{\tau_k}\), which are both to be given on log-scale (that is,
\(\tau_k=exp(y)\) for a random variable \(y\) which has a \(Normal(m_{\tau_k}, s_{\tau_k}^2)\) distribution).
These values are specified in the prior.tau
argument of scenario_jointBLRM()
and sim_jointBLRM()
.
For simplicity, the entries of the list prior.tau
are vectors of length two, which contain the fixed mean \(m_{\tau_k}\)
and fixed SD \(s_{\tau_k}\) on log-scale. These entries are named for their corresponding parameters, as given in the following overview.
Entry | tau_a1 | tau_b1 | tau_a2 | tau_b2 | tau_eta |
Parameter | \(log(\alpha_{1j})\) | \(log(\beta_{1j})\) | \(log(\alpha_{2j})\) | \(log(\beta_{2j})\) | \(\eta_j\) |
Hyper SD | \(\tau_1=\tau_{\alpha_1}\) | \(\tau_2=\tau_{\beta_1}\) | \(\tau_3=\tau_{\alpha_2}\) | \(\tau_4=\tau_{\beta_2}\) | \(\tau_5=\tau_{\eta}\) |
See (Neuenschwander et al., 2014 and 2016) for details regarding the prior choice.
Escalation rules
The function supports in general three different escalation rules and corresponding displays of the results. In this context, the term "escalation rule" refers to a method that is used to derive concrete dosing recommendations from the posterior computed by the BLRM. The supported escalation rules are the escalation with overdose control (EWOC) principle, static loss escalation, and dynamic loss escalation.
Escalation with overdose control (EWOC)
The EWOC principle goes back to Babb et al. (1998) and derives dosing recommendations based on the posterior probability for overdosing, where overdosing refers to DLT rates above the specified target interval. By default, the overdosing interval starts therefore at 0.33. Formally, EWOC considers the posterior distribution \(\pi_j(d)\) of the DLT rate for a dose \(d\) and demands that the posterior probability of \(\pi_j(d)\) lying in the overdosing interval is lower than a prespecified feasibility bound (which defaults to 0.25). As a formula, the EWOC condition is therefore for a dose \(d\) during trial \(j\) (using the default values 0.33 and 0.25 for lower boundary of the overdosing interval and feasibility bound): $$ Prob(\pi_j(d) \ge 0.33) < 0.25. $$ Only doses that satisfy this criterion are then considered as recommendations for the next dose. To obtain a concrete dose among the remaining levels, one typically demands an additional rule. Most commonly, the "optimal probability rule" (selecting the dose that has the largest probability of having a DLT rate within the target interval among the levels that satisfy EWOC) or the "maximal dose rule" (selecting the largest dose that satisfies EWOC) are chosen. For dose combinations, one of the compounds should additionally be selected to be maximized first in case of draws.
Loss function-based escalation
Static loss escalation goes back to Neuenschwander et al. (2008) and applies Bayesian decision theory to obtain dosing recommendations. That is, the selection of a dosing recommendation is viewed as a decision problem among different available dose levels and different decisions (dose levels) are evaluated using a formal loss function. To define the loss function, the range of DLT rates is divided in four disjoint dosing intervals, namely, underdosing (interval \(I_1\)), target dosing (\(I_2\)), excessively toxic dosing (\(I_3\)), and unacceptably toxic dosing (\(I_4\)). In contrast to EWOC, this corresponds to dividing the overdosing interval into two distinct intervals to achieve a finer differentiation.
To define a formal loss function based on these intervals, a pre-specified penalty value (or interval weight), \(w_i\), is assigned to each of the dosing intervals. The loss function is then defined to be \(w_i\) for the decision on a dose with DLT rate in interval \(I_i\). As it is desired to select doses with DLT rate in the target interval, one should typically assume that \(w_2=0\) and that the remaining penalties are positive numbers. The dosing recommendation is now achieved by calculating for each fixed dose level the expected value of the loss function, the so-called Bayes risk (or expected loss). By definition of the loss function, the Bayes risk of a dose \(d\) during trial \(j\) is $$ \sum_{i=1}^4 w_i \cdot Prob(\pi_j(d) \in I_i). $$ The recommended decision is then the dose with minimal Bayes risk among the possible doses for the next cohort.
In terms of the pre-specified weights \(w_i\), one should always set \(w_2 = 0\) for the target interval, but for the remaining weights manual tuning may be required to cover different situations. Values that often work are e.g. \(w_1 = 1\), \(w_3 = 1\), \(w_4 = 2\) for moderate to aggressive escalation decisions, or \(w_1 = 1\), \(w_3 = 2\), \(w_4 = 3\) for rather conservative escalation decisions. Note that \(w_1 = 1\), \(w_3 = 1\), \(w_4 = 1\) leads to a decision rule that simply maximizes the probability to lie in the target interval, which was found to lead to overly aggressive decisions in simulations according to Zhou et al. (2018).
Dynamic adjustment of loss function-based escalation
Dynamic loss escalation refers to a heuristic that aims to adapt the pre-specified loss weights of the method described in the previous subsection. The motivation for this are potential difficulties with respect to pre-specifying weights that ensure appropriate behavior in different situations (larger or lower true DLT rates), as well as the attempt to obtain an escalation rule that behaves more robustly across scenarios, in the sense that it obtains good performance in settings of very low DLT rates as well as in settings of very large ones. Static loss escalation often needs to be tuned to one of these settings to obtain good on-trial behavior, but may perform poorly in other settings due to this. Dynamic loss escalation tries to avoid this by adapting the loss weights to more aggressive or more conservative configurations using a heuristic based on the observed data and posterior.
To apply dynamic loss escalation, four fixed loss weight combinations $$W_k=(w_{k1}, w_{k2}, w_{k3}, w_{k4})$$ for \(k=1,...,4\) with different degrees of aggressiveness need to be selected. The weights should be normalized in the sense that the absolute values of each \(W_k\) must sum up to the same number (i.e., have identical \(l_1\) norms). As decisions from static loss functions are invariant under linear rescaling of the weights, one can assume without loss of generality that the weights sum up to 1.
For the weight adjustment, new loss weights are computed prior to every decision by interpolating between the fixed weights \(W_k\) based on the current posterior interval probabilities of the reference dose of the trial of interest. Denote the reference dose as \(d^*\), which can either be a monotherapy dose level (for monotherapy trials) or a dose combination. Now, for each dosing interval \(I_i\), the corresponding reference interval probabilities \(p^*_i\) are computed from the posterior of the BLRM, i.e., assuming that trial \(j\) is the trial of interest, compute for \(i=1,...,4\) $$ p^*_i = Prob(\pi_j(d^*) \in I_i). $$ Using these, define the current dynamic weight \(w^*\) as the interpolation $$ w^* = p^*_1 * W_1 + p^*_2 * W_2 + p^*_3 * W_3 + p^*_4 * W_4. $$ These dynamic weights can now used to define a formal loss function and arrive at a decision by computing the dose with the minimal expected loss based on the dynamic penalty weights for the intervals.
Intuitively, the heuristic assumes that the reference dose is a priori assumed to be a likely candidate for the MTD, and typically among the
larger planned dose levels. That is, when the reference dose has a large probability of being an underdose, the dose-toxicity scenario
was less toxic than expected a priori, and a more aggressive weight combination can be applied. Conversely, if the reference dose has a large
probability of being overly toxic, the planned dose levels (and therefore, the investigational treatment) may likely be more toxic
than expected a priori, so that a more conservative configuration of interval penalties (larger penalty for overdosing intervals) is appropriate.
Due to this, the weights \(W_1\) should represent the most aggressive configuration, \(W_2\) and \(W_3\) should be moderate to conservative
configurations, while \(W_4\) should be the most conservative among the prespecified weights. Refer to the parameter documentation of
dynamic.weights
for a proposed default configuration that was found to work well in many situations.
References
Stan Development Team (2020). RStan: the R interface to Stan. R package version 2.21.2. https://mc-stan.org
Neuenschwander, B., Branson, M., & Gsponer, T. (2008). Critical aspects of the Bayesian approach to phase I cancer trials. Statistics in medicine, 27(13), 2420-2439, doi:10.1002/sim.3230.
Neuenschwander, B., Matano, A., Tang, Z., Roychoudhury, S., Wandel, S., & Bailey, S. (2014). A Bayesian Industry Approach to Phase I Combination Trials in Oncology. In: Zhao. W & Yang, H. (editors). Statistical methods in drug combination studies. Chapman and Hall/CRC, 95-135, doi:10.1201/b17965.
Neuenschwander, B., Roychoudhury, S., & Schmidli, H. (2016). On the use of co-data in clinical trials. Statistics in Biopharmaceutical Research, 8(3), 345-354, doi:10.1080/19466315.2016.1174149.
Babb, J., Rogatko, A., & Zacks, S. (1998). Cancer phase I clinical trials: Efficient dose escalation with overdose control. Statistics in medicine 17(10), 1103-1120.
Zhou, H., Yuan, Y., & Nie, L. (2018). Accuracy, safety, and reliability of novel phase I designs. Clinical Cancer Research, 24(21), 5483-5484 <doi: 10.1158/1078-0432.ccr-18-0168>.
Examples
if (FALSE) {
result <- scenario_jointBLRM(
data=list(dose1 = c(1, 2, 4, 6, 8, 0, 0, 0, 1, 2),
dose2 = c(0, 0, 0, 0, 0, 10, 20, 30, 10, 10),
n.pat = c(3, 3, 3, 3, 3, 3, 6, 9, 3, 3),
n.dlt = c(0, 0, 0, 0, 1, 0, 0, 1, 0, 0),
trial = c(1, 1, 1, 1, 1, 2, 2, 3, 3, 3)
),
trials.of.interest = c(1, 3),
types.of.interest = c("mono1", "combi"),
doses.of.interest = rbind(
c(1, 2, 4, 6, 8, 12, rep(c(1, 2, 4, 6, 8, 12),
times=3)),
c(0, 0, 0, 0, 0, 0, rep(c(10, 20, 30),
each = 6 ))),
dose.ref1 = 12,
dose.ref2 = 30,
esc.rule = "dynamic.loss",
prior.mu = list(mu_a1 = c(logit(0.33), 2),
mu_b1 = c(0, 1),
mu_a2 = c(logit(0.33), 2),
mu_b2 = c(0, 1),
mu_eta = c(0, 1.121)),
prior.tau = list(tau_a1 = c(log(0.25), log(2)/1.96),
tau_b1 = c(log(0.125), log(2)/1.96),
tau_a2 = c(log(0.25), log(2)/1.96),
tau_b2 = c(log(0.125), log(2)/1.96),
tau_eta = c(log(0.125), log(2)/1.96)),
path = getwd(),
file.name = NULL,
iter=10000,
chains=4
)
}