dfsim | R Documentation |
This function simulates sequential dose-finding experiments on a fixed dose grid. The response function is (implicitly) assumed monotone in (0,1)
dfsim(
n,
starting = NULL,
sprobs = NULL,
cohort = 1,
Fvals,
ensemble = dim(Fvals)[2],
design = krow,
desArgs = list(k = 1),
thresholds = NULL,
seed = NULL,
showdots = TRUE
)
n |
sample size |
starting |
the starting dose level. If |
sprobs |
the probability weights if using a randomized starting dose. If |
cohort |
the cohort (group) size, default 1. |
Fvals |
(vector or matrix): the true values of the response function on the dose grid. These are the dose-response scenarios from which the experimental runs will be simulated. If running an ensemble with different scenarios, each scenarios is a column. If running an identical-scenario ensemble, provide a single vector as well as |
ensemble |
the number of different runs/scenarios to be simulated. Will be determined automatically if |
design |
the dose-finding design function used to determine the next dose. Default |
desArgs |
List of arguments passed on to |
thresholds |
Matrix of size (at least) |
seed |
The random seed if simulating the thresholds. Can be kept "floating" (i.e., varying between calls) if left as |
showdots |
Logical: print out a dot ( |
A vectorized dose-finding simulator, set up to run an entire ensemble simultaneously.
The simulated doses are indices 1:nlev
with nlev
being the number of dose levels.
Upon output they can be optionally "dressed up" with physical values using the xvals
argument.
The simulator's essential use within the upndown
package is to estimate bootstrap confidence intervals for dose-averaging target estimates, via dfboot
. But it can be also used stand-alone as a study-design aid.
The particular dose-finding design simulated is determined by design
and its argument list desArgs
. The 3 straightforward extensions of the median-finding "Classical" UDD are available, namely "k-in-a-row", biased-coin and group (cohort) UDD. To simulate the the median-finding "Classical" UDD itself, use krow
with desArgs = list(k=1)
.
Other non-UDD dose-finding designs - e.g., CRM, CCD, BOIN, etc. - can also be made compatible with dfsim
. Utilities to run those 3 in particular are available on GitHub, under assaforon/UpndownBook/P3_Practical/OtherDesigns.r
.
If you want to create a design
function yourself, it would need to accept doses, responses
as input, and return the next dose allocation (as an integer index).
The main progression loop is run via mapply
.
A list with the following elements:
scenarios
: Fvals
sample
: thresholds
doses
: The matrix of simulated dose allocations for each run (n+1
by ensemble
)
responses
: The matrix of simulated responses (0 or 1) for each run (n
by ensemble
)
cohort
: cohort
details
: desArgs
This is an adaptation of a non-package function used by the author for well over a decade before incorporating it into upndown
in late 2023. For initial guidance, see the code example. If you encounter any funny behavior please let me know. Thank you!
Assaf P. Oron
dfboot
### dfsim example
# We provide a "toy example" for how randomized-F simulations might work.
# We have been strong advocated of this simulation approach, especially for performance comparison
# between designs and between estimators. It is far preferable to the "cherry-picked F" approach.
# Unfortunately, the latter is still more commonly found in dose-finding literature.
# At core is a randomized ensemble of F(x) ("dose-response") curves. It is far easier
# to generate parametric ensembles rather than nonparametric or semi-parametric ones.
# So this is what we do here. We use the Weibull, being capable of the most diverse ensembles
# among common parametric families.
# This being a toy example, it is more simplistic than our current practice. For the latter,
# see either the supplement to Oron et al. 2022, or the NE Journal of SDS due online
# late 2024 or early 2025. Ok, let's go!
# We simulate 7-level experiments.
m = 7
# And 10 curves in total
B = 10
# Parameter generation (I chose the parameter bounds after some trial and error)
# Note I am not fixing a seed, so each time you run this you'll get a different ensemble!
wparams = cbind(2^runif(B, -2, 2.5), runif(B, 1, 10) )
round(wparams, 2)
# Now the F(x) curves; they should be in columns
ensemble = apply(wparams, 1, function(x, doses = m)
pweibull(1:doses, shape = x[1], scale = x[2]) )
# Let's see what we got!
round(ensemble, 3)
# The experiment will be "Classical" median-targeting. In real life if 0.5 falls outside
# of the range of doses, it's not great. For simulation it's fine; it'll enable us to
# watch the allocations for such curves heap near the edge with F closest to 0.5.
# Let the experiments be a measly n=15, to keep runtime under the menacing 5 seconds.
# We start all runs smack in the middle, level 4:
sout = dfsim(n = 15, starting = 4, Fvals = ensemble, design = krow, desArgs = list(k=1) )
names(sout)
# "scenarios" are the F values we provided, while "sample" is the set of randomized thresholds
# simulated from the uniform distribution. If you run comparisons, we recommend that
# you only randomize the first set in the comparison, and feed the very same thresholds to
# all the rest.
# Anyhoo, here are the simulated trajectories. Note that there are n+1 of them, because after
# seeing x_n and y_n, the n+1-th allocation can be determined.
sout$doses
# Compare with the F ensemble. Is it what you expected?
# Probably more random-walky than you thought :)
# The binary responses are below. Before going big on the simulation, it's a good idea to
# sanity-check and see that the doses and responses match according to the design's rules.
sout$responses
# Some meta details about the design and simulation settings are available here:
sout$details
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.