Skip to contents

Version 1.0.0 of BayesianQDM is a redesign of version 0.1.0 and is not backward compatible. In version 0.1.0, each combination of endpoint and operation had its own function with up to about 50 arguments. In version 1.0.0, a study is described by small specification objects that are combined into a design, and three functions work with any design. This vignette shows how to translate code written for version 0.1.0 and lists the changes in the results. The code for version 0.1.0 is shown but not run.

Correspondence of the functions

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()
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()
rdirichlet() Same name
allmultinom() Internal function

Correspondence of the arguments

Version 0.1.0 Version 1.0.0
prob = 'posterior' with theta_TV, theta_MAV, gamma_go, gamma_nogo criterion_posterior(theta_tv, theta_mav, gamma_go, gamma_nogo)
prob = 'predictive' with theta_NULL, m_t, m_c criterion_predictive(theta_null, m_t, m_c, gamma_go, gamma_nogo)
a_t, b_t, a_c, b_c prior_beta(a, b) for each group
prior = 'vague' prior_vague()
prior = 'N-Inv-Chisq' with mu0_*, kappa0_*, nu0_*, sigma0_* prior_nix(mu0, kappa0, nu0, sigma0) for each group
CalcMethod method of design_continuous() and design_continuous2()
design = 'controlled' n_c of at least 1 (binary endpoints), 2 (one continuous endpoint) or 3 (two continuous endpoints)
design = 'external' with ne_*, ye_* (or bar_ye_*, se_*) and alpha0e_* borrow(data_*(...), a0) as external_t or external_c
design = 'uncontrolled' with z (binary) or mu0_c and r (continuous) n_c = 0 and hypothetical_c = hypothetical(...)
pi_t, pi_c and similar vectors of true parameters A data frame of scenarios
error_if_Miss, Gray_inc_Miss Removed; Miss decisions are reported in their own column
col_go, col_nogo, col_gray and base_size of the plot() methods Same names, with col_miss, linewidth, point_size, label_size and legend_position where they apply; base_size is 11 by default instead of 28
title, xlab and ylab of the plot() methods ggplot2::labs() added to the plot
which of the plot() methods for two endpoints One panel per decision by default; overlay = TRUE for which = "overlay"

The meaning of gamma_nogo is unchanged: the NoGo criterion is Pr⁡(θ≤θMAV∣D)≥γnogo\Pr(\theta \le \theta_{MAV} \mid D) \ge \gamma_{nogo}.

Posterior probability for observed data

Version 0.1.0:

pbayespostpred1bin(
  prob = 'posterior', design = 'controlled', theta0 = 0.05,
  n_t = 10, n_c = 10, y_t = 7, y_c = 3,
  a_t = 0.5, b_t = 0.5, a_c = 0.5, b_c = 0.5,
  m_t = NULL, m_c = NULL, z = NULL,
  ne_t = NULL, ne_c = NULL, ye_t = NULL, ye_c = NULL,
  alpha0e_t = NULL, alpha0e_c = NULL,
  lower.tail = FALSE
)

Version 1.0.0 computes the probability directly from the posterior distributions Beta(7.5,3.5)\textrm{Beta}(7.5, 3.5) and Beta(3.5,7.5)\textrm{Beta}(3.5, 7.5), or as the probability of the Go region of a design whose target value is 0.05:

pbetadiff(0.05, a_t = 7.5, b_t = 3.5, a_c = 3.5, b_c = 7.5,
          lower.tail = FALSE)
#> [1] 0.941619

des <- design_binary(
  n_t = 10, n_c = 10,
  prior_t = prior_beta(0.5, 0.5), prior_c = prior_beta(0.5, 0.5),
  criterion = criterion_posterior(theta_tv = 0.05, theta_mav = 0,
                                  gamma_go = 0.8, gamma_nogo = 0.8)
)
qdm_decide(des, data_t = data_binary(10, 7), data_c = data_binary(10, 3))
#> Decision: Go
#>   Go:   P(theta > 0.05 | data) = 0.9416 (threshold 0.8, met)
#>   NoGo: P(theta <= 0 | data) = 0.03567 (threshold 0.8, not met)
#> Posterior distributions
#>   Treatment: Beta(a = 7.5, b = 3.5)
#>   Control:   Beta(a = 3.5, b = 7.5)

Operating characteristics

Version 0.1.0:

pbayesdecisionprob1bin(
  prob = 'posterior', design = 'controlled',
  theta_TV = 0.30, theta_MAV = 0.10, theta_NULL = NULL,
  gamma_go = 0.80, gamma_nogo = 0.20,
  pi_t = seq(0.15, 0.9, l = 10), pi_c = rep(0.15, 10),
  n_t = 10, n_c = 10,
  a_t = 0.5, b_t = 0.5, a_c = 0.5, b_c = 0.5,
  z = NULL, m_t = NULL, m_c = NULL,
  ne_t = NULL, ne_c = NULL, ye_t = NULL, ye_c = NULL,
  alpha0e_t = NULL, alpha0e_c = NULL
)

Version 1.0.0:

des <- design_binary(
  n_t = 10, n_c = 10,
  prior_t = prior_beta(0.5, 0.5), prior_c = prior_beta(0.5, 0.5),
  criterion = criterion_posterior(theta_tv = 0.30, theta_mav = 0.10,
                                  gamma_go = 0.80, gamma_nogo = 0.20)
)
oc <- qdm_oc(des, data.frame(pi_t = seq(0.15, 0.9, length.out = 10),
                             pi_c = 0.15))
oc
#> Operating characteristics (exact enumeration of the outcomes)
#>    pi_t pi_c       Go     NoGo    Gray Miss
#>  0.1500 0.15 0.002463 0.944331 0.05321    0
#>  0.2333 0.15 0.017369 0.833220 0.14941    0
#>  0.3167 0.15 0.060942 0.674407 0.26465    0
#>  0.4000 0.15 0.146761 0.496338 0.35690    0
#>  0.4833 0.15 0.277721 0.328306 0.39397    0
#>  0.5667 0.15 0.442619 0.191543 0.36584    0
#>  0.6500 0.15 0.618562 0.095484 0.28595    0
#>  0.7333 0.15 0.778091 0.038434 0.18347    0
#>  0.8167 0.15 0.898385 0.011172 0.09044    0
#>  0.9000 0.15 0.969265 0.001785 0.02895    0

Calibration of the thresholds

Version 0.1.0:

getgamma1bin(
  prob = 'posterior', design = 'controlled',
  theta_TV = 0.30, theta_MAV = 0.10, theta_NULL = NULL,
  pi_t_go = 0.15, pi_c_go = 0.15, pi_t_nogo = 0.35, pi_c_nogo = 0.15,
  target_go = 0.05, target_nogo = 0.20,
  n_t = 12L, n_c = 12L,
  a_t = 0.5, b_t = 0.5, a_c = 0.5, b_c = 0.5,
  z = NULL, m_t = NULL, m_c = NULL,
  ne_t = NULL, ne_c = NULL, ye_t = NULL, ye_c = NULL,
  alpha0e_t = NULL, alpha0e_c = NULL
)

Version 1.0.0 (the thresholds of the design are replaced by the calibrated ones):

des12 <- design_binary(
  n_t = 12, n_c = 12,
  prior_t = prior_beta(0.5, 0.5), prior_c = prior_beta(0.5, 0.5),
  criterion = criterion_posterior(theta_tv = 0.30, theta_mav = 0.10,
                                  gamma_go = 0.80, gamma_nogo = 0.20)
)
cal <- qdm_calibrate(des12,
                     scenario_go = data.frame(pi_t = 0.15, pi_c = 0.15),
                     scenario_nogo = data.frame(pi_t = 0.35, pi_c = 0.15),
                     target_go = 0.05, target_nogo = 0.20)
cal
#> Calibration of the decision thresholds (exact enumeration of the outcomes)
#>   gamma_go   = 0.29: P(Go criterion met | scenario_go) = 0.04873 (target 0.05)
#>   gamma_nogo = 0.59: P(NoGo criterion met | scenario_nogo) = 0.182 (target 0.2)
#> Decision probabilities with the chosen thresholds
#>       scenario pi_t pi_c      Go   NoGo   Gray Miss
#>    scenario_go 0.15 0.15 0.04873 0.6584 0.2929    0
#>  scenario_nogo 0.35 0.15 0.45442 0.1820 0.3636    0

Version 0.1.0 required the probabilities to be less than the targets; version 1.0.0 requires them to be at most the targets.

External data and hypothetical controls

External data given in version 0.1.0 by ne_c = 20, ye_c = 5, alpha0e_c = 0.5 are given in version 1.0.0 by external_c = borrow(data_binary(n = 20, y = 5), a0 = 0.5). For a continuous endpoint, ne_c, bar_ye_c, se_c and alpha0e_c become borrow(data_continuous(n, mean, sd), a0).

The uncontrolled design of version 0.1.0 with z hypothetical responders among n_c control subjects and control prior Beta(ac,bc)\textrm{Beta}(a_c, b_c) corresponds to n_c = 0, prior_c = prior_beta(a_c, b_c) and hypothetical_c = hypothetical(data = data_binary(n_c, z)); for example:

design_binary(
  n_t = 12, n_c = 0,
  prior_t = prior_beta(0.5, 0.5), prior_c = prior_beta(0.5, 0.5),
  criterion = criterion_posterior(theta_tv = 0.30, theta_mav = 0.10,
                                  gamma_go = 0.80, gamma_nogo = 0.20),
  hypothetical_c = hypothetical(data = data_binary(n = 12, y = 2))
)
#> Design: one binary endpoint
#>   Treatment: n = 12, prior Beta(a = 0.5, b = 0.5)
#>   Control: hypothetical, prior Beta(a = 0.5, b = 0.5)
#>     Hypothetical control: data (binary, n = 12, y = 2)
#> Posterior probability criterion
#>   Go:   P(theta > 0.3 | data) >= 0.8
#>   NoGo: P(theta <= 0.1 | data) >= 0.2

For a continuous endpoint, mu0_c and r become hypothetical(mean = mu0_c, r = r).

Changes in the results

Formulas and numerical methods that were wrong in version 0.1.0 have been corrected, so some results differ.

  • The posterior predictive distribution of the mean of mm future subjects of a continuous endpoint has the squared scale σn2(1/κn+1/m)\sigma_n^2 (1 / \kappa_n + 1 / m) (one endpoint) and the scale matrix (1/κn+1/m)Λn/(νn−1)(1 / \kappa_n + 1 / m) \Lambda_n / (\nu_n - 1) (two endpoints). Version 0.1.0 treated the future subjects as independent draws from the predictive distribution of one subject, which understates the uncertainty.
  • With the vague prior and external data for a continuous endpoint, the posterior distribution of the mean has a0ne+n−1a_0 n_e + n - 1 degrees of freedom, and its scale uses the same denominator (version 0.1.0 used a0ne+na_0 n_e + n).
  • For two binary endpoints, the predictive probabilities are computed exactly instead of by Monte Carlo simulation.
  • For two continuous endpoints, the moment-matching approximation uses the real degrees of freedom (version 0.1.0 rounded them to an integer), and with Monte Carlo simulation each simulated study has its own draws (version 0.1.0 used the same draws for all simulated studies).
  • Numerical integration for one continuous endpoint covers the whole real line (version 0.1.0 truncated the range).
  • Probabilities are no longer set to 0 below .Machine$double.eps^0.25.
  • Miss decisions (both criteria met) are reported in their own column with a warning, instead of an error or being counted as Gray.
  • qdm_decide(), qdm_oc(), qdm_calibrate() and qdm_boundary() have a seed argument and restore the state of the random number generator when a seed is given.

Version 1.0.0 also has features without a counterpart in version 0.1.0: a fixed control (fixed_c of the design functions) for single-arm studies compared with a known value, smaller effects as favorable (direction of the criterion functions), one time-to-event endpoint evaluated by the milestone survival or the hazard ratio (design_tte(), see vignette("time-to-event")) and decision boundaries (qdm_boundary()). NEWS.md lists all changes.