We extend the single-endpoint RA trial to a bivariate binary design with two co-primary binary endpoints:
The trial enrolls \(n_t = n_c = 7\) patients per group in a 1:1 randomised controlled design.
Clinically meaningful thresholds (posterior probability):
| Endpoint 1 | Endpoint 2 | |
|---|---|---|
| \(\theta_{\mathrm{TV}1}\) | 0.20 | 0.20 |
| \(\theta_{\mathrm{MAV}1}\) | 0.10 | 0.10 |
Null hypothesis thresholds (predictive probability): \(\theta_{\mathrm{NULL}1} = 0.15\), \(\theta_{\mathrm{NULL}2} = 0.15\).
Decision thresholds: \(\gamma_{\mathrm{go}} = 0.80\) (Go), \(\gamma_{\mathrm{nogo}} = 0.80\) (NoGo).
Observed data (used in Sections 2–4): treatment group counts for the four response patterns \((Y_{i,1}, Y_{i,2}) \in \{(0,0),(0,1),(1,0),(1,1)\}\):
| Pattern | Treatment (\(x_{t,lm}\)) | Control (\(x_{c,lm}\)) |
|---|---|---|
| (0, 0) | 1 | 2 |
| (0, 1) | 1 | 1 |
| (1, 0) | 2 | 2 |
| (1, 1) | 3 | 2 |
Marginal responder counts: treatment \(y_{t,1} = 5\), \(y_{t,2} = 4\); control \(y_{c,1} = 4\), \(y_{c,2} = 3\).
Because the two endpoints within each patient \(i\) (\(i = 1, \ldots, n_j\)) are correlated, the bivariate binary outcome \((Y_{i,1}, Y_{i,2})\) is modelled jointly through its four-cell probability vector
\[\mathbf{p}_j = (p_{j,00},\, p_{j,01},\, p_{j,10},\, p_{j,11})^\top, \qquad \mathbf{p}_j \in \Delta^3,\]
where \(j \in \{t, c\}\) denotes the treatment or control group, \(\Delta^3\) denotes the 3-simplex (all entries non-negative and summing to 1), and the subscripts refer to the values of \((Y_{i,1}, Y_{i,2})\).
The observed count vector \(\mathbf{x}_j = (x_{j,00}, x_{j,01}, x_{j,10}, x_{j,11})^\top\) with \(\sum_{lm} x_{j,lm} = n_j\) follows
\[\mathbf{x}_j \mid \mathbf{p}_j \;\sim\; \mathrm{Multinomial}(n_j,\, \mathbf{p}_j).\]
The marginal response rates and treatment effects are obtained by summing:
\[\pi_{j1} = p_{j,10} + p_{j,11}, \qquad \pi_{j2} = p_{j,01} + p_{j,11},\]
\[\theta_1 = \pi_{t1} - \pi_{c1}, \qquad \theta_2 = \pi_{t2} - \pi_{c2}.\]
The conjugate prior for \(\mathbf{p}_j\) is the Dirichlet distribution:
\[\mathbf{p}_j \;\sim\; \mathrm{Dir}(\alpha_{j,00},\, \alpha_{j,01},\, \alpha_{j,10},\, \alpha_{j,11}),\]
where all hyperparameters \(\alpha_{j,lm}
> 0\) (corresponding to a_t_00,
a_t_01, a_t_10, a_t_11 for \(j = t\) and a_c_00,
a_c_01, a_c_10, a_c_11 for \(j = c\)). The symmetric choice \(\alpha_{j,lm} = 0.25\) for all \(lm\) is the natural extension of the
Jeffreys prior to the four-cell multinomial and is used throughout this
vignette.
By conjugacy of the Dirichlet-Multinomial model, the posterior is:
\[\mathbf{p}_j \mid \mathbf{x}_j \;\sim\; \mathrm{Dir}(\alpha_{j,00}^*,\, \alpha_{j,01}^*,\, \alpha_{j,10}^*,\, \alpha_{j,11}^*),\]
where the posterior parameters are
\[\alpha_{j,lm}^* = \alpha_{j,lm} + x_{j,lm}, \qquad lm \in \{00, 01, 10, 11\}.\]
The posterior mean for each cell is \(E[p_{j,lm} \mid \mathbf{x}_j] = \alpha_{j,lm}^* / A_j^*\), where \(A_j^* = \sum_{lm} \alpha_{j,lm}^*\).
The within-group Pearson correlation between Endpoint 1 and Endpoint 2 is
\[\rho_j = \frac{p_{j,11} - \pi_{j1}\,\pi_{j2}} {\sqrt{\pi_{j1}(1-\pi_{j1})\,\pi_{j2}(1-\pi_{j2})}}.\]
When specifying operating characteristic scenarios, the true parameter vector \(\mathbf{p}_j\) is specified via the reparameterisation \((\pi_{j1}, \pi_{j2}, \rho_j)\), with the feasibility constraint:
\[\rho_{\min} = \frac{\max(0,\pi_{j1}+\pi_{j2}-1) - \pi_{j1}\pi_{j2}} {\sqrt{\pi_{j1}(1-\pi_{j1})\pi_{j2}(1-\pi_{j2})}} \;\le\; \rho_j \;\le\; \frac{\min(\pi_{j1},\pi_{j2}) - \pi_{j1}\pi_{j2}} {\sqrt{\pi_{j1}(1-\pi_{j1})\pi_{j2}(1-\pi_{j2})}} = \rho_{\max}.\]
The helper function getjointbin() converts \((\pi_{j1}, \pi_{j2}, \rho_j)\) to \((p_{j,00}, p_{j,01}, p_{j,10},
p_{j,11})\):
The bivariate threshold grid for \((\theta_1, \theta_2)\) creates a \(3 \times 3\) partition:
| Endpoint 1 | ||||
|---|---|---|---|---|
| θ1 > θTV1 | θTV1 ≥ θ1 > θMAV1 | θMAV1 ≥ θ1 | ||
| Endpoint 2 | θ2 > θTV2 | R1 | R4 | R7 |
| θTV2 ≥ θ2 > θMAV2 | R2 | R5 | R8 | |
| θMAV2 ≥ θ2 | R3 | R6 | R9 | |
Typical choices: Go if \(P(R_1) \ge \gamma_{\mathrm{go}}\), NoGo if \(P(R_9) \ge \gamma_{\mathrm{nogo}}\).
For the predictive probability, a \(2 \times 2\) partition is used:
| Endpoint 1 | |||
|---|---|---|---|
| θ1 > θNULL1 | θ1 ≤ θNULL1 | ||
| Endpoint 2 | θ2 > θNULL2 | R1 | R3 |
| θ2 ≤ θNULL2 | R2 | R4 | |
Let \(\tilde{\mathbf{x}}_j \sim
\mathrm{Multinomial}(m_j, \mathbf{p}_j)\) be the future count
vector with \(m_j\) future patients
(corresponding to m_t and m_c). Integrating
out \(\mathbf{p}_j\) over its Dirichlet
posterior gives the Dirichlet-Multinomial predictive distribution:
\[P(\tilde{\mathbf{x}}_j = \mathbf{c} \mid \mathbf{x}_j) = \binom{m_j}{\mathbf{c}} \frac{B(\boldsymbol{\alpha}_j^* + \mathbf{c})}{B(\boldsymbol{\alpha}_j^*)}, \quad \sum_{lm} c_{lm} = m_j,\]
where \(B(\cdot)\) is the multivariate Beta function and \(\binom{m_j}{\mathbf{c}} = m_j! / \prod_{lm} c_{lm}!\) is the multinomial coefficient.
Because the Dirichlet-Multinomial does not yield a tractable closed form for the joint probability that \((\tilde\theta_1, \tilde\theta_2)\) falls in a given region, all region probabilities are estimated by Monte Carlo:
\[\widehat{P}(R_r) = \frac{1}{n_\mathrm{MC}} \sum_{s=1}^{n_\mathrm{MC}} \mathbf{1}\!\left[(\pi_{t1}^{(s)} - \pi_{c1}^{(s)},\; \pi_{t2}^{(s)} - \pi_{c2}^{(s)}) \in R_r\right],\]
where \(\mathbf{p}_j^{(s)} \sim \mathrm{Dir}(\boldsymbol{\alpha}_j^*)\) are draws from the Dirichlet posterior and \(\pi_{j1}^{(s)} = p_{j,10}^{(s)} + p_{j,11}^{(s)}\), \(\pi_{j2}^{(s)} = p_{j,01}^{(s)} + p_{j,11}^{(s)}\). For the predictive probability, future proportion differences \(\tilde\theta_k^{(s)} = \tilde{\pi}_{t,k}^{(s)} - \tilde{\pi}_{c,k}^{(s)}\) are computed from corresponding Multinomial draws conditioned on the Dirichlet samples.
Both groups are observed in the PoC trial. The posterior parameters
are updated as \(\alpha_{j,lm}^* =
\alpha_{j,lm} + x_{j,lm}\), where \((x_{t,00}, x_{t,01}, x_{t,10}, x_{t,11})\)
and \((x_{c,00}, x_{c,01}, x_{c,10},
x_{c,11})\) are supplied as x_t_00, …,
x_t_11 and x_c_00, …, x_c_11.
set.seed(42)
p_post_ctrl <- pbayespostpred2bin(
prob = 'posterior', design = 'controlled',
theta_TV1 = 0.20, theta_MAV1 = 0.10,
theta_TV2 = 0.20, theta_MAV2 = 0.10,
theta_NULL1 = NULL, theta_NULL2 = NULL,
x_t_00 = 1L, x_t_01 = 1L, x_t_10 = 2L, x_t_11 = 3L,
x_c_00 = 2L, x_c_01 = 1L, x_c_10 = 2L, x_c_11 = 2L,
a_t_00 = 0.25, a_t_01 = 0.25, a_t_10 = 0.25, a_t_11 = 0.25,
a_c_00 = 0.25, a_c_01 = 0.25, a_c_10 = 0.25, a_c_11 = 0.25,
m_t = NULL, m_c = NULL,
z00 = NULL, z01 = NULL, z10 = NULL, z11 = NULL,
xe_t_00 = NULL, xe_t_01 = NULL, xe_t_10 = NULL, xe_t_11 = NULL,
xe_c_00 = NULL, xe_c_01 = NULL, xe_c_10 = NULL, xe_c_11 = NULL,
alpha0e_t = NULL, alpha0e_c = NULL,
nMC = 1000L
)
print(round(p_post_ctrl, 4))
#> R1 R2 R3 R4 R5 R6 R7 R8 R9
#> 0.174 0.075 0.133 0.075 0.025 0.083 0.149 0.069 0.217
cat(sprintf(
"\nGo region (R1): P = %.4f >= gamma_go (0.80)? %s\n",
p_post_ctrl["R1"], ifelse(p_post_ctrl["R1"] >= 0.80, "YES -> Go", "NO")
))
#>
#> Go region (R1): P = 0.1740 >= gamma_go (0.80)? NO
cat(sprintf(
"NoGo region (R9): P = %.4f >= gamma_nogo (0.80)? %s\n",
p_post_ctrl["R9"], ifelse(p_post_ctrl["R9"] >= 0.80, "YES -> NoGo", "NO")
))
#> NoGo region (R9): P = 0.2170 >= gamma_nogo (0.80)? NOPosterior predictive probability (future Phase III: \(m_t = m_c = 15\)):
set.seed(42)
p_pred_ctrl <- pbayespostpred2bin(
prob = 'predictive', design = 'controlled',
theta_TV1 = NULL, theta_MAV1 = NULL,
theta_TV2 = NULL, theta_MAV2 = NULL,
theta_NULL1 = 0.15, theta_NULL2 = 0.15,
x_t_00 = 1L, x_t_01 = 1L, x_t_10 = 2L, x_t_11 = 3L,
x_c_00 = 2L, x_c_01 = 1L, x_c_10 = 2L, x_c_11 = 2L,
a_t_00 = 0.25, a_t_01 = 0.25, a_t_10 = 0.25, a_t_11 = 0.25,
a_c_00 = 0.25, a_c_01 = 0.25, a_c_10 = 0.25, a_c_11 = 0.25,
m_t = 15L, m_c = 15L,
z00 = NULL, z01 = NULL, z10 = NULL, z11 = NULL,
xe_t_00 = NULL, xe_t_01 = NULL, xe_t_10 = NULL, xe_t_11 = NULL,
xe_c_00 = NULL, xe_c_01 = NULL, xe_c_10 = NULL, xe_c_11 = NULL,
alpha0e_t = NULL, alpha0e_c = NULL,
nMC = 1000L
)
print(round(p_pred_ctrl, 4))
#> R1 R2 R3 R4
#> 0.247 0.221 0.236 0.296
cat(sprintf(
"\nGo region (R1): P = %.4f >= gamma_go (0.80)? %s\n",
p_pred_ctrl["R1"], ifelse(p_pred_ctrl["R1"] >= 0.80, "YES -> Go", "NO")
))
#>
#> Go region (R1): P = 0.2470 >= gamma_go (0.80)? NOWhen no concurrent control group is enrolled, the control distribution is specified via a hypothetical count vector \(\mathbf{z} = (z_{00}, z_{01}, z_{10}, z_{11})\) combined with the Dirichlet prior:
\[\mathbf{p}_c \;\sim\; \mathrm{Dir}(\alpha_{c,00} + z_{00},\; \alpha_{c,01} + z_{01},\; \alpha_{c,10} + z_{10},\; \alpha_{c,11} + z_{11}).\]
This specification encodes prior belief about the bivariate control
response rates — including any assumed within-group correlation —
without requiring observed control data. The hypothetical counts are
supplied as z00, z01, z10,
z11.
set.seed(1)
p_unctrl <- pbayespostpred2bin(
prob = 'posterior', design = 'uncontrolled',
theta_TV1 = 0.20, theta_MAV1 = 0.10,
theta_TV2 = 0.20, theta_MAV2 = 0.10,
theta_NULL1 = NULL, theta_NULL2 = NULL,
x_t_00 = 1L, x_t_01 = 1L, x_t_10 = 2L, x_t_11 = 3L,
x_c_00 = NULL, x_c_01 = NULL, x_c_10 = NULL, x_c_11 = NULL,
a_t_00 = 0.25, a_t_01 = 0.25, a_t_10 = 0.25, a_t_11 = 0.25,
a_c_00 = 0.25, a_c_01 = 0.25, a_c_10 = 0.25, a_c_11 = 0.25,
m_t = NULL, m_c = NULL,
z00 = 2L, z01 = 1L, z10 = 2L, z11 = 1L,
xe_t_00 = NULL, xe_t_01 = NULL, xe_t_10 = NULL, xe_t_11 = NULL,
xe_c_00 = NULL, xe_c_01 = NULL, xe_c_10 = NULL, xe_c_11 = NULL,
alpha0e_t = NULL, alpha0e_c = NULL,
nMC = 1000L
)
print(round(p_unctrl, 4))
#> R1 R2 R3 R4 R5 R6 R7 R8 R9
#> 0.262 0.075 0.142 0.083 0.026 0.058 0.193 0.056 0.105External data for group \(j\) (count
vector \(\mathbf{x}_{ej}\), supplied as
xe_t_00, …, xe_t_11 for \(j = t\) and xe_c_00, …,
xe_c_11 for \(j = c\)) are
incorporated via a Dirichlet power prior with weight \(\alpha_{0e,j} \in (0, 1]\)
(alpha0e_t, alpha0e_c). The augmented prior
parameters are:
\[\alpha_{j,lm}^{*} = \alpha_{j,lm} + \alpha_{0e,j} \cdot x_{ej,lm}.\]
Setting \(\alpha_{0e,j} = 1\) treats the external data as equivalent to current trial data; \(\alpha_{0e,j} \to 0\) recovers the original prior. The current PoC data then update these augmented parameters:
\[\alpha_{j,lm}^{**} = \alpha_{j,lm}^{*} + x_{j,lm} = \alpha_{j,lm} + \alpha_{0e,j}\, x_{ej,lm} + x_{j,lm}.\]
When only the control group uses external data (external control
design), xe_t_00 through xe_t_11 and
alpha0e_t are set to NULL.
set.seed(2)
p_ext <- pbayespostpred2bin(
prob = 'posterior', design = 'external',
theta_TV1 = 0.20, theta_MAV1 = 0.10,
theta_TV2 = 0.20, theta_MAV2 = 0.10,
theta_NULL1 = NULL, theta_NULL2 = NULL,
x_t_00 = 1L, x_t_01 = 1L, x_t_10 = 2L, x_t_11 = 3L,
x_c_00 = 2L, x_c_01 = 1L, x_c_10 = 2L, x_c_11 = 2L,
a_t_00 = 0.25, a_t_01 = 0.25, a_t_10 = 0.25, a_t_11 = 0.25,
a_c_00 = 0.25, a_c_01 = 0.25, a_c_10 = 0.25, a_c_11 = 0.25,
m_t = NULL, m_c = NULL,
z00 = NULL, z01 = NULL, z10 = NULL, z11 = NULL,
xe_t_00 = NULL, xe_t_01 = NULL, xe_t_10 = NULL, xe_t_11 = NULL,
xe_c_00 = 3L, xe_c_01 = 1L, xe_c_10 = 2L, xe_c_11 = 1L,
alpha0e_t = NULL, alpha0e_c = 0.5,
nMC = 1000L
)
print(round(p_ext, 4))
#> R1 R2 R3 R4 R5 R6 R7 R8 R9
#> 0.215 0.072 0.151 0.087 0.036 0.078 0.151 0.075 0.135Sensitivity to borrowing weight \(\alpha_{0e,c}\):
ae_seq <- c(0.01, seq(0.1, 1.0, by = 0.1))
p_ae <- sapply(ae_seq, function(ae) {
set.seed(99)
res <- pbayespostpred2bin(
prob = 'posterior', design = 'external',
theta_TV1 = 0.20, theta_MAV1 = 0.10,
theta_TV2 = 0.20, theta_MAV2 = 0.10,
theta_NULL1 = NULL, theta_NULL2 = NULL,
x_t_00 = 1L, x_t_01 = 1L, x_t_10 = 2L, x_t_11 = 3L,
x_c_00 = 2L, x_c_01 = 1L, x_c_10 = 2L, x_c_11 = 2L,
a_t_00 = 0.25, a_t_01 = 0.25, a_t_10 = 0.25, a_t_11 = 0.25,
a_c_00 = 0.25, a_c_01 = 0.25, a_c_10 = 0.25, a_c_11 = 0.25,
m_t = NULL, m_c = NULL,
z00 = NULL, z01 = NULL, z10 = NULL, z11 = NULL,
xe_t_00 = NULL, xe_t_01 = NULL, xe_t_10 = NULL, xe_t_11 = NULL,
xe_c_00 = 3L, xe_c_01 = 1L, xe_c_10 = 2L, xe_c_11 = 1L,
alpha0e_t = NULL, alpha0e_c = ae, nMC = 500L
)
res["R1"]
})
data.frame(alpha0e_c = ae_seq, P_R1 = round(p_ae, 4))
#> alpha0e_c P_R1
#> 1 0.01 0.142
#> 2 0.10 0.164
#> 3 0.20 0.184
#> 4 0.30 0.180
#> 5 0.40 0.196
#> 6 0.50 0.208
#> 7 0.60 0.220
#> 8 0.70 0.246
#> 9 0.80 0.230
#> 10 0.90 0.228
#> 11 1.00 0.238For given true parameters \((\mathbf{p}_t, \mathbf{p}_c)\), the operating characteristics are computed by exact enumeration over all possible multinomial count combinations via a two-stage strategy.
Stage 1 (precomputation): all count combinations \(\mathbf{x}_{t,i}\) (\(K_t\) combinations) and \(\mathbf{x}_{c,j}\) (\(K_c\) combinations) are enumerated by
allmultinom(). For each pair \((i, j)\), pbayespostpred2bin()
computes the region probability vector once, yielding \(\hat{g}_{\mathrm{go},ij}\) and \(\hat{g}_{\mathrm{nogo},ij}\) independent of
any decision threshold.
Stage 2 (weighting): for given thresholds \((\gamma_{\mathrm{go}}, \gamma_{\mathrm{nogo}})\):
\[\Pr(\mathrm{Go}) = \sum_{i=1}^{K_t} \sum_{j=1}^{K_c} w_{ij}\, \mathbf{1}\!\left[\hat{g}_{\mathrm{go},ij} \ge \gamma_{\mathrm{go}} \text{ and } \hat{g}_{\mathrm{nogo},ij} < \gamma_{\mathrm{nogo}}\right],\]
\[\Pr(\mathrm{NoGo}) = \sum_{i=1}^{K_t} \sum_{j=1}^{K_c} w_{ij}\, \mathbf{1}\!\left[\hat{g}_{\mathrm{nogo},ij} \ge \gamma_{\mathrm{nogo}} \text{ and } \hat{g}_{\mathrm{go},ij} < \gamma_{\mathrm{go}}\right],\]
where \(w_{ij} = P_\mathrm{Mult}(\mathbf{x}_{t,i};\, n_t, \mathbf{p}_t) \times P_\mathrm{Mult}(\mathbf{x}_{c,j};\, n_c, \mathbf{p}_c)\), and
\[\hat{g}_{\mathrm{go},ij} = \sum_{r \in \text{GoRegions}} \hat{P}(R_r \mid \mathbf{x}_{t,i}, \mathbf{x}_{c,j}),\] \[\hat{g}_{\mathrm{nogo},ij} = \sum_{r \in \text{NoGoRegions}} \hat{P}(R_r \mid \mathbf{x}_{t,i}, \mathbf{x}_{c,j}).\]
A Miss (\(\hat{g}_{\mathrm{go},ij} \ge
\gamma_{\mathrm{go}}\) AND \(\hat{g}_{\mathrm{nogo},ij} \ge
\gamma_{\mathrm{nogo}}\)) indicates an inconsistent threshold
configuration and triggers an error by default
(error_if_Miss = TRUE). Gray comprises all remaining
outcomes.
For large \(n_t\) or \(n_c\), the CalcMethod = 'MC'
option replaces full enumeration with \(n_\mathrm{sim}\) multinomial draws,
deduplicates them into \(K \ll
n_\mathrm{sim}\) unique pairs, and evaluates
pbayespostpred2bin() only for those unique pairs.
Note on computation time. The number of multinomial count combinations grows rapidly with \(n\): for \(n_j\) patients and 4 response categories the number of combinations is \(\binom{n_j + 3}{3}\), which equals 286 for \(n_j = 10\) and 1771 for \(n_j = 20\). For the Exact method with two groups this means up to \(286^2 \approx 82{,}000\) unique pairs each requiring
nMCDirichlet draws. When predictive probability is used (\(m_j > 0\)), an additional layer of Multinomial sampling is added inside each Dirichlet draw, further multiplying computation time. Use smallnMC(100–500) andn_t = n_c = 10for demonstration; switch toCalcMethod = 'MC'with moderatensimfor larger sample sizes.
pi_t_seq <- seq(0.20, 0.90, by = 0.10)
n_scen <- length(pi_t_seq)
oc_ctrl <- pbayesdecisionprob2bin(
prob = 'posterior', design = 'controlled',
GoRegions = 1L, NoGoRegions = 9L,
gamma_go = 0.80, gamma_nogo = 0.80,
pi_t1 = rep(pi_t_seq, each = n_scen),
pi_t2 = rep(pi_t_seq, times = n_scen),
rho_t = rep(0.0, n_scen * n_scen),
pi_c1 = rep(0.20, n_scen * n_scen),
pi_c2 = rep(0.20, n_scen * n_scen),
rho_c = rep(0.0, n_scen * n_scen),
n_t = 7L, n_c = 7L,
a_t_00 = 0.25, a_t_01 = 0.25, a_t_10 = 0.25, a_t_11 = 0.25,
a_c_00 = 0.25, a_c_01 = 0.25, a_c_10 = 0.25, a_c_11 = 0.25,
m_t = NULL, m_c = NULL,
theta_TV1 = 0.20, theta_MAV1 = 0.10,
theta_TV2 = 0.20, theta_MAV2 = 0.10,
theta_NULL1 = NULL, theta_NULL2 = NULL,
z00 = NULL, z01 = NULL, z10 = NULL, z11 = NULL,
xe_t_00 = NULL, xe_t_01 = NULL, xe_t_10 = NULL, xe_t_11 = NULL,
xe_c_00 = NULL, xe_c_01 = NULL, xe_c_10 = NULL, xe_c_11 = NULL,
alpha0e_t = NULL, alpha0e_c = NULL,
nMC = 200L, CalcMethod = 'Exact',
error_if_Miss = TRUE, Gray_inc_Miss = FALSE
)
print(oc_ctrl)
#> Go/NoGo/Gray Decision Probabilities (Two Binary Endpoints)
#> -----------------------------------------------------------------------------
#> Probability type : posterior
#> Design : controlled
#> Threshold(s) : TV1 = 0.2, MAV1 = 0.1
#> TV2 = 0.2, MAV2 = 0.1
#> Go threshold : gamma_go = 0.8
#> NoGo threshold : gamma_nogo = 0.8
#> Go regions : {1}
#> NoGo regions : {9}
#> Sample size : n_t = 7, n_c = 7
#> Prior (treatment): a_t = (0.25, 0.25, 0.25, 0.25) [a_00, a_01, a_10, a_11]
#> Prior (control) : a_c = (0.25, 0.25, 0.25, 0.25) [a_00, a_01, a_10, a_11]
#> Method : Exact
#> MC draws : nMC = 200
#> Miss handling : error_if_Miss = TRUE, Gray_inc_Miss = FALSE
#> -----------------------------------------------------------------------------
#> pi_t1 pi_t2 rho_t pi_c1 pi_c2 rho_c Go Gray NoGo
#> 0.2 0.2 0 0.2 0.2 0 0.0002 0.8886 0.1112
#> 0.2 0.3 0 0.2 0.2 0 0.0008 0.9381 0.0611
#> 0.2 0.4 0 0.2 0.2 0 0.0021 0.9666 0.0313
#> 0.2 0.5 0 0.2 0.2 0 0.0045 0.9810 0.0145
#> 0.2 0.6 0 0.2 0.2 0 0.0082 0.9859 0.0059
#> 0.2 0.7 0 0.2 0.2 0 0.0136 0.9845 0.0019
#> 0.2 0.8 0 0.2 0.2 0 0.0205 0.9791 0.0004
#> 0.2 0.9 0 0.2 0.2 0 0.0290 0.9710 0.0000
#> 0.3 0.2 0 0.2 0.2 0 0.0009 0.9380 0.0611
#> 0.3 0.3 0 0.2 0.2 0 0.0031 0.9637 0.0332
#> 0.3 0.4 0 0.2 0.2 0 0.0076 0.9756 0.0168
#> 0.3 0.5 0 0.2 0.2 0 0.0151 0.9772 0.0077
#> 0.3 0.6 0 0.2 0.2 0 0.0262 0.9707 0.0030
#> 0.3 0.7 0 0.2 0.2 0 0.0415 0.9575 0.0010
#> 0.3 0.8 0 0.2 0.2 0 0.0610 0.9388 0.0002
#> 0.3 0.9 0 0.2 0.2 0 0.0848 0.9152 0.0000
#> 0.4 0.2 0 0.2 0.2 0 0.0024 0.9670 0.0306
#> 0.4 0.3 0 0.2 0.2 0 0.0080 0.9755 0.0165
#> 0.4 0.4 0 0.2 0.2 0 0.0186 0.9732 0.0082
#> 0.4 0.5 0 0.2 0.2 0 0.0352 0.9611 0.0037
#> 0.4 0.6 0 0.2 0.2 0 0.0586 0.9400 0.0014
#> 0.4 0.7 0 0.2 0.2 0 0.0892 0.9104 0.0005
#> 0.4 0.8 0 0.2 0.2 0 0.1272 0.8728 0.0000
#> 0.4 0.9 0 0.2 0.2 0 0.1728 0.8272 0.0000
#> 0.5 0.2 0 0.2 0.2 0 0.0053 0.9811 0.0136
#> 0.5 0.3 0 0.2 0.2 0 0.0167 0.9761 0.0073
#> 0.5 0.4 0 0.2 0.2 0 0.0368 0.9596 0.0036
#> 0.5 0.5 0 0.2 0.2 0 0.0667 0.9317 0.0016
#> 0.5 0.6 0 0.2 0.2 0 0.1070 0.8924 0.0006
#> 0.5 0.7 0 0.2 0.2 0 0.1574 0.8424 0.0002
#> 0.5 0.8 0 0.2 0.2 0 0.2176 0.7824 0.0000
#> 0.5 0.9 0 0.2 0.2 0 0.2876 0.7124 0.0000
#> 0.6 0.2 0 0.2 0.2 0 0.0098 0.9850 0.0051
#> 0.6 0.3 0 0.2 0.2 0 0.0296 0.9677 0.0027
#> 0.6 0.4 0 0.2 0.2 0 0.0628 0.9359 0.0013
#> 0.6 0.5 0 0.2 0.2 0 0.1101 0.8894 0.0006
#> 0.6 0.6 0 0.2 0.2 0 0.1709 0.8289 0.0002
#> 0.6 0.7 0 0.2 0.2 0 0.2440 0.7560 0.0000
#> 0.6 0.8 0 0.2 0.2 0 0.3274 0.6726 0.0000
#> 0.6 0.9 0 0.2 0.2 0 0.4198 0.5802 0.0000
#> 0.7 0.2 0 0.2 0.2 0 0.0161 0.9824 0.0016
#> 0.7 0.3 0 0.2 0.2 0 0.0466 0.9526 0.0008
#> 0.7 0.4 0 0.2 0.2 0 0.0958 0.9038 0.0004
#> 0.7 0.5 0 0.2 0.2 0 0.1632 0.8366 0.0002
#> 0.7 0.6 0 0.2 0.2 0 0.2470 0.7530 0.0000
#> 0.7 0.7 0 0.2 0.2 0 0.3437 0.6563 0.0000
#> 0.7 0.8 0 0.2 0.2 0 0.4488 0.5512 0.0000
#> 0.7 0.9 0 0.2 0.2 0 0.5577 0.4423 0.0000
#> 0.8 0.2 0 0.2 0.2 0 0.0235 0.9762 0.0003
#> 0.8 0.3 0 0.2 0.2 0 0.0663 0.9335 0.0002
#> 0.8 0.4 0 0.2 0.2 0 0.1331 0.8669 0.0000
#> 0.8 0.5 0 0.2 0.2 0 0.2221 0.7779 0.0000
#> 0.8 0.6 0 0.2 0.2 0 0.3295 0.6705 0.0000
#> 0.8 0.7 0 0.2 0.2 0 0.4491 0.5509 0.0000
#> 0.8 0.8 0 0.2 0.2 0 0.5724 0.4276 0.0000
#> 0.8 0.9 0 0.2 0.2 0 0.6897 0.3103 0.0000
#> 0.9 0.2 0 0.2 0.2 0 0.0310 0.9690 0.0000
#> 0.9 0.3 0 0.2 0.2 0 0.0861 0.9139 0.0000
#> 0.9 0.4 0 0.2 0.2 0 0.1702 0.8298 0.0000
#> 0.9 0.5 0 0.2 0.2 0 0.2804 0.7196 0.0000
#> 0.9 0.6 0 0.2 0.2 0 0.4108 0.5892 0.0000
#> 0.9 0.7 0 0.2 0.2 0 0.5518 0.4482 0.0000
#> 0.9 0.8 0 0.2 0.2 0 0.6892 0.3108 0.0000
#> 0.9 0.9 0 0.2 0.2 0 0.8073 0.1927 0.0000
#> -----------------------------------------------------------------------------
plot(oc_ctrl, base_size = 20)The same function supports design = 'uncontrolled' (with
hypothetical count vector arguments z00, z01,
z10, z11), design = 'external'
(with power prior arguments xe_c_00, …,
xe_c_11 and alpha0e_c), and
prob = 'predictive' (with future sample size arguments
m_t, m_c and theta_NULL1,
theta_NULL2). The within-group correlation
rho_t can also be varied to study its effect on the
operating characteristics. The function signature and output format are
identical across all combinations.
getgamma2bin() finds the optimal pair \((\gamma_{\mathrm{go}}^*,
\gamma_{\mathrm{nogo}}^*)\) by the same two-stage
precompute-then-sweep strategy as pbayesdecisionprob2bin(),
but sweeps over the two-dimensional grid \(\Gamma_{\mathrm{go}} \times
\Gamma_{\mathrm{nogo}}\) (gamma_go_grid \(\times\) gamma_nogo_grid). The
two thresholds are calibrated independently under separate
scenarios:
pi_t1_go,
pi_t2_go, rho_t_go, pi_c1_go,
pi_c2_go, rho_c_go; typically the null
scenario \(\pi_t = \pi_c\)), so that
\(\Pr(\mathrm{Go}) <
\texttt{target_go}\).pi_t1_nogo,
pi_t2_nogo, rho_t_nogo,
pi_c1_nogo, pi_c2_nogo,
rho_c_nogo; typically the alternative scenario), so that
\(\Pr(\mathrm{NoGo}) <
\texttt{target_nogo}\).Stage 1 (precomputation): pbayespostpred2bin() is called
for every unique multinomial outcome combination \((\mathbf{x}_{t,i}, \mathbf{x}_{c,j})\)
enumerated by allmultinom(). The region probability vector
is summed over GoRegions and NoGoRegions to
obtain \(\hat{g}_{\mathrm{go},ij}\) and
\(\hat{g}_{\mathrm{nogo},ij}\),
independent of \((\gamma_{\mathrm{go}},
\gamma_{\mathrm{nogo}})\).
Stage 2 (gamma sweep): for every pair \((\gamma_{\mathrm{go}}, \gamma_{\mathrm{nogo}}) \in \Gamma_{\mathrm{go}} \times \Gamma_{\mathrm{nogo}}\):
\[\Pr(\mathrm{Go} \mid \gamma_{\mathrm{go}}, \gamma_{\mathrm{nogo}}) = \sum_{i,j} w_{ij}\, \mathbf{1}\!\left[\hat{g}_{\mathrm{go},ij} \ge \gamma_{\mathrm{go}} \text{ and } \hat{g}_{\mathrm{nogo},ij} < \gamma_{\mathrm{nogo}}\right],\]
\[\Pr(\mathrm{NoGo} \mid \gamma_{\mathrm{go}}, \gamma_{\mathrm{nogo}}) = \sum_{i,j} w_{ij}\, \mathbf{1}\!\left[\hat{g}_{\mathrm{nogo},ij} \ge \gamma_{\mathrm{nogo}} \text{ and } \hat{g}_{\mathrm{go},ij} < \gamma_{\mathrm{go}}\right].\]
Results are stored in \(|\Gamma_{\mathrm{go}}| \times
|\Gamma_{\mathrm{nogo}}|\) matrices PrGo_grid and
PrNoGo_grid.
Stage 3 (optimal selection): for each candidate \(\gamma_{\mathrm{go}}\), the worst-case
\(\Pr(\mathrm{Go})\) over all \(\gamma_{\mathrm{nogo}}\) is compared
against target_go; analogously for \(\gamma_{\mathrm{nogo}}\).
Null scenario: \(\pi_{t1} = \pi_{c1} = 0.20\), \(\pi_{t2} = \pi_{c2} = 0.20\), \(\rho_t = \rho_c = 0\) (no treatment effect, independence).
res_gamma <- getgamma2bin(
prob = 'posterior', design = 'controlled',
GoRegions = 1L, NoGoRegions = 9L,
pi_t1_go = 0.20, pi_t2_go = 0.20, rho_t_go = 0.0,
pi_c1_go = 0.20, pi_c2_go = 0.20, rho_c_go = 0.0,
pi_t1_nogo = 0.40, pi_t2_nogo = 0.40, rho_t_nogo = 0.0,
pi_c1_nogo = 0.20, pi_c2_nogo = 0.20, rho_c_nogo = 0.0,
target_go = 0.05, target_nogo = 0.20,
n_t = 7L, n_c = 7L,
a_t_00 = 0.25, a_t_01 = 0.25, a_t_10 = 0.25, a_t_11 = 0.25,
a_c_00 = 0.25, a_c_01 = 0.25, a_c_10 = 0.25, a_c_11 = 0.25,
theta_TV1 = 0.20, theta_MAV1 = 0.10,
theta_TV2 = 0.20, theta_MAV2 = 0.10,
theta_NULL1 = NULL, theta_NULL2 = NULL,
m_t = NULL, m_c = NULL,
z00 = NULL, z01 = NULL, z10 = NULL, z11 = NULL,
xe_t_00 = NULL, xe_t_01 = NULL, xe_t_10 = NULL, xe_t_11 = NULL,
xe_c_00 = NULL, xe_c_01 = NULL, xe_c_10 = NULL, xe_c_11 = NULL,
alpha0e_t = NULL, alpha0e_c = NULL,
nMC = 200L,
gamma_go_grid = seq(0.05, 0.95, by = 0.05),
gamma_nogo_grid = seq(0.05, 0.95, by = 0.05)
)
plot(res_gamma, base_size = 20)The same function supports design = 'uncontrolled' (with
pi_t1_go, pi_t2_go, rho_t_go,
pi_t1_nogo, pi_t2_nogo,
rho_t_nogo; set pi_c*_go and
pi_c*_nogo to NULL),
design = 'external' (with power prior arguments), and
prob = 'predictive' (with theta_NULL1,
theta_NULL2, m_t, and m_c). The
calibration plot and the returned
gamma_go/gamma_nogo values are available for
all combinations.
This vignette covered two binary endpoint analysis in BayesianQDM:
getjointbin().allmultinom(), with
multinomial probability weighting (no outer Monte Carlo needed for small
\(n\)).getgamma2bin(), producing \(|\Gamma_{\mathrm{go}}| \times
|\Gamma_{\mathrm{nogo}}|\) matrices PrGo_grid and
PrNoGo_grid, visualised as contour plots.See vignette("overview") for a comparison across all
four endpoint types.