Fits the covariate-linked gate model using fixed class-conditional mechanistic log-likelihoods.
Usage
mbmm_fit_gate(
logL,
formula,
data,
classes = NULL,
ridge = 1e-04,
penalty = "ridge",
n_perm = 0,
seed = NULL,
id_col = NULL,
maxit = 4000
)Arguments
- logL
Data.frame or matrix of class-conditional log-likelihoods. Columns are normally named
logL_<class>.- formula
One-sided formula defining the gate covariates, such as
~ baseline_antibodyor~ arm.- data
Data.frame containing gate covariates.
- classes
Character vector defining the class order. For two classes,
classes[1]is the positive/event class andclasses[2]is the reference class. For more than two classes, the final class is the multinomial reference class.- ridge
Nonnegative L2 penalty applied to non-intercept coefficients when
penalty = "ridge".- penalty
Either
"ridge"or"none".- n_perm
Number of permutations for an optional permutation p-value. The implemented procedure permutes the complete full-model design matrix and is appropriate only when the tested non-intercept covariates are exchangeable as a block.
- seed
Optional random seed for permutation testing.
- id_col
Optional subject-ID column in
data, copied to the posterior table.- maxit
Maximum number of optimizer iterations.
Details
For a binary latent state, the observed-data marginal likelihood is
$$ \ell(\beta) = \sum_i \log\left[ \pi_i(\beta)L_{i1} + \{1-\pi_i(\beta)\}L_{i0} \right]. $$
The parameters are estimated by direct optimization of this marginal likelihood. An optional ridge penalty can be applied to non-intercept coefficients for numerical stabilization. Ridge is not part of the core MBMM model.
The reported likelihood-ratio statistic is evaluated using the unpenalized observed-data marginal likelihood at the fitted full- and null-model coefficient estimates:
$$ 2\{\ell(\widehat{\beta}_{full}) - \ell(\widehat{\beta}_{null})\}. $$
Examples
set.seed(1)
n <- 150
x <- rnorm(n)
z <- rbinom(
n,
size = 1,
prob = mbmm_inv_logit(-0.5 + 1.5 * x)
)
logL <- data.frame(
logL_pos = ifelse(
z == 1,
log(0.98),
log(0.02)
),
logL_neg = ifelse(
z == 1,
log(0.02),
log(0.98)
)
)
fit <- mbmm_fit_gate(
logL = logL,
formula = ~x,
data = data.frame(x = x),
classes = c("pos", "neg"),
penalty = "ridge",
ridge = 1e-4
)
fit
#> MBMM gate model
#> classes: pos vs neg
#> method: direct-marginal-optimization
#> penalty: ridge
#> ridge: 1e-04
#> n subjects: 150
#> optimizer convergence: full = 0 , null = 0
#> unpenalized logLik: full = -89.1592 , null = -102.353
#> LRT = 26.39 on df = 1 -> p = 2.794e-07
#>
#> Gate coefficients:
#> term estimate odds_ratio
#> (Intercept) -0.3977403 0.6718365
#> x 1.1465444 3.1472984