This vignette describes the analysis of a proof-of-concept (PoC)
study with one normally distributed endpoint.
vignette("overview") introduces the decision criteria.
In group \(k\) (\(k = t, c\)), the outcomes follow \(N(\mu_k, \sigma_k^2)\), and the data are
summarized by the number of subjects \(n_k\), the sample mean \(\bar y_k\) and the sample standard
deviation \(s_k\)
(data_continuous()). The treatment effect is \(\theta = \mu_t - \mu_c\).
With the Normal-Inverse-chi-squared prior (prior_nix()),
\[\mu_k \mid \sigma_k^2 \sim N(\mu_0,
\sigma_k^2 / \kappa_0), \qquad
\sigma_k^2 \sim \textrm{Inv-}\chi^2(\nu_0, \sigma_0^2),\] the
posterior distribution has the same form with parameters \(\kappa_n = \kappa_0 + n\), \(\mu_n = (\kappa_0 \mu_0 + n \bar y) /
\kappa_n\), \(\nu_n = \nu_0 +
n\) and \(\nu_n \sigma_n^2 = \nu_0
\sigma_0^2 + (n - 1) s^2 +
\kappa_0 n (\bar y - \mu_0)^2 / \kappa_n\), and the posterior
distribution of the mean is the t distribution \(t_{\nu_n}(\mu_n, \sigma_n^2 / \kappa_n)\).
With the vague prior \(p(\mu, \sigma^2)
\propto \sigma^{-2}\) (prior_vague()), it is \(t_{n - 1}(\bar y, s^2 / n)\).
For the predictive criterion, the mean of \(m\) future subjects of a group has the posterior predictive distribution \[t_{\nu_n}\left(\mu_n, \; \sigma_n^2 \left(\frac{1}{\kappa_n} + \frac{1}{m}\right)\right).\] Version 0.1.0 of the package 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.
The posterior and predictive probabilities of the Go and NoGo regions
are probabilities of the difference of two t variables, computed by
ptdiff() with one of three methods (argument
method of design_continuous()):
"NI" (the default): numerical integration over the
whole real line, exact up to a small numerical error;"MM": the moment-matching approximation of the
difference by a single t distribution (Yamaguchi, Homma, Takeda and
Maruo, submitted), which requires more than 4 degrees of freedom in both
groups;"MC": Monte Carlo simulation with nMC
draws.A study with 12 subjects in each group and vague priors, with \(\theta_{TV} = 15\) and \(\theta_{MAV} = 5\):
crit <- criterion_posterior(theta_tv = 15, theta_mav = 5,
gamma_go = 0.6, gamma_nogo = 0.7)
des <- design_continuous(n_t = 12, n_c = 12, prior_t = prior_vague(),
prior_c = prior_vague(), criterion = crit)
dec <- qdm_decide(des, data_t = data_continuous(n = 12, mean = 22, sd = 25),
data_c = data_continuous(n = 12, mean = 2, sd = 25))
dec
#> Decision: Go
#> Go: P(theta > 15 | data) = 0.6778 (threshold 0.6, met)
#> NoGo: P(theta <= 5 | data) = 0.08784 (threshold 0.7, not met)
#> Posterior distributions
#> Treatment: mean ~ t(df = 11, location = 22, scale = 7.217)
#> Control: mean ~ t(df = 11, location = 2, scale = 7.217)The posterior distribution of each mean is \(t_{11}(\bar y, s^2 / 12)\). The three
methods of ptdiff() give similar probabilities of the Go
region:
post_t <- dec$posterior_t
post_c <- dec$posterior_c
scale_t <- post_t[["sigma"]] / sqrt(post_t[["kappa"]])
scale_c <- post_c[["sigma"]] / sqrt(post_c[["kappa"]])
set.seed(1)
sapply(c("NI", "MM", "MC"), function(m) {
ptdiff(15, mu_t = post_t[["mu"]], scale_t = scale_t, df_t = post_t[["nu"]],
mu_c = post_c[["mu"]], scale_c = scale_c, df_c = post_c[["nu"]],
method = m, lower.tail = FALSE)
})
#> NI MM MC
#> 0.6777935 0.6780038 0.6791000An informative Normal-Inverse-chi-squared prior is given by its parameters; for example, a control prior centered at 0 with the weight of 2 subjects for the mean and 4 degrees of freedom for the variance:
des_nix <- design_continuous(
n_t = 12, n_c = 12, prior_t = prior_vague(),
prior_c = prior_nix(mu0 = 0, kappa0 = 2, nu0 = 4, sigma0 = 25),
criterion = crit
)
qdm_decide(des_nix, data_t = data_continuous(12, 22, 25),
data_c = data_continuous(12, 2, 25))$posterior_c
#> mu kappa nu sigma
#> 1.714286 14.000000 16.000000 24.214997External data enter through a power prior with weight \(a_0\): data with \(n_e\) subjects, mean \(\bar y_e\) and standard deviation \(s_e\) act as \(a_0 n_e\) subjects with the same mean and the sum of squares \(a_0 (n_e - 1) s_e^2\), which keeps the posterior distribution in closed form (Huang et al., submitted). With the vague prior, the posterior distribution of the mean then has \(a_0 n_e + n - 1\) degrees of freedom. Borrowing half of 30 external control subjects:
des_ext <- design_continuous(
n_t = 12, n_c = 12, prior_t = prior_vague(), prior_c = prior_vague(),
criterion = crit,
external_c = borrow(data_continuous(n = 30, mean = 0, sd = 25), a0 = 0.5)
)
dec_ext <- qdm_decide(des_ext, data_t = data_continuous(12, 22, 25),
data_c = data_continuous(12, 2, 25))
dec_ext$posterior_c
#> mu kappa nu sigma
#> 0.8888889 27.0000000 26.0000000 24.7791527The control mean now has 26 degrees of freedom (\(0.5 \times 30 + 12 - 1\)), and the probability of the Go region is 0.75 (without the external data, 0.678).
For an uncontrolled study, Kang, Yamaguchi and Han (2026, Section
4.2.4) give the control mean the same t distribution as the posterior
distribution of the treatment mean, with location \(\mu_{0c}\) and the squared scale multiplied
by \(r\): \[\mu_c \sim t_{\nu_{nt}}(\mu_{0c}, \; r
\sigma_{nt}^2 / \kappa_{nt}).\] The prior of the control group is
then not used and is left NULL:
des_hyp <- design_continuous(
n_t = 12, n_c = 0, prior_t = prior_vague(), criterion = crit,
hypothetical_c = hypothetical(mean = 0, r = 1)
)
qdm_decide(des_hyp, data_t = data_continuous(12, 22, 25))
#> Decision: Go
#> Go: P(theta > 15 | data) = 0.7403 (threshold 0.6, met)
#> NoGo: P(theta <= 5 | data) = 0.06372 (threshold 0.7, not met)
#> Posterior distributions
#> Treatment: mean ~ t(df = 11, location = 22, scale = 7.217)
#> Control: mean ~ t(df = 11, location = 0, scale = 7.217)With fixed_c, the control mean is a known value \(\mu_{c0}\), for example the mean of the
standard of care reported in the literature. The effect is \(\theta = \mu_t - \mu_{c0}\), its
probabilities are those of the t distribution of the treatment mean, and
prior_c and method are not used. With the
vague prior and a benchmark of \(-10\):
des_fix <- design_continuous(n_t = 12, n_c = 0, prior_t = prior_vague(),
criterion = crit, fixed_c = -10)
dec_fix <- qdm_decide(des_fix, data_t = data_continuous(12, 22, 25))
dec_fix
#> Decision: Go
#> Go: P(theta > 15 | data) = 0.9809 (threshold 0.6, met)
#> NoGo: P(theta <= 5 | data) = 0.00163 (threshold 0.7, not met)
#> Posterior distributions
#> Treatment: mean ~ t(df = 11, location = 22, scale = 7.217)
#> Control: fixed value -10
pt((22 - (-10 + 15)) / (25 / sqrt(12)), df = 11)
#> [1] 0.9809453For the predictive criterion, the mean of the \(m_t\) future subjects has the predictive t distribution given above, and the future effect is that mean minus \(\mu_{c0}\).
With 50 subjects per group in a future study and \(\theta_{NULL} = 0\):
des_pred <- design_continuous(
n_t = 12, n_c = 12, prior_t = prior_vague(), prior_c = prior_vague(),
criterion = criterion_predictive(theta_null = 0, m_t = 50,
gamma_go = 0.9, gamma_nogo = 0.7)
)
qdm_decide(des_pred, data_t = data_continuous(12, 22, 25),
data_c = data_continuous(12, 2, 25))
#> Decision: Go
#> Go: P(future theta > 0 | data) = 0.9457 (threshold 0.9, met)
#> NoGo: P(future theta <= 0 | data) = 0.05428 (threshold 0.7, not met)
#> Posterior distributions
#> Treatment: mean ~ t(df = 11, location = 22, scale = 7.217)
#> Control: mean ~ t(df = 11, location = 2, scale = 7.217)qdm_oc() simulates nsim studies under each
scenario. Only the sufficient statistics are simulated, \(\bar y = \mu + \sigma Z / \sqrt{n}\) and
\(s = \sigma \sqrt{X / (n - 1)}\) with
\(Z \sim N(0, 1)\) and \(X \sim \chi^2_{n - 1}\), and the same
random numbers are used for all scenarios. The moment-matching
approximation is much faster than numerical integration and is
convenient for exploring designs:
des_mm <- design_continuous(n_t = 12, n_c = 12, prior_t = prior_vague(),
prior_c = prior_vague(), criterion = crit,
method = "MM")
scen <- data.frame(mu_t = seq(0, 40, by = 5), sd_t = 25, mu_c = 0, sd_c = 25)
oc <- qdm_oc(des_mm, scen, seed = 1)
oc
#> Operating characteristics (simulation of 10000 studies; probabilities by moment-matching approximation)
#> mu_t sd_t mu_c sd_c Go NoGo Gray Miss
#> 0 25 0 25 0.0419 0.4823 0.4758 0
#> 5 25 0 25 0.1087 0.2928 0.5985 0
#> 10 25 0 25 0.2264 0.1533 0.6203 0
#> 15 25 0 25 0.3876 0.0682 0.5442 0
#> 20 25 0 25 0.5825 0.0238 0.3937 0
#> 25 25 0 25 0.7631 0.0069 0.2300 0
#> 30 25 0 25 0.8817 0.0014 0.1169 0
#> 35 25 0 25 0.9508 0.0003 0.0489 0
#> 40 25 0 25 0.9840 0.0001 0.0159 0
plot(oc)The chosen design can be checked with numerical integration. To keep this vignette quick, only three scenarios and 1000 simulated studies are used here; with the same seed, both methods are applied to the same simulated studies:
scen3 <- scen[c(1, 3, 5), ]
oc_ni <- qdm_oc(des, scen3, nsim = 1000, seed = 1)
oc_mm <- qdm_oc(des_mm, scen3, nsim = 1000, seed = 1)
data.frame(mu_t = scen3$mu_t, Go_NI = oc_ni$Go, Go_MM = oc_mm$Go,
NoGo_NI = oc_ni$NoGo, NoGo_MM = oc_mm$NoGo)
#> mu_t Go_NI Go_MM NoGo_NI NoGo_MM
#> 1 0 0.043 0.043 0.498 0.498
#> 2 10 0.209 0.209 0.180 0.180
#> 3 20 0.575 0.576 0.027 0.027The simulation standard error of the probabilities is at most \(0.5 / \sqrt{nsim}\), 0.005 for the default
nsim = 10000.
qdm_boundary() shows which observed means lead to each
decision. For each observed standard deviation (or sample size) of the
treatment group, it gives the intervals of the observed treatment mean
that lead to Go, NoGo and Gray decisions, and the corresponding observed
differences in means; the ends of the intervals are located by
bisection. With a concurrent control group, the observed control data
are given by data_c:
b <- qdm_boundary(des_mm, sd_t = seq(10, 40, by = 5),
data_c = data_continuous(12, 2, 25))
b
#> Decision boundary of a design with one continuous endpoint
#> n_t = 12
#> Control data: continuous, n = 12, mean = 2, sd = 25
#>
#> Observed treatment mean
#> sd_t NoGo Gray Go
#> 10 <= 2.747 2.747 to 19.05 >= 19.05
#> 15 <= 2.352 2.352 to 19.24 >= 19.24
#> 20 <= 1.866 1.866 to 19.47 >= 19.47
#> 25 <= 1.321 1.321 to 19.74 >= 19.74
#> 30 <= 0.7346 0.7346 to 20.02 >= 20.02
#> 35 <= 0.1162 0.1162 to 20.31 >= 20.31
#> 40 <= -0.5276 -0.5276 to 20.62 >= 20.62
#>
#> Observed difference in means (control mean 2)
#> sd_t NoGo Gray Go
#> 10 <= 0.7473 0.7473 to 17.05 >= 17.05
#> 15 <= 0.3518 0.3518 to 17.24 >= 17.24
#> 20 <= -0.1338 -0.1338 to 17.47 >= 17.47
#> 25 <= -0.6788 -0.6788 to 17.74 >= 17.74
#> 30 <= -1.265 -1.265 to 18.02 >= 18.02
#> 35 <= -1.884 -1.884 to 18.31 >= 18.31
#> 40 <= -2.528 -2.528 to 18.62 >= 18.62
plot(b)With an observed standard deviation of 25, a Go decision needs an observed difference in means of at least 17.7, and a larger standard deviation needs a larger observed difference. For the design with a fixed control, the boundary can be shown against the sample size instead:
b_fix <- qdm_boundary(des_fix, n_t = c(6, 12, 20, 30, 40), sd_t = 25)
b_fix
#> Decision boundary of a design with one continuous endpoint
#> sd_t = 25
#>
#> Observed treatment mean
#> n_t NoGo Gray Go
#> 6 <= -10.71 -10.71 to 7.727 >= 7.727
#> 12 <= -8.897 -8.897 to 6.873 >= 6.873
#> 20 <= -7.981 -7.981 to 6.436 >= 6.436
#> 30 <= -7.42 -7.42 to 6.167 >= 6.167
#> 40 <= -7.09 -7.09 to 6.008 >= 6.008
#>
#> Observed difference from the fixed control mean (-10)
#> n_t NoGo Gray Go
#> 6 <= -0.7097 -0.7097 to 17.73 >= 17.73
#> 12 <= 1.103 1.103 to 16.87 >= 16.87
#> 20 <= 2.019 2.019 to 16.44 >= 16.44
#> 30 <= 2.58 2.58 to 16.17 >= 16.17
#> 40 <= 2.91 2.91 to 16.01 >= 16.01
plot(b_fix)The thresholds are calibrated so that the Go criterion is met with probability at most 0.05 when the treatment has no effect, and the NoGo criterion with probability at most 0.2 when the effect is 20:
cal <- qdm_calibrate(
des_mm,
scenario_go = data.frame(mu_t = 0, sd_t = 25, mu_c = 0, sd_c = 25),
scenario_nogo = data.frame(mu_t = 20, sd_t = 25, mu_c = 0, sd_c = 25),
target_go = 0.05, target_nogo = 0.2, seed = 1
)
cal
#> Calibration of the decision thresholds (simulation of 10000 studies; probabilities by moment-matching approximation)
#> gamma_go = 0.57: P(Go criterion met | scenario_go) = 0.0484 (target 0.05)
#> gamma_nogo = 0.28: P(NoGo criterion met | scenario_nogo) = 0.1975 (target 0.2)
#> Decision probabilities with the chosen thresholds
#> scenario mu_t sd_t mu_c sd_c Go NoGo Gray Miss
#> scenario_go 0 25 0 25 0.0484 0.8615 0.0901 0
#> scenario_nogo 20 25 0 25 0.6135 0.1975 0.1890 0
plot(cal)The chosen thresholds are \(\gamma_{go} =\) 0.57 and \(\gamma_{nogo} =\) 0.28.
Huang, Y., Yamaguchi, Y., Homma, G., Takeda, K. and Maruo, K. (submitted). Conjugate representation of power priors for efficient Bayesian analysis of normal data.
Kang, R., Yamaguchi, Y. and Han, C. (2026). Bayesian quantitative decision-making framework in cell and gene therapy development for rare diseases. Journal of Biopharmaceutical Statistics. https://doi.org/10.1080/10543406.2026.2655410
Yamaguchi, Y., Homma, G., Takeda, K. and Maruo, K. (submitted). Moment-matching approximation for t-differences in clinical trials with continuous endpoints.