| Title: | Self-Adapting Mixture (SAM) Priors |
|---|---|
| Description: | Implementation of the SAM prior and generation of its operating characteristics for dynamically borrowing information from historical data. For details, please refer to Yang et al. (2023) <doi:10.1111/biom.13927>. |
| Authors: | Peng Yang [aut, cre] (ORCID: <https://orcid.org/0000-0002-0630-9506>), Ying Yuan [aut] (ORCID: <https://orcid.org/0000-0003-3163-480X>) |
| Maintainer: | Peng Yang <[email protected]> |
| License: | GPL (>= 3) |
| Version: | 3.0.0 |
| Built: | 2026-05-27 06:26:49 UTC |
| Source: | https://github.com/pengyang0411/samprior |
The calibrate_cutoff_2arm function is designed to calibrate the
posterior probability cutoff for a two-arm comparative trial under the
specified endpoint type and borrowing strategy: self-adapting mixture
prior (SAM), robust MAP prior with fixed weight (rMAP), or non-informative
prior (NP).
calibrate_cutoff_2arm( if.prior, nf.prior, prior.t = nf.prior, target = 0.05, n.t, n, theta.t = NULL, theta = NULL, delta, method = c("SAM", "rMAP", "NP"), alternative = c("greater", "less"), margin = 0, weight_rMAP = 0.5, method.w = "LRT", prior.odds = 1, interval = c(0.5, 0.999), rel.tol = 1e-05, oc_rel.tol = 1e-06, ... ) ## S3 method for class 'betaMix' calibrate_cutoff_2arm( if.prior, nf.prior, prior.t = nf.prior, target = 0.05, n.t, n, theta.t = NULL, theta = NULL, delta, method = c("SAM", "rMAP", "NP"), alternative = c("greater", "less"), margin = 0, weight_rMAP = 0.5, method.w = "LRT", prior.odds = 1, interval = c(0.5, 0.999), rel.tol = 1e-05, oc_rel.tol = 1e-08, ... ) ## S3 method for class 'normMix' calibrate_cutoff_2arm( if.prior, nf.prior, prior.t = nf.prior, target = 0.05, n.t, n, theta.t = NULL, theta = NULL, delta, method = c("SAM", "rMAP", "NP"), alternative = c("greater", "less"), margin = 0, weight_rMAP = 0.5, method.w = "LRT", prior.odds = 1, interval = c(0.5, 0.999), rel.tol = 1e-05, oc_rel.tol = 1e-06, sigma.t, sigma, n_sd_int = 8, ... )calibrate_cutoff_2arm( if.prior, nf.prior, prior.t = nf.prior, target = 0.05, n.t, n, theta.t = NULL, theta = NULL, delta, method = c("SAM", "rMAP", "NP"), alternative = c("greater", "less"), margin = 0, weight_rMAP = 0.5, method.w = "LRT", prior.odds = 1, interval = c(0.5, 0.999), rel.tol = 1e-05, oc_rel.tol = 1e-06, ... ) ## S3 method for class 'betaMix' calibrate_cutoff_2arm( if.prior, nf.prior, prior.t = nf.prior, target = 0.05, n.t, n, theta.t = NULL, theta = NULL, delta, method = c("SAM", "rMAP", "NP"), alternative = c("greater", "less"), margin = 0, weight_rMAP = 0.5, method.w = "LRT", prior.odds = 1, interval = c(0.5, 0.999), rel.tol = 1e-05, oc_rel.tol = 1e-08, ... ) ## S3 method for class 'normMix' calibrate_cutoff_2arm( if.prior, nf.prior, prior.t = nf.prior, target = 0.05, n.t, n, theta.t = NULL, theta = NULL, delta, method = c("SAM", "rMAP", "NP"), alternative = c("greater", "less"), margin = 0, weight_rMAP = 0.5, method.w = "LRT", prior.odds = 1, interval = c(0.5, 0.999), rel.tol = 1e-05, oc_rel.tol = 1e-06, sigma.t, sigma, n_sd_int = 8, ... )
if.prior |
Informative prior constructed from historical data, represented (approximately) as a mixture of conjugate distributions. |
nf.prior |
Non-informative prior used for the mixture and as the robustifying component for the control arm prior. |
prior.t |
Prior used for the treatment arm. If missing, the default
value is set to be |
target |
Target rejection probability under the calibration scenario, typically the desired type I error rate when the calibration scenario corresponds to the null hypothesis. |
n.t |
Sample size for the treatment arm. |
n |
Sample size for the control arm. |
theta.t |
The response rate (binary endpoints) or mean (continuous endpoints) for the treatment arm under the calibration scenario. |
theta |
The response rate (binary endpoints) or mean (continuous endpoints) for the control arm under the calibration scenario. |
delta |
Clinically significant difference used for the SAM prior.
This argument is only used when |
method |
Borrowing strategy for the control arm. Must be one of
|
alternative |
Direction of the posterior decision. Must be one of
|
margin |
Clinical margin. Must be non-negative. Default is |
weight_rMAP |
Weight assigned to the informative prior component
( |
method.w |
Methods used to determine the mixture weight for SAM priors.
The default method is "LRT" (Likelihood Ratio Test), the alternative option
is "PPR" (Posterior Probability Ratio). See |
prior.odds |
The prior probability of |
interval |
Search interval for the posterior probability cutoff. The default is from 0.5 to 0.999. |
rel.tol |
Tolerance passed to |
oc_rel.tol |
Relative tolerance passed to scenario-level calculations. For continuous endpoints this controls numerical integration in the operating-characteristic engine; for binary endpoints this controls numerical integration in posterior probability calculations. |
... |
Additional arguments required by the endpoint-specific method.
For continuous endpoints, this includes |
sigma.t |
Known sampling standard deviation in the treatment arm. |
sigma |
Known sampling standard deviation in the control arm. |
n_sd_int |
Half-width of the numerical integration region for each arm, expressed as a multiple of the corresponding standard error. |
For binary endpoints, the function dispatches to
calibrate_cutoff_bin_2arm. For continuous endpoints, it
dispatches to calibrate_cutoff_cont_2arm.
The function calibrates the posterior probability cutoff for a
two-arm comparative trial so that the repeated-sampling rejection
probability under the specified calibration scenario equals
target. Inference is based on the posterior probability of the
treatment effect , where and
denote the treatment-arm and control-arm parameters,
respectively.
For alternative = "greater", the posterior decision rule is based on
where denotes the clinical margin and denotes the
observed data. Under the default settings, calibration is performed under
the null scenario , where
is the posterior mean of the
informative prior constructed from historical data. This corresponds to a
superiority test when .
For alternative = "less", the posterior decision rule is based on
Calibration is again performed under the null scenario
, where
. This corresponds to an
inferiority test when .
This function acts as a generic front-end and dispatches according to the
class of if.prior. For binary endpoints, it calls
calibrate_cutoff_bin_2arm. For continuous endpoints, it calls
calibrate_cutoff_cont_2arm.
A list with the following elements:
Calibrated posterior probability cutoff.
Value of the root-finding objective at the solution.
Target rejection probability.
Borrowing method used.
Direction of the posterior decision.
Clinical margin used for inference.
True control-arm parameter under the calibration scenario.
True treatment-arm parameter under the calibration scenario.
Search interval used for calibration.
calibrate_cutoff_2arm(betaMix): Calibrate the posterior probability cutoff for a two-arm binary endpoint.
calibrate_cutoff_2arm(normMix): Calibrate the posterior probability cutoff for a two-arm continuous endpoint.
calibrate_cutoff_bin_2arm,
calibrate_cutoff_cont_2arm
## Example: calibrate the posterior probability cutoff for a two-arm ## binary trial using a SAM prior for the control arm ## Informative prior constructed from historical data if.prior <- mixbeta(c(1, 20, 40)) ## Sample sizes n.t <- 100 n <- 50 ## Calibrate the posterior probability cutoff PPC <- calibrate_cutoff_2arm( if.prior = if.prior, ## Informative prior from historical data nf.prior = mixbeta(c(1, 1, 1)), ## Non-informative prior for SAM prior prior.t = mixbeta(c(1, 1, 1)), ## Prior for treatment arm target = 0.05, ## Targeted type I error rate n.t = n.t, ## Sample size for treatment arm n = n, ## Sample size for control arm theta.t = summary(if.prior)["mean"], ## True treatment-arm response rate theta = summary(if.prior)["mean"], ## True control-arm response rate method = "SAM", ## Borrowing method delta = 0.2, ## Clinically significant difference alternative = "greater", ## Superiority test margin = 0 ## Clinical margin ) PPC## Example: calibrate the posterior probability cutoff for a two-arm ## binary trial using a SAM prior for the control arm ## Informative prior constructed from historical data if.prior <- mixbeta(c(1, 20, 40)) ## Sample sizes n.t <- 100 n <- 50 ## Calibrate the posterior probability cutoff PPC <- calibrate_cutoff_2arm( if.prior = if.prior, ## Informative prior from historical data nf.prior = mixbeta(c(1, 1, 1)), ## Non-informative prior for SAM prior prior.t = mixbeta(c(1, 1, 1)), ## Prior for treatment arm target = 0.05, ## Targeted type I error rate n.t = n.t, ## Sample size for treatment arm n = n, ## Sample size for control arm theta.t = summary(if.prior)["mean"], ## True treatment-arm response rate theta = summary(if.prior)["mean"], ## True control-arm response rate method = "SAM", ## Borrowing method delta = 0.2, ## Clinically significant difference alternative = "greater", ## Superiority test margin = 0 ## Clinical margin ) PPC
The calibrate_cutoff_bin_2arm function is designed to calibrate the
posterior probability cutoff for a two-arm comparative trial with a binary
endpoint under one borrowing strategy: self-adapting mixture prior (SAM),
robust MAP prior with fixed weight (rMAP), or non-informative prior (NP).
calibrate_cutoff_bin_2arm( if.prior, nf.prior, prior.t = nf.prior, target = 0.05, n.t, n, theta.t = NULL, theta = NULL, delta, method = c("SAM", "rMAP", "NP"), alternative = c("greater", "less"), margin = 0, weight_rMAP = 0.5, method.w = "LRT", prior.odds = 1, interval = c(0.5, 0.999), rel.tol = 1e-05, oc_rel.tol = 1e-08 )calibrate_cutoff_bin_2arm( if.prior, nf.prior, prior.t = nf.prior, target = 0.05, n.t, n, theta.t = NULL, theta = NULL, delta, method = c("SAM", "rMAP", "NP"), alternative = c("greater", "less"), margin = 0, weight_rMAP = 0.5, method.w = "LRT", prior.odds = 1, interval = c(0.5, 0.999), rel.tol = 1e-05, oc_rel.tol = 1e-08 )
if.prior |
Informative prior constructed based on historical data for the control arm, represented (approximately) as a beta mixture prior. |
nf.prior |
Non-informative prior used for the mixture. |
prior.t |
Prior used for the treatment arm. If missing, the default
value is set to be |
target |
Target rejection probability under the calibration scenario, typically the desired type I error rate when the calibration scenario corresponds to the null hypothesis. |
n.t |
Sample size for the treatment arm. |
n |
Sample size for the control arm. |
theta.t |
The response rate for the treatment arm under the calibration scenario. |
theta |
The response rate for the control arm under the calibration scenario. |
delta |
Clinically significant difference used for the SAM prior.
This argument is only used when |
method |
Borrowing strategy for the control arm. Must be one of
|
alternative |
Direction of the posterior decision. Must be one of
|
margin |
Clinical margin. Must be non-negative. Default is |
weight_rMAP |
Weight assigned to the informative prior component
( |
method.w |
Methods used to determine the mixture weight for SAM priors.
The default method is "LRT" (Likelihood Ratio Test), the alternative option
is "PPR" (Posterior Probability Ratio). See |
prior.odds |
The prior probability of |
interval |
Search interval for the posterior probability cutoff. The default is from 0.5 to 0.999. |
rel.tol |
Tolerance passed to |
oc_rel.tol |
Relative tolerance passed to scenario-level calculations. |
The calibrated cutoff is chosen so that the repeated-sampling rejection probability under a specified scenario equals the target value.
The function solves for the posterior probability cutoff such that the
scenario-level rejection probability returned by
eval_scenario_bin_2arm matches target. Under null
scenarios, this corresponds to calibration of the type I error.
A list with the following elements:
Calibrated posterior probability cutoff.
Value of the root-finding objective at the solution.
Target rejection probability.
Borrowing method used.
Direction of the posterior decision.
Clinical margin used for inference.
True control-arm response rate under the calibration scenario.
True treatment-arm response rate under the calibration scenario.
Search interval used for calibration.
The calibrate_cutoff_cont_2arm function is designed to calibrate the
posterior probability cutoff for a two-arm comparative trial with a
continuous endpoint under one borrowing strategy: self-adapting mixture prior
(SAM), robust MAP prior with fixed weight (rMAP), or non-informative prior
(NP).
calibrate_cutoff_cont_2arm( if.prior, nf.prior, prior.t = nf.prior, target = 0.05, n.t, n, sigma.t, sigma, theta.t = NULL, theta = NULL, delta, method = c("SAM", "rMAP", "NP"), alternative = c("greater", "less"), margin = 0, weight_rMAP = 0.5, method.w = "LRT", prior.odds = 1, interval = c(0.5, 0.999), rel.tol = 1e-05, oc_rel.tol = 1e-06, n_sd_int = 8 )calibrate_cutoff_cont_2arm( if.prior, nf.prior, prior.t = nf.prior, target = 0.05, n.t, n, sigma.t, sigma, theta.t = NULL, theta = NULL, delta, method = c("SAM", "rMAP", "NP"), alternative = c("greater", "less"), margin = 0, weight_rMAP = 0.5, method.w = "LRT", prior.odds = 1, interval = c(0.5, 0.999), rel.tol = 1e-05, oc_rel.tol = 1e-06, n_sd_int = 8 )
if.prior |
Informative prior constructed based on historical data for the control arm, represented (approximately) as a normal mixture prior. |
nf.prior |
Non-informative prior used for the mixture. |
prior.t |
Prior used for the treatment arm. If missing, the default
value is set to be |
target |
Target rejection probability under the calibration scenario, typically the desired type I error rate when the calibration scenario corresponds to the null hypothesis. |
n.t |
Sample size for the treatment arm. |
n |
Sample size for the control arm. |
sigma.t |
Known sampling standard deviation for the treatment arm. |
sigma |
Known sampling standard deviation for the control arm. |
theta.t |
The mean for the treatment arm under the calibration scenario. |
theta |
The mean for the control arm under the calibration scenario. |
delta |
Clinically significant difference used for the SAM prior.
This argument is only used when |
method |
Borrowing strategy for the control arm. Must be one of
|
alternative |
Direction of the posterior decision. Must be one of
|
margin |
Clinical margin. Must be non-negative. Default is |
weight_rMAP |
Weight assigned to the informative prior component
( |
method.w |
Methods used to determine the mixture weight for SAM priors.
The default method is "LRT" (Likelihood Ratio Test), the alternative option
is "PPR" (Posterior Probability Ratio). See |
prior.odds |
The prior probability of |
interval |
Search interval for the posterior probability cutoff. The default is from 0.5 to 0.999. |
rel.tol |
Tolerance passed to |
oc_rel.tol |
Relative tolerance passed to scenario-level numerical integration. |
n_sd_int |
Half-width of the numerical integration region for each arm, expressed as a multiple of the corresponding standard error. |
The calibrated cutoff is chosen so that the repeated-sampling rejection probability under a specified scenario equals the target value.
The function solves for the posterior probability cutoff such that the
scenario-level rejection probability returned by
eval_scenario_cont_2arm matches target. Under null
scenarios, this corresponds to calibration of the type I error.
A list with the following elements:
Calibrated posterior probability cutoff.
Value of the root-finding objective at the solution.
Target rejection probability.
Borrowing method used.
Direction of the posterior decision.
Clinical margin used for inference.
True control-arm mean under the calibration scenario.
True treatment-arm mean under the calibration scenario.
Search interval used for calibration.
The eval_oc_bin_2arm function is designed to evaluate
repeated-sampling operating characteristics for multiple scenarios in a
two-arm comparative trial with a binary endpoint under one or more
borrowing strategies: self-adapting mixture prior (SAM), robust MAP prior
with fixed weight (rMAP), or non-informative prior (NP).
eval_oc_bin_2arm( if.prior, nf.prior, prior.t = nf.prior, theta, theta.t, n.t, n, delta, method = c("SAM", "rMAP", "NP"), cutoff, alternative = c("greater", "less"), margin = 0, weight_rMAP = 0.5, method.w = "LRT", prior.odds = 1, rel.tol = 1e-08 )eval_oc_bin_2arm( if.prior, nf.prior, prior.t = nf.prior, theta, theta.t, n.t, n, delta, method = c("SAM", "rMAP", "NP"), cutoff, alternative = c("greater", "less"), margin = 0, weight_rMAP = 0.5, method.w = "LRT", prior.odds = 1, rel.tol = 1e-08 )
if.prior |
Informative prior constructed based on historical data for the control arm, represented (approximately) as a beta mixture prior. |
nf.prior |
Non-informative prior used as the robustifying component for the control arm prior. |
prior.t |
Prior used for the treatment arm. If missing, the default
value is set to be |
theta |
A vector of true control arm response rates. |
theta.t |
A vector of true treatment arm response rates. |
n.t |
Sample size for the treatment arm. |
n |
Sample size for the control arm. |
delta |
Clinically significant difference used for the SAM prior.
This argument is only used when |
method |
Borrowing methods to evaluate. Any subset of
|
cutoff |
Posterior probability cutoff specification. Either a single
numeric value applied to all methods, or a named numeric vector/list with
method-specific cutoffs, for example
|
alternative |
Direction of the posterior decision. Must be one of
|
margin |
Clinical margin. Must be a non-negative scalar. The default
value is |
weight_rMAP |
Weight assigned to the informative prior component
( |
method.w |
Methods used to determine the mixture weight for SAM priors.
The default method is "LRT" (Likelihood Ratio Test), the alternative option
is "PPR" (Posterior Probability Ratio). See |
prior.odds |
The prior probability of |
rel.tol |
Relative tolerance passed to scenario-level numerical
integration used in |
For each scenario, the function computes the repeated-sampling rejection
probability, bias, RMSE, and mean borrowing weight using
eval_scenario_bin_2arm.
The vectors theta and theta.t must have the same length.
Each pair (theta[i], theta.t[i]) defines one scenario.
The cutoff argument may be common across methods or method-specific.
This is useful when each borrowing method is calibrated separately before
operating characteristics are evaluated.
A data frame with one row per scenario-method combination and columns:
Scenario index.
True control arm response rate.
True treatment arm response rate.
True treatment effect, .
Borrowing method used.
Direction of the posterior decision.
Posterior probability cutoff used.
Clinical margin used for inference.
Repeated-sampling rejection probability.
Bias of the posterior mean estimator of .
Root mean squared error of the posterior mean estimator of .
Average borrowing weight under the specified method.
The eval_oc_cont_2arm function is designed to evaluate
repeated-sampling operating characteristics for multiple scenarios in a
two-arm comparative trial with a continuous endpoint under one or more
borrowing strategies: self-adapting mixture prior (SAM), robust MAP prior
with fixed weight (rMAP), or non-informative prior (NP).
eval_oc_cont_2arm( if.prior, nf.prior, prior.t = nf.prior, theta, theta.t, n.t, n, sigma.t, sigma, delta, method = c("SAM", "rMAP", "NP"), cutoff, alternative = c("greater", "less"), margin = 0, weight_rMAP = 0.5, method.w = "LRT", prior.odds = 1, rel.tol = 1e-06, n_sd_int = 8 )eval_oc_cont_2arm( if.prior, nf.prior, prior.t = nf.prior, theta, theta.t, n.t, n, sigma.t, sigma, delta, method = c("SAM", "rMAP", "NP"), cutoff, alternative = c("greater", "less"), margin = 0, weight_rMAP = 0.5, method.w = "LRT", prior.odds = 1, rel.tol = 1e-06, n_sd_int = 8 )
if.prior |
Informative prior constructed based on historical data for the control arm, represented (approximately) as a normal mixture prior. |
nf.prior |
Non-informative prior used as the robustifying component for the control arm prior. |
prior.t |
Prior used for the treatment arm. If missing, the default
value is set to be |
theta |
A vector of true control arm means. |
theta.t |
A vector of true treatment arm means. |
n.t |
Sample size for the treatment arm. |
n |
Sample size for the control arm. |
sigma.t |
Known sampling standard deviation in the treatment arm. |
sigma |
Known sampling standard deviation in the control arm. |
delta |
Clinically significant difference used for the SAM prior.
This argument is only used when |
method |
Borrowing methods to evaluate. Any subset of
|
cutoff |
Posterior probability cutoff specification. Either a single
numeric value applied to all methods, or a named numeric vector/list with
method-specific cutoffs, for example
|
alternative |
Direction of the posterior decision. Must be one of
|
margin |
Clinical margin. Must be a non-negative scalar. The default
value is |
weight_rMAP |
Weight assigned to the informative prior component
( |
method.w |
Methods used to determine the mixture weight for SAM priors.
The default method is "LRT" (Likelihood Ratio Test), the alternative option
is "PPR" (Posterior Probability Ratio). See |
prior.odds |
The prior probability of |
rel.tol |
Relative tolerance passed to scenario-level numerical integration. |
n_sd_int |
Half-width of the numerical integration region for each arm, expressed as a multiple of the corresponding standard error. |
For each scenario, the function computes the repeated-sampling rejection
probability, bias, RMSE, and mean borrowing weight using
eval_scenario_cont_2arm.
The vectors theta and theta.t must have the same length.
Each pair (theta[i], theta.t[i]) defines one scenario.
The cutoff argument may be common across methods or method-specific.
This is useful when each borrowing method is calibrated separately before
operating characteristics are evaluated.
A data frame with one row per scenario-method combination and columns:
Scenario index.
True control arm mean.
True treatment arm mean.
True treatment effect, .
Borrowing method used.
Direction of the posterior decision.
Posterior probability cutoff used.
Clinical margin used for inference.
Repeated-sampling rejection probability.
Bias of the posterior mean estimator of .
Root mean squared error of the posterior mean estimator of .
Average borrowing weight under the specified method.
The eval_scenario_bin_2arm function is designed to evaluate
repeated-sampling operating characteristics for a two-arm comparative trial
with a binary endpoint under one borrowing strategy: self-adapting mixture
prior (SAM), robust MAP prior with fixed weight (rMAP), or non-informative
prior (NP).
eval_scenario_bin_2arm( if.prior, nf.prior, prior.t = nf.prior, n.t, n, theta.t, theta, cutoff, delta, method = c("SAM", "rMAP", "NP"), alternative = c("greater", "less"), margin = 0, weight_rMAP = 0.5, method.w = "LRT", prior.odds = 1, rel.tol = 1e-08 )eval_scenario_bin_2arm( if.prior, nf.prior, prior.t = nf.prior, n.t, n, theta.t, theta, cutoff, delta, method = c("SAM", "rMAP", "NP"), alternative = c("greater", "less"), margin = 0, weight_rMAP = 0.5, method.w = "LRT", prior.odds = 1, rel.tol = 1e-08 )
if.prior |
Informative prior constructed based on historical data for the control arm, represented (approximately) as a beta mixture prior. |
nf.prior |
Non-informative prior used as the robustifying component for the control arm prior. |
prior.t |
Prior used for the treatment arm. If missing, the default
value is set to be |
n.t |
Number of subjects in the treatment arm. |
n |
Number of subjects in the control arm. |
theta.t |
True treatment arm response rate. |
theta |
True control arm response rate. |
cutoff |
Posterior probability cutoff used for decision making.
Rejection occurs if the posterior probability exceeds |
delta |
Clinically significant difference used for the SAM prior.
This argument is only used when |
method |
Borrowing strategy for the control arm. Must be one of
|
alternative |
Direction of the posterior decision. Must be one of
|
margin |
Clinical margin. Must be a non-negative scalar. The default
value is |
weight_rMAP |
Weight assigned to the informative prior component
( |
method.w |
Methods used to determine the mixture weight for SAM priors.
The default method is "LRT" (Likelihood Ratio Test), the alternative option
is "PPR" (Posterior Probability Ratio). See |
prior.odds |
The prior probability of |
rel.tol |
Relative tolerance for numerical integration used in posterior probability calculations. |
The treatment effect is defined as ,
where and denote the true response rates in the
treatment and control arms, respectively.
For a given true scenario , this function computes
the repeated-sampling rejection probability, bias, root mean squared error
(RMSE), and mean borrowing weight. The rejection probability is accelerated
by exploiting monotonicity of the posterior decision in the treatment-arm
response count for each fixed control-arm response count.
A one-row data frame with the following columns:
True control arm response rate.
True treatment arm response rate.
True treatment effect, .
Borrowing method used.
Direction of the posterior decision.
Posterior probability cutoff used for decision making.
Clinical margin used for inference.
Repeated-sampling rejection probability.
Bias of the posterior mean estimator of .
Root mean squared error of the posterior mean estimator of .
Average borrowing weight under the specified method.
The eval_scenario_cont_2arm function is designed to evaluate
repeated-sampling operating characteristics for a two-arm comparative trial
with a continuous endpoint under one borrowing strategy: self-adapting
mixture prior (SAM), robust MAP prior with fixed weight (rMAP), or
non-informative prior (NP).
eval_scenario_cont_2arm( if.prior, nf.prior, prior.t = nf.prior, n.t, n, sigma.t, sigma, theta.t, theta, cutoff, delta, method = c("SAM", "rMAP", "NP"), alternative = c("greater", "less"), margin = 0, weight_rMAP = 0.5, method.w = "LRT", prior.odds = 1, rel.tol = 1e-06, n_sd_int = 8 )eval_scenario_cont_2arm( if.prior, nf.prior, prior.t = nf.prior, n.t, n, sigma.t, sigma, theta.t, theta, cutoff, delta, method = c("SAM", "rMAP", "NP"), alternative = c("greater", "less"), margin = 0, weight_rMAP = 0.5, method.w = "LRT", prior.odds = 1, rel.tol = 1e-06, n_sd_int = 8 )
if.prior |
Informative prior constructed based on historical data for the control arm, represented (approximately) as a normal mixture prior. |
nf.prior |
Non-informative prior used as the robustifying component for the control arm prior. |
prior.t |
Prior used for the treatment arm. If missing, the default
value is set to be |
n.t |
Number of subjects in the treatment arm. |
n |
Number of subjects in the control arm. |
sigma.t |
Known sampling standard deviation in the treatment arm. |
sigma |
Known sampling standard deviation in the control arm. |
theta.t |
True treatment arm mean. |
theta |
True control arm mean. |
cutoff |
Posterior probability cutoff used for decision making.
Rejection occurs if the posterior probability exceeds |
delta |
Clinically significant difference used for the SAM prior.
This argument is only used when |
method |
Borrowing strategy for the control arm. Must be one of
|
alternative |
Direction of the posterior decision. Must be one of
|
margin |
Clinical margin. Must be a non-negative scalar. The default
value is |
weight_rMAP |
Weight assigned to the informative prior component
( |
method.w |
Methods used to determine the mixture weight for SAM priors.
The default method is "LRT" (Likelihood Ratio Test), the alternative option
is "PPR" (Posterior Probability Ratio). See |
prior.odds |
The prior probability of |
rel.tol |
Relative tolerance passed to numerical integration. |
n_sd_int |
Half-width of the numerical integration region for each arm, expressed as a multiple of the corresponding standard error. |
The treatment effect is defined as ,
where and denote the true means in the
treatment and control arms, respectively.
For a given true scenario , this function computes
the repeated-sampling rejection probability, bias, root mean squared error
(RMSE), and mean borrowing weight using one-dimensional numerical
integration.
The rejection probability is computed by reducing the repeated-sampling decision rule to a one-dimensional integral over the control-arm sample mean.
Bias and RMSE are evaluated for the posterior mean estimator of the control
arm mean . Both are computed from one-dimensional first and
second moments of the control-arm posterior mean. The mean borrowing weight
is computed by one-dimensional integration over the control-arm sample mean.
Under null scenarios, reject_prob corresponds to type I error. Under
alternative scenarios, it corresponds to power.
A one-row data frame with the following columns:
True control arm mean.
True treatment arm mean.
True treatment effect, .
Borrowing method used.
Direction of the posterior decision.
Posterior probability cutoff used for decision making.
Clinical margin used for inference.
Repeated-sampling rejection probability.
Bias of the posterior mean estimator of .
Root mean squared error of the posterior mean estimator of .
Average borrowing weight under the specified method.
The get_OC function generates operating characteristics of SAM
priors using the analytical operating characteristic engines for two-arm
trials with binary or continuous endpoints. As an option, the operating
characteristics of robust MAP priors can also be generated for comparison.
get_OC( if.prior, theta.h, method.w, prior.odds, nf.prior, prior.t = nf.prior, delta, n, n.t, target = 0.05, if.rMAP = FALSE, weight.rMAP = 0.5, theta, theta.t, alternative = c("greater", "less"), margin = 0, rel.tol = 1e-05, oc_rel.tol = 1e-06, interval = c(0.5, 0.999), n_sd_int = 8, ... )get_OC( if.prior, theta.h, method.w, prior.odds, nf.prior, prior.t = nf.prior, delta, n, n.t, target = 0.05, if.rMAP = FALSE, weight.rMAP = 0.5, theta, theta.t, alternative = c("greater", "less"), margin = 0, rel.tol = 1e-05, oc_rel.tol = 1e-06, interval = c(0.5, 0.999), n_sd_int = 8, ... )
if.prior |
Informative prior constructed from historical data, represented (approximately) as a mixture of conjugate distributions. |
theta.h |
Estimate of the treatment effect based on historical data.
Included for interface compatibility. If missing, the default value is set
to the posterior mean estimate from |
method.w |
Methods used to determine the mixture weight for SAM priors.
The default method is LRT (Likelihood Ratio Test), the alternative option can
be PPR (Posterior Probability Ratio). See |
prior.odds |
The prior probability of |
nf.prior |
Non-informative prior used as the robustifying component for the control arm prior. |
prior.t |
Prior used for the treatment arm. If missing, the default
value is set to be |
delta |
Clinically significant difference used for the SAM prior. |
n |
Sample size for the control arm. |
n.t |
Sample size for the treatment arm. |
target |
Target type I error used to calibrate the posterior probability cutoff for each method. The default value is typically 0.05. |
if.rMAP |
Whether to evaluate the operating characteristics of the
robust MAP prior for comparison. The default value is |
weight.rMAP |
Weight assigned to the informative prior component
( |
theta |
A vector of the response rate (binary endpoints) or mean (continuous endpoints) for the control arm. |
theta.t |
A vector of the response rate (binary endpoints) or mean (continuous endpoints) for the treatment arm. |
alternative |
Direction of the posterior decision. Must be one of
|
margin |
Clinical margin. Must be a non-negative scalar. The default
value is |
rel.tol |
Tolerance passed to numerical root finding. |
oc_rel.tol |
Relative tolerance passed to operating characteristic evaluation. |
interval |
Search interval for the posterior probability cutoff. |
n_sd_int |
Half-width of the numerical integration region for each arm, expressed as a multiple of the corresponding standard error. Used for continuous endpoints only. |
... |
Additional parameters. For continuous endpoints, this includes
|
Compared with the original simulation-based implementation, this function does not rely on trial simulation. Instead, it first calibrates the posterior probability cutoff for each borrowing method to achieve the target type I error, and then evaluates operating characteristics analytically across the requested scenarios.
For each borrowing method, the function first calibrates the posterior
probability cutoff so that the repeated-sampling rejection probability under
the boundary null scenario equals the target type I error target.
Specifically, calibration is based on the first value of theta. Let
denote the control-arm parameter under the
calibration scenario. Then the treatment-arm parameter is set to
when alternative = "greater", and
to when alternative = "less".
Thus, when margin = 0, calibration is performed under the null
scenario , corresponding to no treatment effect
difference between the treatment and control arms. After the cutoff is
calibrated, the function evaluates the operating characteristics across all
requested scenarios using the analytical two-arm engines.
A data frame with one row per scenario-method combination. The columns are:
Scenario index.
True control-arm parameter value.
True treatment-arm parameter value.
Borrowing method, one of "NP", "rMAP", or "SAM".
Calibrated posterior probability cutoff for the method.
Bias of the posterior mean estimator of .
Root mean squared error of the posterior mean estimator of .
Average borrowing weight under the method.
Repeated-sampling rejection probability.
Yang P, Zhao Y, Nie L, Vallejo J, Yuan Y. SAM: Self-adapting mixture prior to dynamically borrow information from historical data in clinical trials. Biometrics 2023;79(4):2857-2868.
Schmidli H, Gsteiger S, Roychoudhury S, O'Hagan A, Spiegelhalter D, Neuenschwander B. Robust meta-analytic-predictive priors in clinical trials with historical control information. Biometrics 2014;70(4):1023-1032.
eval_oc_bin_2arm,
eval_oc_cont_2arm, calibrate_cutoff_bin_2arm,
calibrate_cutoff_cont_2arm
## Example: operating characteristics for a two-arm binary trial ## using a SAM prior without rMAP comparison ## Informative prior constructed from historical data if.prior <- mixbeta(c(1, 20, 40)) ## Evaluate operating characteristics OC <- get_OC( if.prior = if.prior, nf.prior = mixbeta(c(1, 1, 1)), ## Non-informative prior for control mixture prior.t = mixbeta(c(1, 1, 1)), ## Prior for treatment arm delta = 0.2, ## Clinically significant difference for SAM n = 50, ## Sample size for control arm n.t = 100, ## Sample size for treatment arm target = 0.05, ## Target type I error for cutoff calibration if.rMAP = FALSE, ## Do not include rMAP comparison theta = c(summary(if.prior)["mean"], summary(if.prior)["mean"]), theta.t = c(summary(if.prior)["mean"], 0.50), alternative = "greater", ## Superiority test margin = 0 ## Clinical margin ) OC## Example: operating characteristics for a two-arm binary trial ## using a SAM prior without rMAP comparison ## Informative prior constructed from historical data if.prior <- mixbeta(c(1, 20, 40)) ## Evaluate operating characteristics OC <- get_OC( if.prior = if.prior, nf.prior = mixbeta(c(1, 1, 1)), ## Non-informative prior for control mixture prior.t = mixbeta(c(1, 1, 1)), ## Prior for treatment arm delta = 0.2, ## Clinically significant difference for SAM n = 50, ## Sample size for control arm n.t = 100, ## Sample size for treatment arm target = 0.05, ## Target type I error for cutoff calibration if.rMAP = FALSE, ## Do not include rMAP comparison theta = c(summary(if.prior)["mean"], summary(if.prior)["mean"]), theta.t = c(summary(if.prior)["mean"], 0.50), alternative = "greater", ## Superiority test margin = 0 ## Clinical margin ) OC
The post_summary_bin_2arm function is designed to compute the
posterior summary for the treatment effect in a two-arm comparative trial
with a binary endpoint under one of three borrowing strategies:
self-adapting mixture prior (SAM), robust MAP prior with fixed weight
(rMAP), or non-informative prior (NP).
post_summary_bin_2arm( x.t, x, if.prior, nf.prior, prior.t = nf.prior, n.t, n, delta, cutoff, method = c("SAM", "rMAP", "NP"), alternative = c("greater", "less"), margin = 0, weight_rMAP = 0.5, method.w = "LRT", prior.odds = 1, rel.tol = 1e-08 )post_summary_bin_2arm( x.t, x, if.prior, nf.prior, prior.t = nf.prior, n.t, n, delta, cutoff, method = c("SAM", "rMAP", "NP"), alternative = c("greater", "less"), margin = 0, weight_rMAP = 0.5, method.w = "LRT", prior.odds = 1, rel.tol = 1e-08 )
x.t |
Observed number of responses in the treatment arm. |
x |
Observed number of responses in the control arm. |
if.prior |
Informative prior constructed based on historical data for the control arm, represented (approximately) as a beta mixture prior. |
nf.prior |
Non-informative prior used as the robustifying component for the control arm prior. |
prior.t |
Prior used for the treatment arm. If missing, the default
value is set to be |
n.t |
Sample size for the treatment arm. |
n |
Sample size for the control arm. |
delta |
Clinically significant difference used for the SAM prior.
This argument is only used when |
cutoff |
Posterior probability cutoff used for decision making.
The null hypothesis is rejected if the posterior tail probability
exceeds |
method |
Borrowing strategy for the control arm. Must be one of
|
alternative |
Direction of the posterior decision. Must be one of
|
margin |
Clinical margin. Must be a non-negative scalar. The default
value is |
weight_rMAP |
Weight assigned to the informative prior component
( |
method.w |
Methods used to determine the mixture weight for SAM priors.
The default method is "LRT" (Likelihood Ratio Test), the alternative option
is "PPR" (Posterior Probability Ratio). See |
prior.odds |
The prior probability of |
rel.tol |
Relative tolerance for numerical integration used to evaluate the posterior probability. |
The treatment effect is defined as , where
and denote the response rates in the treatment
and control arms, respectively. Inference is based on the posterior
distribution of given the observed response counts from the two
arms.
The posterior for the treatment arm is obtained by updating
prior.t using the observed response count x.t. The posterior
for the control arm depends on the selected borrowing strategy:
SAM: the prior for the control arm is a mixture of
if.prior and nf.prior, with adaptive mixture weight
determined by the SAM borrowing rule.
rMAP: the prior for the control arm is a fixed mixture of
if.prior and nf.prior, with fixed weight
weight_rMAP.
NP: the prior for control arm is nf.prior.
When alternative = "greater", inference is based on
. When
alternative = "less", inference is based on
.
The posterior mean and posterior variance of are defined as
and
where independence between the treatment and control arm posteriors is assumed conditional on the current and historical data.
A list containing the posterior probability in the requested
direction, posterior mean and variance of ,
decision indicator, borrowing weight used for the control arm prior,
and the corresponding trial data and method information.
The post_summary_cont_2arm function is designed to compute the
posterior summary for the treatment effect in a two-arm comparative trial
with a continuous endpoint under one of three borrowing strategies:
self-adapting mixture prior (SAM), robust MAP prior with fixed weight
(rMAP), or non-informative prior (NP).
post_summary_cont_2arm( ybar_t, ybar, if.prior, nf.prior, prior.t = nf.prior, n.t, n, sigma.t, sigma, delta, cutoff, method = c("SAM", "rMAP", "NP"), alternative = c("greater", "less"), margin = 0, weight_rMAP = 0.5, method.w = "LRT", prior.odds = 1 )post_summary_cont_2arm( ybar_t, ybar, if.prior, nf.prior, prior.t = nf.prior, n.t, n, sigma.t, sigma, delta, cutoff, method = c("SAM", "rMAP", "NP"), alternative = c("greater", "less"), margin = 0, weight_rMAP = 0.5, method.w = "LRT", prior.odds = 1 )
ybar_t |
Observed sample mean in the treatment arm. |
ybar |
Observed sample mean in the control arm. |
if.prior |
Informative prior constructed based on historical data for the control arm, represented (approximately) as a normal mixture prior. |
nf.prior |
Non-informative prior used as the robustifying component for the control arm prior. |
prior.t |
Prior used for the treatment arm. If missing, the default
value is set to be |
n.t |
Sample size for the treatment arm. |
n |
Sample size for the control arm. |
sigma.t |
Known standard deviation in the treatment arm. |
sigma |
Known standard deviation in the control arm. |
delta |
Clinically significant difference used for the SAM prior.
This argument is only used when |
cutoff |
Posterior probability cutoff used for decision making.
The null hypothesis is rejected if the posterior tail probability
exceeds |
method |
Borrowing strategy for the control arm. Must be one of
|
alternative |
Direction of the posterior decision. Must be one of
|
margin |
Clinical margin. Must be a non-negative scalar. The default
value is |
weight_rMAP |
Weight assigned to the informative prior component
( |
method.w |
Methods used to determine the mixture weight for SAM priors.
The default method is "LRT" (Likelihood Ratio Test), the alternative option
is "PPR" (Posterior Probability Ratio). See |
prior.odds |
The prior probability of |
The treatment effect is defined as , where
and denote the means in the treatment and
control arms, respectively. Inference is based on the posterior distribution
of given the observed sample means from the two arms.
The posterior for the treatment arm is obtained by updating
prior.t using the observed sample mean ybar_t. The posterior
for the control arm depends on the selected borrowing strategy:
SAM: the control arm prior is a mixture of if.prior
and nf.prior, with adaptive mixture weight determined by the
SAM borrowing rule.
rMAP: the control arm prior is a fixed mixture of
if.prior and nf.prior, with fixed weight
weight_rMAP.
NP: the control arm prior is nf.prior only.
When alternative = "greater", inference is based on
. When
alternative = "less", inference is based on
.
The posterior mean and posterior variance of are defined as
are defined as
and
where independence between the treatment and control arm posteriors is assumed conditional on the current and historical data.
A list containing the posterior probability in the requested
direction, posterior mean and variance of , decision indicator,
borrowing weight used for the control arm prior, and the corresponding
trial data and method information.
The PS_prior function is designed to calculate the Propensity Score-Integrated
(PS) informative prior constructed based on historical data.
PS_prior( formula, data, outcome, study, treat, method, distance, ratio, ps.method, trim ) PS_prior.default( formula, data, outcome, study, treat, method, distance, ratio, ps.method, trim ) PS_prior.beta( formula, data, outcome, study, treat, method, distance, ratio, ps.method, trim ) PS_prior.norm( formula, data, outcome, study, treat, method, distance, ratio, ps.method, trim )PS_prior( formula, data, outcome, study, treat, method, distance, ratio, ps.method, trim ) PS_prior.default( formula, data, outcome, study, treat, method, distance, ratio, ps.method, trim ) PS_prior.beta( formula, data, outcome, study, treat, method, distance, ratio, ps.method, trim ) PS_prior.norm( formula, data, outcome, study, treat, method, distance, ratio, ps.method, trim )
formula |
A two-sided |
data |
A data frame containing the variables named in |
outcome |
The variable name of the outcome. |
study |
The variable name of the study indicator. |
treat |
The variable name of the treatment indicator. |
method |
The matching method to be used. The allowed methods are
|
distance |
The distance measure to be used. Can be either the name of a
method of estimating propensity scores (e.g., |
ratio |
For methods that allow it, how many historical control units should be
matched to each current control unit in |
ps.method |
PS method utilize to calculate an informative prior
based on historical data. The allowed methods are |
trim |
Lower and upper bound of trimming used in |
This function aims to calculate informative priors using historical data by incorporating covariate information to enhance borrowing strength and address prior-data conflicts.
Let be the study indicator, where indicate patient is
from current control study, and indicate patient is from
historical control study. Given the covariates data , the propensity
score is defined as follows,
where distance allows different methods to estimate the propensity scores.
Calculate informative prior through PS matching is to identify a subset of
historical data () that have similar PS as current control data
(). Various algorithms are available for PS matching, please refer
to method. The informative prior can then be calculated based on
the matched historical dataset.
Alternative, we can utilize the inverse probability of treatment weighting
(IPTW) to adjust the distribution of in historical data ,
making it similar to that in . Specifically, for the th
subject, we assign a weight to the outcome in
based on its PS and a fixed weight
to in , as follows:
To avoid extremely large weights that may compromise IPTW, symmetric
trimming rule can be used to trim the tails of the PS distribution by
input trim with default [0.1,0.9], that is to trim observations
whose estimated PS is outside of this range.
To standardized , we compute the effective sample size (ESS),
which approximately reflects the level of precision or equivalently its
sample size, retained in the sample after weight as
. The standardized weight
is given by
For binary endpoint , the informative
prior can be constructed as follows,
where is a non-informative prior, a natural choice is
, with .
For continuous endpoint , suppose
is unknown, with non-informative prior ,
follows a student- distribution with degree of
freedom . Given that is moderate and large,
it can be approximated by a normal distribution
with
Displays the informative prior calculated from historical data based on the selected PS method.
PS_prior.default(): The function calculates the Propensity Score-Integrated
informative prior based on historical data for binary and continuous endpoint.
PS_prior.beta(): The function calculates the Propensity Score-Integrated
informative prior based on historical data for binary endpoint.
PS_prior.norm(): The function calculates the Propensity Score-Integrated
informative prior based on historical data for continuous endpoint.
Zhao Y, Laird G, Chen J, Yuan Y. PS-SAM: doubly robust propensity-score-integrated self-adapting mixture prior to dynamically borrow information from historical data.
## Load example data data('PS_SAM_data') ## Subset the data to contain historical data and current control dat <- PS_SAM_data[PS_SAM_data$A == 0, ] str(dat) ## Examples for binary endpoints ## Generate the informative prior based on historical data using PS Matching summary(PS_prior(formula = 'G ~ X_1 + X_2 + X_3', data = dat, ps.method = 'Matching', method = 'nearest', outcome = 'Y_binary', study = 'G', treat = 'A')) ## Generate the informative prior based on historical data using PS Weighting summary(PS_prior(formula = 'G ~ X_1 + X_2 + X_3', data = dat, ps.method = 'Weighting', outcome = 'Y_binary', study = 'G', treat = 'A')) ## Examples for continuous endpoints ## Generate the informative prior based on historical data using PS Matching summary(PS_prior(formula = 'G ~ X_1 + X_2 + X_3', data = dat, ps.method = 'Matching', method = 'nearest', outcome = 'Y_continuous', study = 'G', treat = 'A')) ## Generate the informative prior based on historical data using PS Weighting summary(PS_prior(formula = 'G ~ X_1 + X_2 + X_3', data = dat, ps.method = 'Weighting', outcome = 'Y_continuous', study = 'G', treat = 'A'))## Load example data data('PS_SAM_data') ## Subset the data to contain historical data and current control dat <- PS_SAM_data[PS_SAM_data$A == 0, ] str(dat) ## Examples for binary endpoints ## Generate the informative prior based on historical data using PS Matching summary(PS_prior(formula = 'G ~ X_1 + X_2 + X_3', data = dat, ps.method = 'Matching', method = 'nearest', outcome = 'Y_binary', study = 'G', treat = 'A')) ## Generate the informative prior based on historical data using PS Weighting summary(PS_prior(formula = 'G ~ X_1 + X_2 + X_3', data = dat, ps.method = 'Weighting', outcome = 'Y_binary', study = 'G', treat = 'A')) ## Examples for continuous endpoints ## Generate the informative prior based on historical data using PS Matching summary(PS_prior(formula = 'G ~ X_1 + X_2 + X_3', data = dat, ps.method = 'Matching', method = 'nearest', outcome = 'Y_continuous', study = 'G', treat = 'A')) ## Generate the informative prior based on historical data using PS Weighting summary(PS_prior(formula = 'G ~ X_1 + X_2 + X_3', data = dat, ps.method = 'Weighting', outcome = 'Y_continuous', study = 'G', treat = 'A'))
This dataset demonstrates the construction of a Propensity Score-Integrated (PS) SAM prior. It simulates a two-arm randomized clinical trial (RCT) with a 2:1 randomization ratio between treatment and control arms, considering both binary and continuous endpoints.
PS_SAM_dataPS_SAM_data
A data frame with 600 observations.
"A" is the treatment assignment (1 = treated, 0 = control).
"G" is the study indicator (1 = current, 0 = historical).
"" is a binary covariate.
"" is a continuous covariate.
"" is a continuous covariate.
"" is binary outcome.
"" is continuous outcome.
The dataset includes:
Sample size for treatment arm: .
Sample size for control arm: .
Sample size for historical control study: .
Covariates for the control arm were generated from
where stands for Bernoulli distribution. Covariates for the
historical controls were generated from a mixture distribution, with half
were generated the same as for the control arm, while the other half were
drawn from
For the binary endpoint, were generated from the logit model:
where is the treatment effect size, and we let
to generate a moderate treatment effect size so that they study has a reasonable
power.
For the continuous endpoint, were generated from the following
normal model:
where we let , and .
This dataset enables evaluation of the PS-SAM prior's performance in addressing heterogeneity between the RCT control arm and historical controls.
# Load the dataset data(PS_SAM_data) # View the structure str(PS_SAM_data)# Load the dataset data(PS_SAM_data) # View the structure str(PS_SAM_data)
The SAM_prior function is designed to display the SAM prior, given
the informative prior (constructed from historical data), non-informative
prior, and the mixture weight calculated using SAM_weight
function (Yang, et al., 2023).
SAM_prior(if.prior, nf.prior, weight, ...) ## S3 method for class 'betaMix' SAM_prior(if.prior, nf.prior, weight, ...) ## S3 method for class 'gammaMix' SAM_prior(if.prior, nf.prior, weight, ...) ## S3 method for class 'normMix' SAM_prior(if.prior, nf.prior, weight, ..., sigma)SAM_prior(if.prior, nf.prior, weight, ...) ## S3 method for class 'betaMix' SAM_prior(if.prior, nf.prior, weight, ...) ## S3 method for class 'gammaMix' SAM_prior(if.prior, nf.prior, weight, ...) ## S3 method for class 'normMix' SAM_prior(if.prior, nf.prior, weight, ..., sigma)
if.prior |
Informative prior constructed from historical data, represented (approximately) as a mixture of conjugate distributions. |
nf.prior |
Non-informative prior used for the mixture. |
weight |
Weight assigned to the informative prior component
( |
... |
Additional parameters required for different endpoints. |
sigma |
Variance used for constructing the non-informative prior for continuous endpoints. |
SAM prior is constructed by mixing an informative prior
, constructed based on historical data, with a
non-informative prior using the mixture weight
determined by SAM_weight function to achieve the
degree of prior-data conflict (Schmidli et al., 2015, Yang et al., 2023).
Let and denote the treatment effects
associated with the current arm data and historical data ,
respectively. Let denote the clinically significant difference
such that if , then is
regarded as clinically distinct from , and it is therefore
inappropriate to borrow any information from . Consider two
hypotheses:
represents that and are consistent (i.e.,
no prior-data conflict) and thus information borrowing is desirable,
whereas represents that the treatment effect of
differs from to such a degree that no information should be
borrowed.
The SAM prior uses the likelihood ratio test (LRT) statistics to
quantify the degree of prior-data conflict and determine the extent of
information borrowing.
where denotes the likelihood function. An alternative
Bayesian choice is the posterior probability ratio (PPR):
where and is the prior probabilities of
and being true. is the Bayes Factor that in this case
is the same as the LRT.
The SAM prior, denoted as , is then defined
as a mixture of an informative prior , constructed
based on and a non-informative prior :
where the mixture weight is calculated as:
As the level of prior-data conflict increases, the likelihood ratio
decreases, resulting in a decrease in the weight
assigned to the informative prior and thus a decrease in information
borrowing. As a result, is data-driven and
has the ability to self-adapt the information borrowing based on the
degree of prior-data conflict.
Displays the SAM prior as a mixture of an informative prior (constructed based on the historical data) and a non-informative prior.
SAM_prior(betaMix): The function calculates the SAM prior for beta
mixture distribution. The default nf.prior is set to be
mixbeta(c(1,1,1)) which represents a uniform prior Beta(1,1).
SAM_prior(gammaMix): The function calculates the SAM prior for gamma
mixture distribution. The default nf.prior is set to be
mixgamma(c(1,0.001,0.001)) which represents a vague gamma prior
Gamma(0.001,0.001).
SAM_prior(normMix): The function calculates the SAM prior for normal
mixture distribution. The default nf.prior is set to be
mixnorm(c(1,summary(if.prior)['mean'], sigma)) which represents a
unit-information prior.
Yang P, Zhao Y, Nie L, Vallejo J, Yuan Y. SAM: Self-adapting mixture prior to dynamically borrow information from historical data in clinical trials. Biometrics 2023; 79(4), 2857-2868.
Schmidli H, Gsteiger S, Roychoudhury S, O'Hagan A, Spiegelhalter D, Neuenschwander B. Robust meta-analytic-predictive priors in clinical trials with historical control information. Biometrics 2014; 70(4):1023-1032.
set.seed(123) ## Examples for binary endpoints ## Suppose that the informative prior constructed based on historical data is ## beta(40, 60) prior.historical <- mixbeta(c(1, 40, 60)) ## Data of the control arm data.control <- rbinom(60, size = 1, prob = 0.42) ## Calculate the mixture weight of the SAM prior wSAM <- SAM_weight(if.prior = prior.historical, delta = 0.15, ## Clinically significant difference data = data.control ## Control arm data ) ## Assume beta(1,1) as the non-informative prior used for mixture nf.prior <- mixbeta(nf.prior = c(1,1,1)) ## Generate the SAM prior SAM.prior <- SAM_prior(if.prior = prior.historical, ## Informative prior nf.prior = nf.prior, ## Non-informative prior weight = wSAM ## Mixture weight of the SAM prior ) plot(SAM.prior) ## Examples for continuous endpoints ## Suppose that the informative prior constructed based on historical data is ## N(0, 3) sigma <- 3 prior.mean <- 0 prior.se <- sigma/sqrt(100) prior.historical <- mixnorm(c(1, prior.mean, prior.se), sigma = sigma) ## Data of the control arm data.control <- rnorm(80, mean = 0, sd = sigma) ## Calculate the mixture weight of the SAM prior wSAM <- SAM_weight(if.prior = prior.historical, delta = 0.2 * sigma, ## Clinically significant difference data = data.control ## Control arm data ) ## Assume unit-information prior N(0,3) as the non-informative prior used ## for the mixture nf.prior <- mixnorm(nf.prior = c(1,prior.mean, sigma), sigma = sigma) ## Generate the SAM prior SAM.prior <- SAM_prior(if.prior = prior.historical, ## Informative prior nf.prior = nf.prior, ## Non-informative prior weight = wSAM ## Mixture weight of the SAM prior ) plot(SAM.prior)set.seed(123) ## Examples for binary endpoints ## Suppose that the informative prior constructed based on historical data is ## beta(40, 60) prior.historical <- mixbeta(c(1, 40, 60)) ## Data of the control arm data.control <- rbinom(60, size = 1, prob = 0.42) ## Calculate the mixture weight of the SAM prior wSAM <- SAM_weight(if.prior = prior.historical, delta = 0.15, ## Clinically significant difference data = data.control ## Control arm data ) ## Assume beta(1,1) as the non-informative prior used for mixture nf.prior <- mixbeta(nf.prior = c(1,1,1)) ## Generate the SAM prior SAM.prior <- SAM_prior(if.prior = prior.historical, ## Informative prior nf.prior = nf.prior, ## Non-informative prior weight = wSAM ## Mixture weight of the SAM prior ) plot(SAM.prior) ## Examples for continuous endpoints ## Suppose that the informative prior constructed based on historical data is ## N(0, 3) sigma <- 3 prior.mean <- 0 prior.se <- sigma/sqrt(100) prior.historical <- mixnorm(c(1, prior.mean, prior.se), sigma = sigma) ## Data of the control arm data.control <- rnorm(80, mean = 0, sd = sigma) ## Calculate the mixture weight of the SAM prior wSAM <- SAM_weight(if.prior = prior.historical, delta = 0.2 * sigma, ## Clinically significant difference data = data.control ## Control arm data ) ## Assume unit-information prior N(0,3) as the non-informative prior used ## for the mixture nf.prior <- mixnorm(nf.prior = c(1,prior.mean, sigma), sigma = sigma) ## Generate the SAM prior SAM.prior <- SAM_prior(if.prior = prior.historical, ## Informative prior nf.prior = nf.prior, ## Non-informative prior weight = wSAM ## Mixture weight of the SAM prior ) plot(SAM.prior)
The SAM_weight function is designed to calculate the mixture
weight of the SAM priors according to the degree of prior-data
conflicts (Yang, et al., 2023).
SAM_weight(if.prior, theta.h, method.w, prior.odds, data, delta, ...) ## S3 method for class 'betaMix' SAM_weight(if.prior, theta.h, method.w, prior.odds, data, delta, n, r, ...) ## S3 method for class 'normMix' SAM_weight( if.prior, theta.h, method.w, prior.odds, data, delta, m, n, sigma, ... ) ## S3 method for class 'gammaMix' SAM_weight(if.prior, theta.h, method.w, prior.odds, data, delta, u, w, ...)SAM_weight(if.prior, theta.h, method.w, prior.odds, data, delta, ...) ## S3 method for class 'betaMix' SAM_weight(if.prior, theta.h, method.w, prior.odds, data, delta, n, r, ...) ## S3 method for class 'normMix' SAM_weight( if.prior, theta.h, method.w, prior.odds, data, delta, m, n, sigma, ... ) ## S3 method for class 'gammaMix' SAM_weight(if.prior, theta.h, method.w, prior.odds, data, delta, u, w, ...)
if.prior |
Informative prior constructed based on historical data, represented (approximately) as a mixture of conjugate distributions. |
theta.h |
Estimate of the treatment effect based on historical data.
If missing, the default value is set to be the posterior mean estimate from
|
method.w |
Methods used to determine the mixture weight for SAM priors. The default method is "LRT" (Likelihood Ratio Test), the alternative option is "PPR" (Posterior Probability Ratio). See Details section for more information. |
prior.odds |
The prior probability of |
data |
Data of the control arm from the current trial, see Methods section for more details. |
delta |
Clinically significant difference used for the SAM prior. |
... |
Additional parameters required for different endpoints. |
n |
Number of subjects in the control arm for continuous endpoint. |
r |
Number of responses in the control arm for binary endpoint. |
m |
Mean estimate in the control arm for continuous endpoint. |
sigma |
Standard deviation in the control arm for continuous endpoint. |
u |
Number of events in the control arm for time-to-event endpoint. |
w |
Total observed time in the control arm for time-to-event endpoint. |
SAM prior is constructed by mixing an informative prior
, constructed based on historical data, with a
non-informative prior using the mixture weight
determined by SAM_weight function to achieve the
degree of prior-data conflict (Schmidli et al., 2015, Yang et al., 2023).
Let and denote the treatment effects
associated with the current arm data and historical data ,
respectively. Let denote the clinically significant difference
such that if , then is
regarded as clinically distinct from , and it is therefore
inappropriate to borrow any information from . Consider two
hypotheses:
represents that and are consistent (i.e.,
no prior-data conflict) and thus information borrowing is desirable,
whereas represents that the treatment effect of
differs from to such a degree that no information should be
borrowed.
The SAM prior uses the likelihood ratio test (LRT) statistics to
quantify the degree of prior-data conflict and determine the extent of
information borrowing.
where denotes the likelihood function. An alternative
Bayesian choice is the posterior probability ratio (PPR):
where and is the prior probabilities of
and being true. is the Bayes Factor that in this case
is the same as the LRT.
The SAM prior, denoted as , is then defined
as a mixture of an informative prior , constructed
based on and a non-informative prior :
where the mixture weight is calculated as:
As the level of prior-data conflict increases, the likelihood ratio
decreases, resulting in a decrease in the weight
assigned to the informative prior and thus a decrease in information
borrowing. As a result, is data-driven and
has the ability to self-adapt the information borrowing based on the
degree of prior-data conflict.
The mixture weight of the SAM priors.
SAM_weight(betaMix): The function calculates the mixture weight of SAM
priors for beta mixture distribution. The input data can be patient-level
data (i.e., a vector of 0 and 1 representing the response status of each
patient) or summary statistics (i.e., the number of patients and the number
of responses).
SAM_weight(normMix): The function calculates the mixture weight of SAM
priors for normal mixture distribution. The input data should be
a vector of patient-level observations. The input data can be
patient-level data (i.e., a vector of continuous response of each
patient) or summary statistics (i.e., the mean estimate, number of subjects,
and the standard deviation in the control arm).
SAM_weight(gammaMix): The function calculates the mixture weight of SAM
priors for gamma mixture distribution. The input data can be
patient-level data (i.e., a matrix with the first row as the censoring
indicator and the second row recording the observed time) or summary
statistics (i.e., the number of uncensored observations u and
total observed time w).
Yang P, Zhao Y, Nie L, Vallejo J, Yuan Y. SAM: Self-adapting mixture prior to dynamically borrow information from historical data in clinical trials. Biometrics 2023; 79(4), 2857-2868.
set.seed(123) ## Examples for binary endpoints ## Example 1: no prior-data conflict ## Suppose that the informative prior constructed based on historical data is ## beta(40, 60) prior.historical <- mixbeta(c(1, 40, 60)) ## Data of control arm data.control <- rbinom(60, size = 1, prob = 0.42) ## Calculate the mixture weight of the SAM prior wSAM <- SAM_weight(if.prior = prior.historical, delta = 0.15, ## Clinically significant difference data = data.control ## Control arm data ) print(wSAM) ## Example 2: in the presence of prior-data conflict, where the current data ## has 12 responses in 60 patients wSAM <- SAM_weight(if.prior = prior.historical, delta = 0.15, ## Clinically significant difference ## Methods to determine mixture weight for the SAM priors ## by Posterior Probability Ratio method.w = 'PPR', ## Prior odds of favoring no prior-data conflicts to ## the presence of prior-data conflict prior.odd = 1/9, n = 60, ## Number of patients in the control arm r = 12 ## Number of responses in the control arm ) print(wSAM) ## Example 3: in the presence of prior-data conflict, where the current data ## has 12 responses in 60 patients wSAM <- SAM_weight(if.prior = prior.historical, delta = 0.15, ## Clinically significant difference n = 60, ## Number of patients in the control arm r = 12 ## Number of responses in the control arm ) print(wSAM) ## Examples for continuous endpoints ## Example 1: no prior-data conflict ## Suppose that the informative prior constructed from historical data is ## N(0, 3) sigma <- 3 prior.mean <- 0 prior.se <- sigma/sqrt(100) prior.historical <- mixnorm(c(1, prior.mean, prior.se), sigma = sigma) ## Data of the control arm data.control <- rnorm(80, mean = 0, sd = sigma) wSAM <- SAM_weight(if.prior = prior.historical, delta = 0.3 * sigma, ## Clinically significant difference data = data.control ## Control arm data ) print(wSAM) ## Example 2: in the presence of prior-data conflict, where the current data ## has mean of 0.5 data.control <- rnorm(80, mean = 1, sd = sigma) wSAM <- SAM_weight(if.prior = prior.historical, delta = 0.3 * sigma, ## Clinically significant difference data = data.control ## Control arm data ) print(wSAM) ## Examples for survival endpoints ## Example 1: no prior-data conflict ## Suppose the survival times from historical data follows exp(1) distribution ## with random censoring time follows U(0.5, 5) distribution T_hi <- rexp(100, rate = 1) C_hi <- runif(100, min = 0.5, max = 5) ## Indicators of the uncensored events delta_hi <- as.numeric(T_hi < C_hi) ## Observed survival times from historical data U_hi <- T_hi U_hi[delta_hi == 0] <- C_hi[delta_hi == 0] ## Construct the informative prior based on simulated historical data prior.historical <- mixgamma(c(1, sum(delta_hi), sum(U_hi)), param = 'ab', likelihood = 'exp') ## Suppose the survival times from control data follows exp(0.95) distribution ## with random censoring time follows U(0.5, 5) distribution T_ci <- rexp(100, rate = 0.95) C_ci <- runif(100, min = 0.5, max = 5) ## Indicators of the uncensored events delta_ci <- as.numeric(T_ci < C_ci) ## Observed survival times from control data U_ci <- T_ci U_ci[delta_ci == 0] <- C_ci[delta_ci == 0] ## Data of the control arm data.control <- rbind(sum(delta_ci), sum(U_ci)) wSAM <- SAM_weight(if.prior = prior.historical, delta = 0.2, ## Clinically significant difference data = data.control ## Control arm data ) print(wSAM) ## Example 2: in the presence of prior-data conflict, where the current survival ## times follows exp(2) distribution with random censoring time follows U(0.5, 5) ## distribution T_ci <- rexp(100, rate = 2) C_ci <- runif(100, min = 0.5, max = 5) ## Indicators of the uncensored events delta_ci <- as.numeric(T_ci < C_ci) ## Observed survival times from control data U_ci <- T_ci U_ci[delta_ci == 0] <- C_ci[delta_ci == 0] ## Data of the control arm data.control <- rbind(sum(delta_ci), sum(U_ci)) wSAM <- SAM_weight(if.prior = prior.historical, delta = 0.2, ## Clinically significant difference data = data.control ## Control arm data ) print(wSAM)set.seed(123) ## Examples for binary endpoints ## Example 1: no prior-data conflict ## Suppose that the informative prior constructed based on historical data is ## beta(40, 60) prior.historical <- mixbeta(c(1, 40, 60)) ## Data of control arm data.control <- rbinom(60, size = 1, prob = 0.42) ## Calculate the mixture weight of the SAM prior wSAM <- SAM_weight(if.prior = prior.historical, delta = 0.15, ## Clinically significant difference data = data.control ## Control arm data ) print(wSAM) ## Example 2: in the presence of prior-data conflict, where the current data ## has 12 responses in 60 patients wSAM <- SAM_weight(if.prior = prior.historical, delta = 0.15, ## Clinically significant difference ## Methods to determine mixture weight for the SAM priors ## by Posterior Probability Ratio method.w = 'PPR', ## Prior odds of favoring no prior-data conflicts to ## the presence of prior-data conflict prior.odd = 1/9, n = 60, ## Number of patients in the control arm r = 12 ## Number of responses in the control arm ) print(wSAM) ## Example 3: in the presence of prior-data conflict, where the current data ## has 12 responses in 60 patients wSAM <- SAM_weight(if.prior = prior.historical, delta = 0.15, ## Clinically significant difference n = 60, ## Number of patients in the control arm r = 12 ## Number of responses in the control arm ) print(wSAM) ## Examples for continuous endpoints ## Example 1: no prior-data conflict ## Suppose that the informative prior constructed from historical data is ## N(0, 3) sigma <- 3 prior.mean <- 0 prior.se <- sigma/sqrt(100) prior.historical <- mixnorm(c(1, prior.mean, prior.se), sigma = sigma) ## Data of the control arm data.control <- rnorm(80, mean = 0, sd = sigma) wSAM <- SAM_weight(if.prior = prior.historical, delta = 0.3 * sigma, ## Clinically significant difference data = data.control ## Control arm data ) print(wSAM) ## Example 2: in the presence of prior-data conflict, where the current data ## has mean of 0.5 data.control <- rnorm(80, mean = 1, sd = sigma) wSAM <- SAM_weight(if.prior = prior.historical, delta = 0.3 * sigma, ## Clinically significant difference data = data.control ## Control arm data ) print(wSAM) ## Examples for survival endpoints ## Example 1: no prior-data conflict ## Suppose the survival times from historical data follows exp(1) distribution ## with random censoring time follows U(0.5, 5) distribution T_hi <- rexp(100, rate = 1) C_hi <- runif(100, min = 0.5, max = 5) ## Indicators of the uncensored events delta_hi <- as.numeric(T_hi < C_hi) ## Observed survival times from historical data U_hi <- T_hi U_hi[delta_hi == 0] <- C_hi[delta_hi == 0] ## Construct the informative prior based on simulated historical data prior.historical <- mixgamma(c(1, sum(delta_hi), sum(U_hi)), param = 'ab', likelihood = 'exp') ## Suppose the survival times from control data follows exp(0.95) distribution ## with random censoring time follows U(0.5, 5) distribution T_ci <- rexp(100, rate = 0.95) C_ci <- runif(100, min = 0.5, max = 5) ## Indicators of the uncensored events delta_ci <- as.numeric(T_ci < C_ci) ## Observed survival times from control data U_ci <- T_ci U_ci[delta_ci == 0] <- C_ci[delta_ci == 0] ## Data of the control arm data.control <- rbind(sum(delta_ci), sum(U_ci)) wSAM <- SAM_weight(if.prior = prior.historical, delta = 0.2, ## Clinically significant difference data = data.control ## Control arm data ) print(wSAM) ## Example 2: in the presence of prior-data conflict, where the current survival ## times follows exp(2) distribution with random censoring time follows U(0.5, 5) ## distribution T_ci <- rexp(100, rate = 2) C_ci <- runif(100, min = 0.5, max = 5) ## Indicators of the uncensored events delta_ci <- as.numeric(T_ci < C_ci) ## Observed survival times from control data U_ci <- T_ci U_ci[delta_ci == 0] <- C_ci[delta_ci == 0] ## Data of the control arm data.control <- rbind(sum(delta_ci), sum(U_ci)) wSAM <- SAM_weight(if.prior = prior.historical, delta = 0.2, ## Clinically significant difference data = data.control ## Control arm data ) print(wSAM)