View source: R/MLB_SLB_anlaysis.R
| MLB_SLB_anlaysis | R Documentation |
Arms and notation (H/C/T):
H — Historical control arm. External/previous-study control,
used to build an informative prior for the concurrent control.
C — Concurrent control arm. In-trial control; first fitted
under a non-informative prior to assess prior–data conflict and
compute an adaptive weight; then re-fitted under an MLB/SLB prior.
T — Treatment arm. In-trial treatment; typically fitted under
a non-informative prior, then compared against the (re)fitted control.
MLB_SLB_anlaysis(
historical_df,
concurrent_df,
treatment_df,
family = c("gaussian", "bernoulli"),
delta,
n_hist = NULL,
fixed_weight = 0.5,
mcmc_settings = list(n.chains = 3, n.iter = 10000, n.burnin = 5000, n.thin = 2,
parallel = FALSE),
decision_MLB,
direction_MLB = c("lower", "higher"),
decision_SLB,
direction_SLB = c("lower", "higher")
)
historical_df |
Long-format data.frame for H with columns |
concurrent_df |
Long-format data.frame for C with columns |
treatment_df |
Long-format data.frame for T with columns |
family |
Character, |
delta |
Clinically significant difference (CSD) used in SLB weight. |
n_hist |
Positive integer: historical sample size for unit-information prior (continuous only). |
fixed_weight |
MLB mixing weight |
mcmc_settings |
JAGS settings list with fields |
decision_MLB |
A REQUIRED decision function for MLB prior with threshold p that takes two numeric vectors of
posterior samples Direction of test (how probabilities are computed/decisions typically defined):
|
direction_MLB |
Character scalar specifying the clinical direction of superiority for MLB prior:
|
decision_SLB |
A REQUIRED decision function for SLB prior with threshold p that takes two numeric vectors of
posterior samples Direction of test (how probabilities are computed/decisions typically defined):
|
direction_SLB |
Character scalar specifying the clinical direction of superiority for SLB prior:
|
Target parameters \theta_H,\theta_C,\theta_T:
family = "gaussian" (continuous outcome):
\theta is the total change at the final visit t_K,
i.e., \theta=\beta_1 t_K (thus \beta_1=\theta/t_K).
family = "bernoulli" (binary, probit link):
\theta is the marginal response probability at the final visit,
\Pr(Y=1 \text{ at } t_K)\in (0,1).
We write \theta_H, \theta_C, \theta_T for the historical,
concurrent-control, and treatment arms, respectively.
Workflow (continuous or binary endpoints):
Fit H under SPM with a vague prior on \theta to obtain posterior draws.
Build an informative prior g_0 for \theta_C via
RBesT::mixfit on the \theta_H draws.
Build a non-informative prior g_1:
Gaussian: unit-information prior from g_0 (inflate SD by \sqrt{n_\mathrm{hist}});
Bernoulli: \mathrm{Beta}(1,1).
Fit C under g_1 to get posterior samples.
Compute SLB weight via posterior-probability-ratio KDE (see SLB_weight).
Construct MLB prior (fixed weight) and SLB prior (data-adaptive weight) via Mixprior.
Fit C under MLB/SLB priors; fit T under g_1.
Posterior comparisons \theta_T vs \theta_C and decisions per direction.
An object of class "mlbslb_result":
estimates: posterior means of \theta for each arm/prior (MLB/SLB).
weights: list with MLB_weight and SLB_weight.
probabilities: posterior superiority probabilities (per direction) under MLB/SLB.
decisions: 0/1 decisions under MLB/SLB according to your decision(). (1 indicates test superiority is established).
posterior_samples: posterior draws used in the analysis.
set.seed(1000)
t_vec <- seq(4, 48, 4)
# --- Continuous outcome ---
data_H <- generate_spm(n=60, t_vec, family="gaussian",
alpha0=-4, alpha1=0.05, rho=-1, sigma_b=1,
theta= -3.2, sigma_e=1)$dat
data_C <- generate_spm(n=30, t_vec, family="gaussian",
alpha0=-4, alpha1=0.05, rho=-1, sigma_b=1,
theta= -3.2, sigma_e=1)$dat
data_T <- generate_spm(n=60, t_vec, family="gaussian",
alpha0=-5.3, alpha1=0.05, rho=-1.5, sigma_b=1,
theta= -3.7, sigma_e=1)$dat
# Full MCMC fitting takes several minutes.
ans_1 <- MLB_SLB_anlaysis(
historical_df = data_H, concurrent_df = data_C, treatment_df = data_T,
family="gaussian", delta=0.5, n_hist=length(unique(data_H$id)), fixed_weight=0.5,
mcmc_settings = list(n.chains=3, n.iter=10000, n.burnin=5000, n.thin=2, parallel=FALSE),
decision_MLB = function(theta_t, theta_c, p = 0.95) mean(theta_t < theta_c) > 0.95,
# Smaller-is-better (treatment < control), p = 0.95
direction_MLB = "lower",
decision_SLB = function(theta_t, theta_c, p = 0.95) mean(theta_t < theta_c) > 0.95,
# Smaller-is-better (treatment < control), p = 0.95
direction_SLB = "lower"
)
ans_1$decisions; ans_1$probabilities
# --- Binary outcome ---
set.seed(1000)
data_H <- generate_spm(n=200, t_vec, family="bernoulli",
alpha0=-4, alpha1=0.05, rho=-1, sigma_b=1,
theta=0.40, beta0=-2)$dat
data_C <- generate_spm(n=100, t_vec, family="bernoulli",
alpha0=-4, alpha1=0.05, rho=-1, sigma_b=1,
theta=0.40, beta0=-2)$dat
data_T <- generate_spm(n=200, t_vec, family="bernoulli",
alpha0=-5.3, alpha1=0.05, rho=-1.5, sigma_b=1,
theta=0.50, beta0=-1.5)$dat
# Full MCMC fitting takes several minutes.
ans_2 <- MLB_SLB_anlaysis(historical_df = data_H, concurrent_df = data_C, treatment_df = data_T,
family="bernoulli", delta=0.1, n_hist=length(unique(data_H$id)), fixed_weight=0.5,
mcmc_settings = list(n.chains=3, n.iter=10000, n.burnin=5000, n.thin=2, parallel=FALSE),
decision_MLB = function(theta_t, theta_c, p = 0.95) mean(theta_t > theta_c) > 0.95,
# Larger-is-better (treatment > control), p = 0.95
direction_MLB = "higher",
decision_SLB = function(theta_t, theta_c, p = 0.95) mean(theta_t > theta_c) > 0.95,
# Larger-is-better (treatment > control), p = 0.95
direction_SLB = "higher"
)
ans_2$decisions; ans_2$probabilities
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.