std::sort() on a fixed-size array, for which GCC 16 gave a
compiler warning (-Warray-bounds) during installation. The
results are unchanged.This version is a redesign of the package and is not backward
compatible with version 0.1.0. A study is described by small
specification objects (priors, data, external data, hypothetical
controls and decision criteria) that are combined into a design, and
three functions work with any design: qdm_decide(),
qdm_oc() and qdm_calibrate().
qdm_boundary() shows the observed data that lead to each
decision. Formulas and numerical methods that were wrong in version
0.1.0 have been corrected (see below), so some results differ from those
of version 0.1.0. vignette("migration") shows how to
translate code written for version 0.1.0.
| Version 0.1.0 | Version 1.0.0 |
|---|---|
pbayespostpred1bin(),
pbayespostpred1cont(), pbayespostpred2bin(),
pbayespostpred2cont() |
qdm_decide() with a design and observed data |
pbayesdecisionprob1bin(),
pbayesdecisionprob1cont(),
pbayesdecisionprob2bin(),
pbayesdecisionprob2cont() |
qdm_oc() |
getgamma1bin(), getgamma1cont(),
getgamma2bin(), getgamma2cont() |
qdm_calibrate() |
Arguments prob, design,
prior, CalcMethod, theta_*,
gamma_*, a_*, b_*,
kappa0_* and similar |
Arguments of criterion_*(), prior_*() and
design_*() |
Arguments ne_*, ye_*,
alpha0e_*, bar_ye_*, se_* |
borrow(data_*(...), a0) |
Arguments z, z00 to z11,
mu0_c, r |
hypothetical() |
ptdiff_NI(), ptdiff_MC(),
ptdiff_MM() |
ptdiff() with method = "NI",
"MC" or "MM" |
pbetadiff(), pbetabinomdiff() |
Same names, with the arguments ordered by group |
getjointbin() |
cellprob_binary2() |
allmultinom() |
Internal function |
rdirichlet() |
Same name |
print() and plot() methods for eight
classes |
Methods for qdm_decision, qdm_oc,
qdm_calibration, qdm_boundary,
qdm_design and the specification objects |
inst/validation/ contains scripts that compare the
package with published and submitted results (Kang et al., 2026; Huang,
Talukder, Han and Kuan, 2019; Huang et al., submitted; Yamaguchi, Homma,
Takeda and Maruo, submitted; Yamaguchi et al., submitted), and
inst/validation/results/summary.md reports the comparisons,
with a registered reason for every difference beyond rounding, including
the results that are not reproduced.prior_beta(), prior_dirichlet(),
prior_nix(), prior_niw(),
prior_gamma() and prior_vague().data_binary(),
data_continuous(), data_binary2(),
data_continuous2() and data_tte().conduct_tte().borrow().hypothetical().criterion_posterior() and
criterion_predictive(). For all endpoints, the Go criterion
is that the probability of the Go region is at least
gamma_go and the NoGo criterion is that the probability of
the NoGo region is at least gamma_nogo.criterion_posterior() and
criterion_predictive() have the argument
direction. With direction = "greater" (the
default), larger effects are favorable, as in version 0.1.0. With
direction = "less", smaller effects are favorable, for
example for the rate of an adverse event or a hazard ratio: the Go
region is that the effect is below theta_tv (or, for the
predictive criterion, that the future effect is below
theta_null), the NoGo region is that it is at least
theta_mav (at least theta_null for the
predictive criterion), and theta_tv must be smaller than
theta_mav. For two endpoints, the direction can be set for
each endpoint, for example an efficacy endpoint and a safety
endpoint.qdm_regions() shows the numbering of the regions for
two endpoints.design_binary() specifies a study with one binary
endpoint: sample sizes, Beta priors, external data for either group
(borrow()), and a concurrent, external-only
(n_c = 0 with external_c) or hypothetical
(n_c = 0 with hypothetical_c) control
group.qdm_decide() computes the probabilities of the Go and
NoGo regions for observed data and returns the decision: Go, NoGo, Gray,
or Miss (both criteria met).qdm_oc() computes the probabilities of the four
decisions under scenarios for the true response rates by exact
enumeration of the outcomes. Miss decisions are reported in their own
column with a warning; the arguments error_if_Miss and
Gray_inc_Miss of version 0.1.0 are removed.qdm_calibrate() chooses gamma_go and
gamma_nogo as the smallest grid values for which the
probabilities that the Go criterion is met under one scenario and that
the NoGo criterion is met under another are at most their targets
(version 0.1.0 required them to be less than the targets), and returns
the design with these thresholds and its decision probabilities.print() methods for designs, decisions, operating
characteristics and calibrations, and plot() methods
(ggplot2) for operating characteristics and calibrations. Without a
concurrent control group, the thresholds in the plot of operating
characteristics are shifted by the mean of the distribution of the
control group..Machine$double.eps^0.25. A probability that is below a
threshold by less than 1e-10 is treated as equal to the threshold, so
that exact ties are not decided by rounding errors.design_continuous() specifies a study with one normally
distributed endpoint: sample sizes, Normal-Inverse-chi-squared
(prior_nix()) or vague (prior_vague()) priors,
external data for either group (borrow()), a concurrent,
external-only or hypothetical control group, and the method used to
compute the probabilities ("NI", "MM" or
"MC").a0 * n_e + n - 1 degrees of freedom, and the
posterior scale uses the same denominator (version 0.1.0 used
a0 * n_e + n, so the posterior did not reduce to the one
without external data as a0 tends to 0).m
future subjects is
t(nu_n, mu_n, sigma_n^2 * (1 / kappa_n + 1 / m)). Version
0.1.0 used the squared scale
sigma_n^2 * (1 + 1 / kappa_n) / m, which treats the
m future subjects as independent draws from the predictive
distribution of one subject and understates the uncertainty for
m of 2 or more.hypothetical(mean = mu0c, r = r)) gives the control mean
the distribution t(nu_nt, mu0c, r * sigma_nt^2 / kappa_nt)
(Kang et al., 2026, Section 4.2.4). For the predictive criterion its
squared scale is
r * sigma_nt^2 * (1 / kappa_nt + 1 / m_c).qdm_oc() and qdm_calibrate() simulate the
sample means and standard deviations of nsim studies, with
the same random numbers for all scenarios. With
method = "MC", the probabilities of the Go and NoGo regions
are estimated from the same draws, so that they add up to 1 for the
predictive criterion.qdm_decide() has a seed argument for
designs with method = "MC".design_binary2() specifies a study with two binary
endpoints: sample sizes, Dirichlet priors for the probabilities of the
four combinations of responses (prior_dirichlet()),
external data for either group
(borrow(data_binary2(...), a0)), a concurrent,
external-only or hypothetical control group, the number of Monte Carlo
draws nMC, and whether the operating characteristics are
computed by enumerating all outcomes (enumerate = TRUE, the
default) or by simulation.criterion_posterior() and
criterion_predictive() have the argument rule.
With rule = "joint" (the default), the criteria are on the
probabilities of unions of regions (go_regions and
nogo_regions, numbered as in qdm_regions()).
With rule = "and" or rule = "or", the criteria
are on each endpoint separately (the probability that the effect exceeds
its TV, or is at most its MAV), with one threshold for both endpoints or
one per endpoint.nMC draws (default 10000) from the Dirichlet posterior
distributions, computed in C++. The probabilities of all regions, and of
the Go and NoGo regions, are estimated from the same draws, and
qdm_decide() reports all of them.
qdm_decide(), qdm_oc() and
qdm_calibrate() take seed for these
draws.qdm_oc() takes scenarios with the columns
pi_t1, pi_t2, rho_t,
pi_c1, pi_c2 and rho_c. With
enumeration, the region probabilities are computed once for every pair
of treatment and control outcomes, with the same Monte Carlo draws for
all pairs, and weighted by the multinomial probabilities under each
scenario. With simulation, all scenarios use the same uniform random
numbers. Enumeration is limited to 1e7 pairs of outcomes (for example,
24 subjects in each group). A scenario whose correlation is outside the
feasible range for its response rates is not evaluable: its
probabilities are NA with a warning (version 0.1.0 stopped
with an error in its Monte Carlo path). qdm_calibrate()
requires feasible scenarios.plot() of operating characteristics for two endpoints
draws a heat map of the probability of each decision over the effects on
the two endpoints and marks scenarios that are not evaluable with
“NE”.design_continuous2() specifies a study with two
continuous endpoints: sample sizes, Normal-Inverse-Wishart
(prior_niw()) or vague (prior_vague()) priors,
external data for either group
(borrow(data_continuous2(...), a0)), a concurrent,
external-only or hypothetical
(hypothetical(mean = c(m1, m2), r = r)) control group, the
decision criterion for two endpoints (with rule as for two
binary endpoints), and the method used to compute the probabilities
("MM" or "MC").kappa0 = 0, nu0 = -1 and
Lambda0 = 0.m
future subjects has the scale matrix
(1 / kappa_n + 1 / m) * Lambda_n / (nu_n - 1). Version
0.1.0 used
(1 + kappa_n) / kappa_n * Lambda_n / (nu_n - 1) / m, which
treats the m future subjects as independent draws from the
predictive distribution of one subject.method = "MM", the moment-matching approximation
of the difference of two bivariate t distributions is used, and its
rectangle probabilities are computed by numerical integration in C++ for
real degrees of freedom (version 0.1.0 rounded the degrees of freedom to
an integer for mvtnorm::pmvt()). With
method = "MC", the probabilities of all regions are
estimated from the same draws, and every simulated study uses its own
draws (version 0.1.0 used the same draws for all simulated studies, so
the Monte Carlo error did not average out).qdm_oc() takes scenarios with the columns
mu_t1, mu_t2, sd_t1,
sd_t2, rho_t, mu_c1,
mu_c2, sd_c1, sd_c2 and
rho_c, and simulates the sample means and the sums of
squares and cross-products (Bartlett decomposition of the Wishart
distribution) of nsim studies with the same random numbers
for all scenarios.fixed_c for a
single-arm study compared with a known value of the control parameter (a
response rate, a mean, a milestone survival probability, or a median
survival time for the hazard ratio; one value per endpoint for two
endpoints). It requires n_c = 0 and
prior_c = NULL. The effect is the treatment parameter minus
the fixed value (for the hazard ratio, the treatment hazard divided by
the control hazard log(2) / fixed_c), so the probabilities
depend only on the posterior distribution of the treatment group: Beta
probabilities (one binary endpoint), t probabilities (one continuous
endpoint), probabilities of the bivariate t distribution by numerical
integration for any degrees of freedom (two continuous endpoints), Monte
Carlo draws from the Dirichlet posterior (posterior probabilities for
two binary endpoints), Gamma probabilities (posterior probabilities for
a time-to-event endpoint), and exact predictive probabilities for binary
endpoints, in which a future proportion equal to the fixed value plus
the null value is not counted as larger. The argument
method is not used for continuous endpoints.design_tte() specifies a study with one time-to-event
endpoint evaluated by the survival probability at a milestone time or by
the hazard ratio (see below): exponential event times with Gamma priors
on the hazards (prior_gamma()), data summarized by the
number of events and the total observed time (data_tte()),
external data for either group through a power prior, and a concurrent,
external-only, hypothetical or fixed control group. With the milestone
survival, the effect is the difference of the milestone survival
probabilities.psurvdiff()), or exactly for a fixed
control. Posterior predictive probabilities are estimated by simulating
nMC future studies conducted as specified by
conduct_future, with hazards drawn from the posterior
distributions; the milestone survival of each group in the future study
is estimated at the posterior mean of the hazard given the future data
and the prior of the group.qdm_oc() and qdm_calibrate() simulate
nsim studies with piecewise uniform enrollment, piecewise
exponential dropout and an analysis at a calendar time or at a given
number of events among all subjects of the study
(conduct_tte()), under scenarios given by the median
survival times (median_t, median_c), with the
same random numbers for all scenarios.effect = "hazard_ratio", the effect is the hazard
ratio lambda_t / lambda_c (Huang, Talukder, Han and Kuan,
2019), usually with direction = "less" in the criterion.
The posterior distribution of the hazard ratio is a scaled F
distribution, so posterior probabilities are exact
(phazardratio()); a fixed control is given by its median
survival time. Posterior predictive probabilities compare the ratio of
the estimated hazards of the future study with
theta_null.inst/validation/ reproduces the probabilities of a Go
decision in Table 1 of Huang et al. (2019) (a randomized study analyzed
at a given number of events) with the hazard ratio and the posterior
criterion.qdm_boundary() returns the intervals of an observed
quantity that lead to Go, NoGo, Gray and Miss decisions, for each value
of a second quantity: the number of treatment responders for each number
of control responders (one binary endpoint with a concurrent control
group) or for each sample size (without one), the observed treatment
mean for each standard deviation or sample size (one continuous
endpoint), the observed treatment mean of endpoint 2 for each observed
mean of endpoint 1 (two continuous endpoints), and the number of events
for each total observed time (time-to-event endpoint). The intervals are
also given as observed response rates or milestone survival
probabilities and as observed treatment effects (differences from the
control group or the fixed control value, or observed hazard ratios).
Two binary endpoints are not supported.print() method shows the intervals as tables with
one row per condition and one column per decision, for example the
numbers of responders out of 20 that lead to Go (10-20),
the corresponding observed response rates (50.0% to 100.0%)
and the observed differences from a fixed control rate of 0.2
(0.3 to 0.8). The plot() method draws the
regions of the decisions with the boundary values written on them
(labels, label_size), and for one binary
endpoint with a concurrent control group a secondary axis with the
observed response rate of the treatment group.plot() methods for operating characteristics,
calibrations and decision boundaries return ggplot2 objects, which can
be changed further by adding ggplot2 functions such as
labs() and theme(). In all three plots,
arguments set the colors of the decisions (col_go,
col_nogo, col_gray and col_miss,
green, red, gray and orange by default; the calibration plot uses
col_go and col_nogo), the base font size
(base_size, 11 by default instead of 28 in version 0.1.0)
and the position of the legend (legend_position). The plots
of operating characteristics and calibrations also take the width of the
lines (linewidth), and the plots of operating
characteristics and decision boundaries the size of the text drawn in
the plot (label_size); the plot of operating
characteristics also takes the size of the points
(point_size). Other arguments are ignored with a
warning.cell_values = FALSE).
Scenarios that are not evaluable are white and marked “NE”.plot() of operating characteristics for two endpoints
has the argument overlay, which replaces
which = "overlay" of version 0.1.0. With
overlay = TRUE, a single heat map shows in each cell the
decision with the highest probability, shaded in five steps of that
probability, with legends for the decisions and the steps (Yamaguchi et
al., submitted, Figure 2). cell_values = FALSE leaves out
the probabilities written in the cells of either heat map.pbetadiff() has the argument order
(q, a_t, b_t, a_c, b_c). The range of integration is
restricted to the support and split at quantiles of both Beta
distributions, so concentrated distributions are integrated accurately.
When a shape parameter of the control group is below 1, the integral
near the unbounded end of its density is computed after a change of
variables that removes the singularity. The computation is done in
C++.pbetabinomdiff() has the argument order
(q, m_t, a_t, b_t, m_c, a_c, b_c) and computes the
probability mass functions on the log scale, so large numbers of future
subjects no longer cause overflow. Values of q far outside
[-1, 1] are handled exactly.ptdiff() replaces ptdiff_NI(),
ptdiff_MC() and ptdiff_MM(). The numerical
integration now covers the whole real line (version 0.1.0 truncated the
range, with errors of up to about 3e-4 for small degrees of freedom). It
integrates over the group with the smaller scale, splits the range
around the peak of the density and the change of the other factor, and
integrates the parts far from the origin on a logarithmic scale, so that
scale ratios from 1e-9 to 1e3 and degrees of freedom from 0.5 to
Inf are handled.rdirichlet() always returns a matrix.cellprob_binary2() replaces
getjointbin().psurvdiff() computes the distribution function of the
difference of two milestone survival probabilities with Gamma
distributed exponential hazards, by adaptive quadrature in C++ over the
hazard of one group, with the range split at quantiles of both hazards
and a change of variables near 0 when a shape parameter is below 1. Each
tail is computed directly, so both are accurate near 0.phazardratio() computes the distribution function of
the ratio of two Gamma distributed hazards from the F distribution.\dontrun{} with \donttest{} in
examples for getgamma2bin() and
getgamma2cont().Initial release providing a comprehensive Bayesian quantitative decision-making framework for clinical trials with single and two-endpoint analyses for binary and continuous outcomes.
pbayesdecisionprob1bin() - Go/NoGo/Gray decision
probabilities for a single binary endpointpbayesdecisionprob1cont() - Go/NoGo/Gray decision
probabilities for a single continuous endpointpbayesdecisionprob2bin() - Go/NoGo/Gray decision
probabilities for two binary endpointspbayesdecisionprob2cont() - Go/NoGo/Gray decision
probabilities for two continuous endpointsprint.pbayesdecisionprob1bin() - Print method for
pbayesdecisionprob1bin objectsprint.pbayesdecisionprob1cont() - Print method for
pbayesdecisionprob1cont objectsprint.pbayesdecisionprob2bin() - Print method for
pbayesdecisionprob2bin objectsprint.pbayesdecisionprob2cont() - Print method for
pbayesdecisionprob2cont objectsplot.pbayesdecisionprob1bin() - Plot method for
pbayesdecisionprob1bin objects; displays Go/NoGo/Gray
decision probabilities as a line plot across treatment scenariosplot.pbayesdecisionprob1cont() - Plot method for
pbayesdecisionprob1cont objects; displays Go/NoGo/Gray
decision probabilities as a line plot across treatment scenariosplot.pbayesdecisionprob2bin() - Plot method for
pbayesdecisionprob2bin objects; displays Go/NoGo/Gray
decision probabilities as a tile or scatter plot over a two-dimensional
treatment scenario gridplot.pbayesdecisionprob2cont() - Plot method for
pbayesdecisionprob2cont objects; displays Go/NoGo/Gray
decision probabilities as a tile or scatter plot over a two-dimensional
treatment scenario gridplot.getgamma1bin() - Plot method for
getgamma1bin objects; displays calibration curves of
marginal Go and NoGo probabilities against the threshold grid for a
single binary endpointplot.getgamma1cont() - Plot method for
getgamma1cont objects; displays calibration curves of
marginal Go and NoGo probabilities against the threshold grid for a
single continuous endpointplot.getgamma2bin() - Plot method for
getgamma2bin objects; displays calibration curves of
marginal Go and NoGo probabilities against the threshold grid for two
binary endpointsplot.getgamma2cont() - Plot method for
getgamma2cont objects; displays calibration curves of
marginal Go and NoGo probabilities against the threshold grid for two
continuous endpointspbayespostpred1bin() - Posterior or predictive
probability for a single binary endpointpbayespostpred1cont() - Posterior or predictive
probability for a single continuous endpointpbayespostpred2bin() - Joint region probabilities for
two binary endpointspbayespostpred2cont() - Joint region probabilities for
two continuous endpointsgetgamma1bin() - Find optimal Go/NoGo thresholds for a
single binary endpoint by grid search over candidate gamma valuesgetgamma1cont() - Find optimal Go/NoGo thresholds for a
single continuous endpoint by grid search over candidate gamma
valuesgetgamma2bin() - Find optimal Go/NoGo thresholds for
two binary endpoints by grid search over candidate gamma value
pairsgetgamma2cont() - Find optimal Go/NoGo thresholds for
two continuous endpoints by grid search over candidate gamma value
pairsptdiff_NI() - CDF for the difference of two
t-distributions via numerical integrationptdiff_MC() - CDF for the difference of two
t-distributions via Monte Carlo simulationptdiff_MM() - CDF for the difference of two
t-distributions via Moment-Matching approximationpbetadiff() - CDF for the difference of two independent
Beta distributionspbetabinomdiff() - Beta-binomial posterior predictive
probabilityrdirichlet() - Random sampler for the Dirichlet
distributiongetjointbin() - Joint binary probability from marginals
and a correlation parameterallmultinom() - Enumerate all multinomial outcome
combinations