Open Puzzled-Face opened 1 month ago
Interesting idea, thanks @Puzzled-Face - can you give a code example for the situation mentioned above? Just so that I can better imagine this.
For example
data <- Data(
doseGrid = c(1, 3, 9, 18, 36, 54, 80, 100),
x = c(1, 1, 1, 3, 3, 3, 9, 9, 9),
y = c(rep(0, 8), 1),
cohort = rep(1L:3L, each = 3),
ID = 1L:9L
)
model <- .DefaultLogisticLogNormal()
samples <- mcmc(data, model, .DefaultMcmcOptions())
next_best_mtd <- NextBestMTD(
0.25,
function(mtd_samples) quantile(mtd_samples, probs = 0.25)
)
next_best_min_dist <- .DefaultNextBestMinDist()
nextBest(next_best_mtd, Inf, samples, model, data)
nextBest(next_best_min_dist, Inf, samples, model, data)
next_best_min <- NextBestMin(list(next_best_mtd, next_best_min_dist))
nextBest(next_best_min, Inf, samples, model, data)
next_best_max <- NextBestMax(list(next_best_mtd, next_best_min_dist))
nextBest(next_best_max, Inf, samples, model, data)
More realistically (and this is the type of use case that prompted the issue):
ordinal_data <- DataOrdinal(
doseGrid = c(1, 3, 9, 18, 36, 54, 80, 100),
x = c(1, 1, 1, 3, 3, 3, 9, 9, 9),
y = c(rep(0, 6), 0, 0, 1, 0, 0, 2),
cohort = rep(1L:3L, each = 3),
ID = 1L:9L,
yCategories = c("No Tox" = 0L, "DLT" = 1L, "CRS" = 2L)
)
ordinal_model <- .DefaultLogisticLogNormalOrdinal()
samples <- mcmc(ordinal_data, ordinal_model, .DefaultMcmcOptions())
# We want separate constrants on p(DLT) and p(CRS). The next best dose must satisfy both.
next_best_trial <- NextBestMin(
list(
# Limit p(DLT) to 33%
NextBestOrdinal(1L, .DefaultNextBestMinDist(0.33)),
# Limit p(CRS) to 5%
NextBestOrdinal(2L, .DefaultNextBestMinDist(0.05))
)
)
nextBest(next_best_trial, Inf, samples, ordinal_model, ordinal_data)
Though this code will currently fail since nextBest(<NextBest>, <numeric>, <Samples>, ordinal_model, ordinal_data)
will fail because <NextBest>
must be an instance of NextBestOrdinal
, which operates on only one toxicity grade.
The PR associated with this issue is the set up for #856, which will provide support for this situation. The tests included in the PR demonstrate the correct function of the new class(es) for Data
and GeneralModel
. (Though note the addition of a new dependency on patchwork
. This (or similar) is required to get a sensible value in the plot
element of the return value of nextBest()
.)
I think it would generally be good for this kind of larger feature to have a design doc first :-)
But for the content, I would like to check whether this cannot be equally well achieved by additional Increments
rules? Because there we already have the restrictions on the dose range, and NextBest
is then for optimizing a certain criterion subject to the restrictions from Increments
. Note that we also have NextBest
rules which are combining multiple outcomes (e.g. safety and efficacy)
Good points. Will think about whether Increments
will suffice. Though I am doubtful. Increments
tend to impose limits relative to the current dose and are based on the trial design. (For example, 200% increment from the highest dose administered so far.) What I am proposing here is a limit based on the fitted model, which seems to fit more naturally with NextBest
. The additional functionality is simply the ability to apply more than one rule.
I don't think dual endpoints present any fundamental difficulties, though we may need different generics to handle them.
We also have already Increments
rules with models, e.g. https://github.com/openpharma/crmPack/blob/main/R/Rules-class.R#L1362
I would see the dual endpoints NextBest
rules as examples where multiple models are combined into a single rule, rather than defining them separately and the combining with min or max. For example, if the ordinal model needs something specific here, it could be an interesting alternative to just define a special rule for this case.
Hmmm. I think it is possible to do what I propose with an Increments
rule, but I still think it fits better as a NextBest
. The reason is simple: the Increments
rules are based on the design of the trial (ratio of this dose level to the next etc), whereas the NextBest
rules may be based on the results of the trial. Even the IncrementsHSRBeta
rule you link to above uses a fixed prior when evaluating the likelihood of toxicity rather than the current posterior obtained from the trial to date.
The point is made clear by the signatures of the relevant generics. For maxDose
, used with Increments
, the signature is (Increments, Data, ...)
, whereas for nextBest
, used with NextBest
it is (NextBest, numeric, Samples, GeneralModel, Data, ...)
.
So we could create (say) an IncrementsMaxToxProb
, but it would need a Samples
object passed to it. This would make it look like a NextBest
class even though it wasn't.
Equally, I could make a NextBestMaxToxProb
class specific for DataOrdinal
data and LogisiticLogNormalOrdinal
models, but that would lose the generality the other options provide.
I can see where the philosophical conflict arises. Conceptually, we determine which doses are safe/eligible (with an Increments
rule) and then determine which of the eligible/safe doses is optimal for the next cohort (with a NextBest
rule). As I wrote earlier, determining which doses are eligible is typically a design decision whereas determining which is optimal is based on results. This is the first example where an eligibility/safety questions requires results rather than simply design data.
The solution based on an ordinal-specific NextBest
rule is probably minimum effort/minimum risk, but it does break the assumption I made in designing the wrapper classes for ordinal rules that only one toxicity grade is relevant. I would say that using a set of new NextBest
rules is safe and more consistent with the way the package is currently written. But creating a new Increments
rule that takes a Samples
argument is most consistent with the idea of first choosing which doses are safe and then selecting the best dose amongst the safe doses.
It's not an easy decision!
Thanks @Puzzled-Face for the analysis, much appreciated!
I just think that normally this won't be needed, so am trying to keep the changes to a minimum. How about a compromise where you have a special NextBest
class for ordinal models and that takes multiple NextBest
objects itself? So nothing that needs to work with all possible models etc, but just tailored for this problem.
Some trials, most obviously those using ordinal models, may need to recommend a dose based on the minimum/maximum of different
NextBest
rules.For example
This is not currently supported, but would be by the creation of
NextBestMin
(andNextBestMax
) classes with behaviour analogous toCohortSizeMin
andCohortSizeMax
.