| Title: | Mixed-Effects Models via the 'mixeff-rs' Rust Crate |
|---|---|
| Description: | Fits linear and generalized linear mixed-effects models from 'lme4'-style formulas, with optimization by the bundled 'mixeff-rs' Rust crate. A fitted model stores the compiled model specification, the optimizer certificate, and per-coefficient inference metadata (method, status, reliability) as data, so a result can be inspected, saved, and reloaded without a live handle to the compiled engine. When an inference method is unavailable for a fit, the affected value is either withheld with a stable reason code or reported under the name of the method actually used, never silently swapped. Vignettes cover migration from 'lme4' and the meaning of random-effects formula syntax. |
| Authors: | Brad Buchsbaum [aut, cre, cph] (author of mixeff and the bundled 'mixeff-rs' crate), Authors of the dependency Rust crates [ctb] (see inst/AUTHORS for details) |
| Maintainer: | Brad Buchsbaum <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.2.0 |
| Built: | 2026-10-10 18:53:55 UTC |
| Source: | https://github.com/bbuchsbaum/mixeff |
With two or more fitted models, anova() performs a sequential
likelihood-ratio comparison (like anova(glmer1, glmer2)). For a single
model, fixed-effect tests are routed to drop1() (term LRTs),
summary() (Wald z), or contrast() (custom Wald contrasts), which the
GLMM contract supports directly.
## S3 method for class 'mm_glmm' anova(object, ...)## S3 method for class 'mm_glmm' anova(object, ...)
object |
A fitted |
... |
Additional fitted models to compare. |
A data frame of class c("mm_anova_comparison", "mm_glmm_comparison", "anova", "data.frame") shaped like anova(glmer1, glmer2): columns npar,
AIC, BIC, logLik, -2*log(L) (lme4 before 2.0 called it
deviance), Chisq, Df, Pr(>Chisq), rows named after the arguments. The underlying comparison
(with the model formulas) is reachable as x$table.
With no extra models, anova() returns a term-level F-test table for
object shaped like lmerTest's: a data frame of class "anova" with
columns Sum Sq, Mean Sq, NumDF, DenDF, F value and Pr(>F)
(rows named by term; Mean Sq = F * sigma^2 and Sum Sq = NumDF * Mean Sq, as in lmerTest). With further fitted models in ..., it returns
lme4's likelihood-ratio table (npar, AIC, BIC, logLik,
-2*log(L), Chisq, Df, Pr(>Chisq), rows named after the arguments;
lme4 before 2.0 called the -2*log(L) column deviance),
computed by compare() (REML fits are refit by ML, as in lme4).
## S3 method for class 'mm_lmm' anova( object, ..., type = c("III", "II", "I", "block"), method = c("auto", "satterthwaite", "kenward_roger", "bootstrap", "asymptotic", "none"), refit_for_comparison = c("auto", "error", "ml"), ddf = NULL )## S3 method for class 'mm_lmm' anova( object, ..., type = c("III", "II", "I", "block"), method = c("auto", "satterthwaite", "kenward_roger", "bootstrap", "asymptotic", "none"), refit_for_comparison = c("auto", "error", "ml"), ddf = NULL )
object |
A fitted |
... |
Optional additional fitted models; triggers |
type |
Term-hypothesis type. |
method |
Degrees-of-freedom / test method. |
refit_for_comparison |
Passed to |
ddf |
lmerTest's spelling of the method: |
mixeff's provenance stays on the result: x$table is the full
term-level (or compare()) table with method, status, reliability and
reason columns, and x$type / x$requested_method record the request.
Rows the engine could not certify keep NA statistics and their reason
is printed under the table.
A data frame of class c("mm_anova", "anova", "data.frame") for
one model, or c("mm_anova_comparison", "mm_model_comparison", "anova", "data.frame") for several.
as_json() returns a JSON string that carries the parsed object's public
R-side state and the raw compiler artifact JSON. saveRDS() / readRDS()
remains the primary persistence path for fitted objects; revive() restores
process-local caches after deserialization.
as_json(x, pretty = FALSE, ...) ## S3 method for class 'mm_compiled' as_json(x, pretty = FALSE, ...)as_json(x, pretty = FALSE, ...) ## S3 method for class 'mm_compiled' as_json(x, pretty = FALSE, ...)
x |
A compiled |
pretty |
Logical; pretty-print JSON when |
... |
Reserved for future methods. |
A length-one character string containing JSON.
audit() returns the user-facing audit report attached to an mm_spec
(pre-fit) or an mm_fit (post-fit). The text is rendered by the upstream Rust crate (the
mixedmodels.model_audit_report schema's Display impl) — Rust authors
the wording, R formats nothing. Routing every printed audit line
through the upstream renderer is what enforces the R9 "no advice
creep" contract: drift in scope notes / tone is visible in one place
rather than scattered across R formatters.
audit(object, ...) ## Default S3 method: audit(object, ...) ## S3 method for class 'mm_compiled' audit(object, ...)audit(object, ...) ## Default S3 method: audit(object, ...) ## S3 method for class 'mm_compiled' audit(object, ...)
object |
An |
... |
Reserved for future methods. |
audit() accepts an mm_spec from
compile_model() or an mm_fit from lmm()/glmm() and emits the report sections (Requested Model,
Model State, Fixed/Random Effects, Information Budget, Dependence
Paths, Parameterization Trace, Effective Covariance, Policy
Recommendations, Optimizer, Inference, Diagnostics). Sections that
depend on a fit (Optimizer / Inference) report not applicable before fitting on a pre-fit spec.
An object of class mm_audit carrying:
textthe rendered report text (a single character string, newline-separated)
summary_textthe compact report rendered by the upstream
ModelAuditReport::render_summary (Audit Summary plus the
Requested Model section)
design_auditthe parsed design_audit field from the
CompiledModelArtifact (random-term audits, fixed-effect rank,
covariance kernel graph, ...) — NULL on uncompilable formulas
reportthe parsed upstream ModelAuditReport v2, including
Rust-authored random_term_cards for downstream explanation verbs
random_term_cardsthe report's per-random-term cards, copied to the top level for convenient inspection
cross_card_constraintsreport-level constraints between random-term cards
diagnosticsthe parsed report diagnostics, falling back to artifact diagnostics when needed
print.mm_audit defaults to the compact upstream-rendered summary in
summary_text. Use print(x, full = TRUE) for the complete upstream
report stored in text.
Raises an mm_schema_error if the supplied object does not carry a
parsed artifact with the expected schema header.
set.seed(1) df <- data.frame( y = rnorm(20), x = rnorm(20), subject = factor(rep(letters[1:5], each = 4)) ) audit(compile_model(y ~ x + (1 + x | subject), df))set.seed(1) df <- data.frame( y = rnorm(20), x = rnorm(20), subject = factor(rep(letters[1:5], each = 4)) ) audit(compile_model(y ~ x + (1 + x | subject), df))
audit()
audit_design() and audit() were two names for one operation; the
surface collapsed to audit() for 0.2.0. This alias forwards with a
deprecation note and will be removed in a future release.
audit_design(spec)audit_design(spec)
spec |
An |
See audit().
Fixed-effect bootstrap control
bootstrap_control( nsim = 999L, seed = NULL, failed_refit_policy = c("exclude", "count_extreme", "abort"), threads = 1L )bootstrap_control( nsim = 999L, seed = NULL, failed_refit_policy = c("exclude", "count_extreme", "abort"), threads = 1L )
nsim |
Requested bootstrap replicate count. |
seed |
Optional integer seed. |
failed_refit_policy |
How failed refits are accounted for. Stable Rust
wire labels are |
threads |
Number of worker threads for the replicate refits
(default |
A list used by contrast(..., method = "bootstrap"),
test_effect(), and confint(..., method = "bootstrap").
The engine simulates every replicate's response serially, in the serial
random-number order, and refits the replicates on threads worker
threads. The result is identical for every threads value; only the
wall-clock time changes. Workers never call into R: the R thread alone
polls for interrupts, so Ctrl-C / Esc still stops the run. The default is
1 because CRAN policy limits packages to at most two threads unless the
user explicitly asks for more; passing threads is that request (for
example threads = parallel::detectCores()).
bootstrap_control(nsim = 199, seed = 1, threads = 2)bootstrap_control(nsim = 199, seed = 1, threads = 2)
changes() summarizes the transitions recorded in the compiler artifact:
requested formula to effective formula, design-time reductions or covariance
transitions, and fitted covariance rank/status from the optimizer
certificate pass.
changes(object, ...) ## S3 method for class 'mm_compiled' changes(object, ...)changes(object, ...) ## S3 method for class 'mm_compiled' changes(object, ...)
object |
A compiled |
... |
Reserved for future methods. |
An mm_change_log object with a data-frame table and the raw
artifact fragments used to build it.
compare() is the namespace-qualified model-comparison front door. For LMMs
it reports likelihood, information criteria, and asymptotic likelihood-ratio
comparisons. REML fits are refit by ML when refit_for_comparison = "auto"
or "ml"; "error" refuses that comparison.
compare(object, ...) ## S3 method for class 'mm_lmm' compare( object, ..., target = c("fixed_effects", "random_effects", "prediction"), method = c("auto", "lrt", "bootstrap", "aic", "kenward_roger", "satterthwaite"), refit_for_comparison = c("auto", "error", "ml"), nsim = 0L, seed = NULL, threads = 1L )compare(object, ...) ## S3 method for class 'mm_lmm' compare( object, ..., target = c("fixed_effects", "random_effects", "prediction"), method = c("auto", "lrt", "bootstrap", "aic", "kenward_roger", "satterthwaite"), refit_for_comparison = c("auto", "error", "ml"), nsim = 0L, seed = NULL, threads = 1L )
object |
A fitted |
... |
Additional fitted |
target |
Comparison target label. |
method |
|
refit_for_comparison |
How to handle REML fits. |
nsim |
Number of bootstrap simulations for |
seed |
Optional bootstrap seed. |
threads |
Worker threads for the bootstrap refits (default 1; see
|
An mm_model_comparison object with a data-frame table.
compare_covariance() is a compact alternate view of the same upstream
random-term cards used by explain_model() and random_options(). For each
current random-term card, it lays out the full, diagonal, and scalar
covariance families without ranking them.
compare_covariance(spec)compare_covariance(spec)
spec |
An |
An object of class mm_compare_covariance with a table data
frame and the upstream cards it was derived from.
compile_model() parses the formula, runs the upstream semantic-IR /
design-audit pipeline against the supplied data, and returns an
mm_spec object — the audit-first analogue of the design-only step in
base lm()'s model.frame() / model.matrix() chain. Nothing is
optimized; nothing is fitted. audit(), explain_model(),
random_options(), and lmm() all consume the same artifact.
compile_model(formula, data)compile_model(formula, data)
formula |
A two-sided lme4-style formula, e.g.
|
data |
A |
The compiled artifact is the structured truth: every print, summary, and audit verb in mixeff reads back from it rather than re-deriving meaning from formula text. R formats; Rust authors wording (PRD §9.6).
Compiling returns a populated mm_spec with the JSON artifact
attached. explain_model(), random_options(), and
compare_covariance() render random-effects guidance from upstream
random-term cards; lmm() and glmm() fit the model itself.
An object inheriting from mm_spec and containing:
callthe matched call
formulathe input formula
varscharacter vector of variables read from data
model_framethe data columns used to compile the artifact, retained so prefit audit views can evaluate nearby formula spellings
artifactparsed JSON artifact (the
mixedmodels.compiled_model_artifact v1 schema)
The raw artifact JSON is attached as attr(spec$artifact, "raw_json")
so the post-compile FFI calls (e.g., the internal
mm_audit_report_text primitive) can round-trip without re-encoding.
Raises typed conditions (all inheriting from mm_condition):
mm_formula_error — formula is not a two-sided R formula or
fails parsing.
mm_data_error — data is not a data.frame, refers to
unknown variables, contains NAs in design columns, or has an
unsupported column type.
mm_schema_error — the artifact JSON returned by Rust does
not match the wrapper's known schema set.
audit() for the printed audit report.
set.seed(1) df <- data.frame( y = rnorm(20), x = rnorm(20), subject = factor(rep(letters[1:5], each = 4)) ) spec <- compile_model(y ~ x + (1 + x | subject), df) audit(spec)set.seed(1) df <- data.frame( y = rnorm(20), x = rnorm(20), subject = factor(rep(letters[1:5], each = 4)) ) spec <- compile_model(y ~ x + (1 + x | subject), df) audit(spec)
Two routes are available. method = "asymptotic" builds Wald intervals
(estimate +/- z * SE) from the Rust fixed-effect inference table; it
requires a certified fit (method = "joint_laplace") or the explicit
working-Hessian opt-in, and refuses the profiled (pirls_profiled) estimator with
a typed reason. method = "bootstrap" runs a parametric bootstrap —
each replicate simulates a response from the fitted model under fresh
random-effect draws and refits the same (effective) estimator — and
returns percentile intervals; it works on profiled-estimator fits for
every supported family, including negative binomial (fixed-theta fits
condition replicates on that theta; estimated-theta fits re-estimate
theta per replicate, propagating its uncertainty). On joint_laplace
fits the bootstrap is refused at this engine pin — replicate refits
cannot re-run the joint estimator — and those fits have certified Wald
intervals instead.
The bootstrap result carries replicate accounting as attributes:
mm_bootstrap (requested, successful, failed, seed, per-parameter
standard errors, Monte Carlo SE, and a reliability grade) and
mm_estimator. Failed replicates are counted, never silently dropped.
Profile intervals are not certified for GLMMs and are refused.
## S3 method for class 'mm_glmm' confint( object, parm, level = 0.95, method = c("asymptotic", "wald", "profile", "bootstrap"), ... )## S3 method for class 'mm_glmm' confint( object, parm, level = 0.95, method = c("asymptotic", "wald", "profile", "bootstrap"), ... )
object |
A fitted |
parm |
Optional fixed-effect names or indices; defaults to all. |
level |
Confidence level. |
method |
|
... |
For |
An mm_confint matrix of lower/upper bounds ("asymptotic"), or
a plain matrix of percentile bounds with bootstrap-accounting
attributes ("bootstrap").
method = "asymptotic" (the default; synonyms "wald" and lme4's
"Wald") gives Wald intervals for the fixed effects from the stored
standard errors. method = "profile" gives profile-likelihood intervals
with lme4's rows and names: .sig01, .sig02, ... (random-effect
standard deviations and correlations, numbered as lme4 >= 2.0 does: term
by term, each term's standard deviations before its correlations),
.sigma, then the fixed effects. As in lme4, every fit is profiled on the
ML deviance: a REML fit's intervals are those of its ML refit. The
engine's relative-Cholesky theta1, ... intervals (on the fit's own
criterion) are kept in attr(ci, "mm_profile")$table and can be
requested by name through parm. When one parameter's profile is
irregular (non-monotone, not bracketing the estimate, or a failed refit),
its undetermined bounds are NA – lme4 would warn and interpolate
linearly, often reporting [-1, 1] for a correlation – and the reason is
in attr(ci, "mm_profile")$table (status, reason_code, reason);
printing the result adds a note. See profile.mm_lmm().
method = "bootstrap" (lme4's
"boot") gives parametric-bootstrap intervals for the fixed effects,
controlled by bootstrap_control().
## S3 method for class 'mm_lmm' confint( object, parm, level = 0.95, method = c("asymptotic", "wald", "bootstrap", "profile"), bootstrap = NULL, interval = c("percentile", "basic"), threads = 1L, ... )## S3 method for class 'mm_lmm' confint( object, parm, level = 0.95, method = c("asymptotic", "wald", "bootstrap", "profile"), bootstrap = NULL, interval = c("percentile", "basic"), threads = 1L, ... )
object |
A fitted |
parm |
Parameters to report: names (fixed-effect names, and for
|
level |
Confidence level. |
method |
|
bootstrap |
Optional |
interval |
Bootstrap interval type, |
threads |
Worker threads for |
... |
Unused. |
lme4's confint.merMod() defaults to method = "profile"; mixeff keeps
the Wald default because the profile refits the model many times
(about the cost of lme4's profile; several seconds for a modest model)
and can refuse on near-singular fits, while the Wald route is free.
Request method = "profile" to reproduce lme4's default output.
An mm_confint matrix of lower/upper bounds.
set.seed(1) d <- data.frame(g = factor(rep(1:10, each = 6)), x = rnorm(60)) d$y <- 1 + 0.5 * d$x + rnorm(10)[d$g] + rnorm(60) fit <- lmm(y ~ x + (1 | g), d, control = mm_control(verbose = -1)) confint(fit) confint(fit, method = "profile")set.seed(1) d <- data.frame(g = factor(rep(1:10, each = 6)), x = rnorm(60)) d$y <- 1 + 0.5 * d$x + rnorm(10)[d$g] + rnorm(60) fit <- lmm(y ~ x + (1 | g), d, control = mm_control(verbose = -1)) confint(fit) confint(fit, method = "profile")
Note: this is not emmeans::contrast. contrast() is mixeff's fixed-effect
contrast front door. R validates the contrast matrix shape, then asks Rust
to evaluate estimability, method prerequisites, standard errors, degrees of
freedom, statistics, p-values, reliability, and unavailable reasons.
## S3 method for class 'mm_glmm' contrast(fit, L, rhs = 0, method = c("asymptotic", "wald"), ...) contrast( fit, L, rhs = 0, method = c("auto", "satterthwaite", "kenward_roger", "bootstrap", "asymptotic", "boundary_lrt", "none"), bootstrap = NULL, ... ) ## S3 method for class 'mm_lmm' contrast( fit, L, rhs = 0, method = c("auto", "satterthwaite", "kenward_roger", "bootstrap", "asymptotic", "boundary_lrt", "none"), bootstrap = NULL, ... )## S3 method for class 'mm_glmm' contrast(fit, L, rhs = 0, method = c("asymptotic", "wald"), ...) contrast( fit, L, rhs = 0, method = c("auto", "satterthwaite", "kenward_roger", "bootstrap", "asymptotic", "boundary_lrt", "none"), bootstrap = NULL, ... ) ## S3 method for class 'mm_lmm' contrast( fit, L, rhs = 0, method = c("auto", "satterthwaite", "kenward_roger", "bootstrap", "asymptotic", "boundary_lrt", "none"), bootstrap = NULL, ... )
fit |
A fitted |
L |
A numeric contrast vector or matrix with one column per fixed effect. |
rhs |
Numeric right-hand side, recycled to the number of contrasts. |
method |
Requested inference method. |
... |
Reserved for future methods. |
bootstrap |
Optional |
For mm_glmm fits, contrasts use an asymptotic Wald z-test built from the
stored fixed-effect covariance (the GLMM contract does not provide
finite-sample df), so method accepts only "asymptotic" (alias "wald").
An mm_contrast object with a data-frame table. The estimate
column is the tested difference, L beta_hat - rhs.
Degrees of freedom for a contrast
df_for_contrast( fit, L, method = c("auto", "satterthwaite", "kenward_roger", "bootstrap", "asymptotic", "none"), ... ) ## S3 method for class 'mm_lmm' df_for_contrast( fit, L, method = c("auto", "satterthwaite", "kenward_roger", "bootstrap", "asymptotic", "none"), ... )df_for_contrast( fit, L, method = c("auto", "satterthwaite", "kenward_roger", "bootstrap", "asymptotic", "none"), ... ) ## S3 method for class 'mm_lmm' df_for_contrast( fit, L, method = c("auto", "satterthwaite", "kenward_roger", "bootstrap", "asymptotic", "none"), ... )
fit |
A fitted |
L |
A contrast vector or matrix. |
method |
Requested degrees-of-freedom method. |
... |
Reserved for future methods. |
An mm_df_for_contrast object with $table (one row per
contrast: contrast, df, method, requested_method, reason),
$df (the named numeric vector), and $method. When the method is
"none" or the engine refuses, df is NA and reason records why.
diagnostics() returns the structured diagnostics carried by a compiled
spec or fitted model artifact. fit_status() is the compact status string
recorded by the optimizer certificate for fitted models.
diagnostics(fit, severity = NULL, stage = NULL, ...) ## S3 method for class 'mm_compiled' diagnostics(fit, severity = NULL, stage = NULL, ...) fit_status(fit, ...) ## S3 method for class 'mm_fit' fit_status(fit, ...) ## S3 method for class 'mm_compiled' fit_status(fit, ...)diagnostics(fit, severity = NULL, stage = NULL, ...) ## S3 method for class 'mm_compiled' diagnostics(fit, severity = NULL, stage = NULL, ...) fit_status(fit, ...) ## S3 method for class 'mm_fit' fit_status(fit, ...) ## S3 method for class 'mm_compiled' fit_status(fit, ...)
fit |
A compiled |
severity |
Optional character vector used to filter diagnostics by severity. |
stage |
Optional character vector used to filter diagnostics by stage. |
... |
Reserved for future methods. |
diagnostics() returns an mm_diagnostics object containing the
raw diagnostic list and a data-frame view. fit_status() returns a
length-one character string.
Refits reduced fixed-effect GLMMs (random-effect terms preserved exactly)
and compares each to the full fit by asymptotic likelihood-ratio test,
mirroring drop1(glmerMod, test = "Chisq").
## S3 method for class 'mm_glmm' drop1(object, scope = NULL, test = c("none", "Chisq"), ...)## S3 method for class 'mm_glmm' drop1(object, scope = NULL, test = c("none", "Chisq"), ...)
object |
A fitted |
scope |
Optional character vector of fixed-effect terms to drop. |
test |
|
... |
Reserved for future methods. |
An mm_drop1 object.
drop1.mm_lmm() refits reduced fixed-effect models and compares them to the
original fit. It is conservative: random-effect terms are preserved exactly,
and the reduced formulas are reported in the result table.
## S3 method for class 'mm_lmm' drop1( object, scope = NULL, test = c("none", "Chisq"), refit_for_comparison = c("auto", "error", "ml"), ... )## S3 method for class 'mm_lmm' drop1( object, scope = NULL, test = c("none", "Chisq"), refit_for_comparison = c("auto", "error", "ml"), ... )
object |
A fitted |
scope |
Optional character vector of fixed-effect terms to drop. |
test |
Comparison test label. |
refit_for_comparison |
How to handle REML fits. |
... |
Reserved for future methods. |
An mm_drop1 object.
Routes each requested contrast row through the Rust fixed-effect inference
bridge and reports the upstream estimability assessment verbatim.
Returned rows carry status (the closed enum from upstream:
estimable, not_estimable, aliased, ...), a boolean estimable
convenience flag, the contrast rank and requested_rank, and a
stable reason populated only when the engine refuses the contrast.
estimability(fit, L = NULL, ...) ## S3 method for class 'mm_lmm' estimability(fit, L = NULL, ...)estimability(fit, L = NULL, ...) ## S3 method for class 'mm_lmm' estimability(fit, L = NULL, ...)
fit |
A fitted |
L |
Optional contrast vector or matrix. Defaults to the fixed-effect coefficient basis. |
... |
Reserved for future methods. |
An mm_estimability object.
explain_model() renders the random-effects guidance surface for an
mm_spec returned by compile_model() or an mm_fit.
It formats the upstream RandomTermCard and diagnostic payloads; Rust
remains the source of truth for per-block English wording and design facts.
explain_model(spec)explain_model(spec)
spec |
An |
An object of class mm_explanation carrying:
textthe rendered explanation text
cardsthe upstream random-term cards
cross_card_constraintsreport-level constraints between cards
diagnosticsthe upstream diagnostics used for design notes
reportthe parsed upstream ModelAuditReport
Raises an mm_schema_error if spec is not an mm_spec/mm_fit or does
not carry a valid compiled artifact.
set.seed(1) df <- data.frame( y = rnorm(20), t = rep(0:3, 5), s = factor(rep(1:5, each = 4)) ) explain_model(compile_model(y ~ t + (1 | s), df))set.seed(1) df <- data.frame( y = rnorm(20), t = rep(0:3, 5), s = factor(rep(1:5, each = 4)) ) explain_model(compile_model(y ~ t + (1 | s), df))
The native handle is a process-local cache of the fitted engine model,
created by lmm() and glmm(). While it is alive, computations that need
the engine model (contrasts, summary() tests, predictions with intervals,
ranef(condVar = TRUE), profiles, bootstraps, model comparison,
verify_convergence()) reuse it instead of refitting. A FALSE result
does not mean the fit is unusable: the handle does not survive
saveRDS() / readRDS() or a new R process, and those computations then
refit the model from the stored model frame, with identical results;
extractors read from the durable artifact and flat R-side payload, and
revive() recreates the lazy cache after serialization. Set
options(mixeff.keep_handle = FALSE) before fitting to not keep handles
(each one holds a copy of the model data for as long as the fit object
lives).
fit_handle_alive(fit, ...) ## S3 method for class 'mm_fit' fit_handle_alive(fit, ...)fit_handle_alive(fit, ...) ## S3 method for class 'mm_fit' fit_handle_alive(fit, ...)
fit |
A fitted |
... |
Reserved for future methods. |
A length-one logical value.
getME() mirrors lme4::getME() for lmm() and glmm() fits. Every
component is rebuilt R-side from quantities the fit stores (fixed
effects, theta and its map, conditional modes, fitted values, the model
frame), so it works on fits restored with readRDS().
getME(object, name, ...) ## S3 method for class 'mm_lmm' getME(object, name, ...) ## S3 method for class 'mm_glmm' getME(object, name, ...)getME(object, name, ...) ## S3 method for class 'mm_lmm' getME(object, name, ...) ## S3 method for class 'mm_glmm' getME(object, name, ...)
object |
A fitted |
name |
Component name, or a character vector of names, or |
... |
Reserved for future methods. |
Supported components: "X", "Z", "Zt", "Ztlist", "mmList",
"y", "mu", "u", "b", "Gp", "Tp", "L", "Lambda",
"Lambdat", "Lind", "Tlist", "ST", "A", "RX", "RZX",
"sigma", "flist", "fixef", "beta", "theta", "REML",
"is_REML", "n_rtrms", "n_rfacs", "N", "n", "p", "q",
"p_i", "l_i", "q_i", "k", "m_i", "m", "cnms", "devcomp",
"offset", "weights", "lower", "glmer.nb.theta" (negative-binomial
GLMMs), and "ALL" (a named list of every available component).
"L" is the sparse Cholesky factor (a Matrix CHMfactor, with the same
fill-reducing permutation lme4 uses) of Lambda'Z'WZ Lambda + I, where
W holds the prior weights for an LMM and the final PIRLS working weights
for a GLMM. "RZX", "RX", "u" and "devcomp" (cmp and dims) are
computed from the same decomposition at the fitted parameters. "u" is
the minimum-norm spherical mode with b = Lambda u, which is the
penalized optimum also when Lambda is singular.
"devfun" is refused: the optimizer runs inside the Rust engine and no R
deviance function exists. Refusals, and requests for unknown components,
raise an mm_inference_unavailable condition with
reason_code = "getme_component_unavailable" naming the component.
The requested component, or a named list for multiple names.
set.seed(1) df <- data.frame(y = rnorm(60), x = rnorm(60), g = factor(rep(seq_len(10), each = 6))) fit <- lmm(y ~ x + (1 | g), df, control = mm_control(verbose = -1)) getME(fit, "theta") getME(fit, "lower") getME(fit, "devcomp")$cmpset.seed(1) df <- data.frame(y = rnorm(60), x = rnorm(60), g = factor(rep(seq_len(10), each = 6))) fit <- lmm(y ~ x + (1 | g), df, control = mm_control(verbose = -1)) getME(fit, "theta") getME(fit, "lower") getME(fit, "devcomp")$cmp
glmm() validates the R-side family/link request, compiles the model
formula, and delegates the numerical fit to the upstream Rust
GeneralizedLinearMixedModel. The default method = "joint_laplace" is
the labeled joint Laplace route (fast = FALSE, nAGQ = 1), the estimator
lme4::glmer() uses by default, backed by the native dependency-light
optimizer in this vendored build. method = "pirls_profiled" is the
labeled fast-PIRLS profiled path (lme4's nAGQ = 0).
glmm( formula, data, family, random = NULL, weights = NULL, offset = NULL, subset = NULL, na.action = getOption("na.action"), contrasts = NULL, method = c("joint_laplace", "pirls_profiled"), nAGQ = 1L, inference = c("auto", "none", "asymptotic", "bootstrap", "working_hessian"), control = mm_control(), ... )glmm( formula, data, family, random = NULL, weights = NULL, offset = NULL, subset = NULL, na.action = getOption("na.action"), contrasts = NULL, method = c("joint_laplace", "pirls_profiled"), nAGQ = 1L, inference = c("auto", "none", "asymptotic", "bootstrap", "working_hessian"), control = mm_control(), ... )
formula |
A two-sided lme4-style formula. |
data |
A |
family |
A supported GLMM family object or family constructor. The
supported surface (every family/link pair the engine fits) is:
|
random |
Reserved for the native random-effect constructor path. |
weights |
Optional prior weights: a column of |
offset |
Optional fixed linear-predictor offset: a column of |
subset, na.action, contrasts
|
As in |
method |
GLMM estimation method. |
nAGQ |
Number of adaptive Gauss-Hermite quadrature points. |
inference |
Requested inference posture. The default |
control |
A list from |
... |
Reserved for future use. |
Optimization runs inside a single native call with no progress output: the
pre-fit explanation block (when verbose >= 0) is the last thing printed
before the fitted result returns. The fit checks for a user interrupt
(Ctrl-C / Esc) between optimizer evaluations and stops with a typed
mm_interrupted error (the check happens at evaluation boundaries, so a
single very expensive evaluation finishes first). Evaluation budgets are bounded (a bounded budget caps optimizer
iterations; it does not prove every native evaluation terminates); runtime on
large problems is governed by mm_control(max_feval = ).
An object of class mm_glmm, also inheriting from mm_fit and
mm_compiled.
set.seed(1) df <- data.frame( y = rbinom(120, 1, 0.5), x = rnorm(120), g = factor(rep(seq_len(12), each = 10)) ) # Default: glmer-equivalent joint Laplace estimates. fit <- glmm(y ~ x + (1 | g), df, family = binomial(), control = mm_control(verbose = -1)) fixef(fit) # Fast profiled PIRLS path (lme4's nAGQ = 0): fit_fast <- glmm(y ~ x + (1 | g), df, family = binomial(), method = "pirls_profiled", control = mm_control(verbose = -1)) fixef(fit_fast)set.seed(1) df <- data.frame( y = rbinom(120, 1, 0.5), x = rnorm(120), g = factor(rep(seq_len(12), each = 10)) ) # Default: glmer-equivalent joint Laplace estimates. fit <- glmm(y ~ x + (1 | g), df, family = binomial(), control = mm_control(verbose = -1)) fixef(fit) # Fast profiled PIRLS path (lme4's nAGQ = 0): fit_fast <- glmm(y ~ x + (1 | g), df, family = binomial(), method = "pirls_profiled", control = mm_control(verbose = -1)) fixef(fit_fast)
inference_options() is the audit verb for fixed-effect inference. It does
not run any test; it predicts, from the fit's metadata, which inference
methods will succeed on this fit and at what approximate cost. The goal is
to remove trial-and-error: a user reading the table can see which routes
are immediately available, which will refuse and why, and which require a
bootstrap.
inference_options(fit, term = NULL, nsim = 1000L, ...) ## S3 method for class 'mm_lmm' inference_options(fit, term = NULL, nsim = 1000L, ...) ## S3 method for class 'mm_glmm' inference_options(fit, term = NULL, nsim = 1000L, ...)inference_options(fit, term = NULL, nsim = 1000L, ...) ## S3 method for class 'mm_lmm' inference_options(fit, term = NULL, nsim = 1000L, ...) ## S3 method for class 'mm_glmm' inference_options(fit, term = NULL, nsim = 1000L, ...)
fit |
A fitted |
term |
Optional fixed-effect term name. Reserved for future per-term refinement; currently unused (the table is fit-level). |
nsim |
Bootstrap replicate count to use when estimating cost. Used
only to format the |
... |
Reserved for future methods. |
Like random_options(), this function does not rank or recommend. There is
no "best method" row.
An mm_inference_options object with a table data frame of one
row per candidate method.
Fitted artifacts may carry Rust-owned fixed-effect inference rows. When present, those rows are the source of truth for estimates, standard errors, degrees of freedom, statistics, p-values, methods, status, reliability, and unavailable reasons. Legacy objects without this artifact field fall back to an unavailable table.
inference_table(fit, ...) ## S3 method for class 'mm_lmm' inference_table( fit, method = c("auto", "satterthwaite", "kenward_roger", "asymptotic", "none"), ... ) ## S3 method for class 'mm_glmm' inference_table(fit, method = "auto", ...)inference_table(fit, ...) ## S3 method for class 'mm_lmm' inference_table( fit, method = c("auto", "satterthwaite", "kenward_roger", "asymptotic", "none"), ... ) ## S3 method for class 'mm_glmm' inference_table(fit, method = "auto", ...)
fit |
A fitted |
... |
Reserved for future methods. |
method |
Inference method. |
An mm_inference_table.
Follows lme4::isSingular(): a fit is singular when any covariance
parameter with a lower bound of zero (a diagonal element of a relative
covariance factor, getME(x, "lower") == 0) is below tol. Works for
lmm() and glmm() fits. lme4::isSingular() is a plain function, so
it cannot dispatch on mixeff fits; call is_singular() instead. Fits
without a stored theta map (very old serialized objects) fall back to the
engine's fit-status and effective-covariance labels.
is_singular(x, tol = 1e-04, ...) ## S3 method for class 'mm_lmm' is_singular(x, tol = 1e-04, ...) ## S3 method for class 'mm_glmm' is_singular(x, tol = 1e-04, ...)is_singular(x, tol = 1e-04, ...) ## S3 method for class 'mm_lmm' is_singular(x, tol = 1e-04, ...) ## S3 method for class 'mm_glmm' is_singular(x, tol = 1e-04, ...)
x |
A fitted |
tol |
Tolerance on the zero-bounded theta values (default |
... |
Reserved for future methods. |
A length-one logical value.
lmm() is mixeff's linear mixed-model fit driver. It compiles the
requested lme4-style formula, emits the same explain_model() view that
pre-fit audit users see as a message (silence it with suppressMessages()
or mm_control(verbose = -1)), then delegates the numerical fit to the
upstream Rust LinearMixedModel.
lmm( formula, data, REML = TRUE, weights = NULL, subset = NULL, na.action = getOption("na.action"), contrasts = NULL, control = mm_control(), offset = NULL )lmm( formula, data, REML = TRUE, weights = NULL, subset = NULL, na.action = getOption("na.action"), contrasts = NULL, control = mm_control(), offset = NULL )
formula |
A two-sided lme4-style formula, e.g.
|
data |
A |
REML |
Logical; fit by restricted maximum likelihood when |
weights |
Optional positive numeric case weights, either a vector with
one value per row or an expression evaluated in |
subset |
Optional expression selecting rows of |
na.action |
A function (or function name) controlling missing-value
handling, as in |
contrasts |
Optional named list of factor contrasts. The engine codes
unordered factors with treatment contrasts ( |
control |
A list from |
offset |
Optional known component of the linear predictor: a numeric
vector with one value per row of |
The returned object is deliberately serializable: fixed effects, theta, sigma, likelihood summaries, fitted values, residuals, random effects, and the post-fit compiler artifact are all stored directly on the R object. The native Rust handle is treated as a rebuildable cache, not as the source of truth.
Optimization runs inside a single native call with no progress output: the
pre-fit explanation block (when verbose >= 0) is the last thing printed
before the fitted result returns. The fit checks for a user interrupt
(Ctrl-C / Esc) between optimizer evaluations and stops with a typed
mm_interrupted error (the check happens at evaluation boundaries, so a
single very expensive evaluation finishes first). Evaluation budgets are bounded (a bounded budget caps optimizer
iterations; it does not prove every native evaluation terminates); runtime on
large problems is governed by mm_control(max_feval = ).
An object of class mm_lmm, also inheriting from mm_fit and
mm_compiled.
The fixed-effects part accepts R's formula language as lm()/lmer()
do: factor(), relevel(), cut(), scale(), poly(),
splines::ns()/bs(), as.numeric(), comparisons such as I(x > 0),
offset(), and the operators *, :, ^, %in%, - and parenthesised
groups such as (a + b)^2 or a * (b + c). Terms the engine cannot
evaluate itself are evaluated in R (with stats::model.frame()
semantics: on the full data, before subset/na.action) and sent to
the engine as synthetic columns; coefficient names match lme4's
(poly(x, 2)1, factor(cyl)6), and predict() on new data reuses the
training basis (predvars), as lm() does. A logical predictor is coded
like a factor with levels FALSE/TRUE, as model.matrix() codes it.
Such transforms are not supported inside random-effect terms, where the
engine refuses them with a typed error.
set.seed(1) df <- data.frame( y = rnorm(80), x = rnorm(80), subject = factor(rep(seq_len(20), each = 4)) ) fit <- lmm(y ~ x + (1 | subject), df, control = mm_control(verbose = -1)) fixef(fit) VarCorr(fit) summary(fit)set.seed(1) df <- data.frame( y = rnorm(80), x = rnorm(80), subject = factor(rep(seq_len(20), each = 4)) ) fit <- lmm(y ~ x + (1 | subject), df, control = mm_control(verbose = -1)) fixef(fit) VarCorr(fit) summary(fit)
mm_allfit() is mixeff's counterpart of lme4::allFit(): it refits
fit once per optimizer (through update() with
mm_control(optimizer = ), keeping the rest of the fit's control) and
summarises the fixed effects, covariance parameters, log-likelihood,
convergence status and run time side by side, so a fit's sensitivity to
the optimizer is visible. An optimizer that is not compiled into this
build, or whose refit fails, is reported as a failed row with its error
message – never dropped.
mm_allfit(fit, optimizers = mm_allfit_optimizers(), verbose = FALSE)mm_allfit(fit, optimizers = mm_allfit_optimizers(), verbose = FALSE)
fit |
A fitted |
optimizers |
Character vector of |
verbose |
Print each optimizer as it runs. |
An object of class mm_allfit: a named list of fits (or
conditions for failed refits). summary() returns a list with
which.OK, msgs, fixef, theta, llik, fit_status, and
times, mirroring summary(lme4::allFit(...)).
set.seed(1) d <- data.frame(g = factor(rep(1:8, each = 5)), x = rep(0:4, 8)) d$y <- 1 + 0.5 * d$x + rnorm(8)[d$g] + rnorm(40) fit <- lmm(y ~ x + (1 | g), d, control = mm_control(verbose = -1)) af <- mm_allfit(fit, optimizers = c("auto", "pattern_search", "cobyla")) summary(af)$llikset.seed(1) d <- data.frame(g = factor(rep(1:8, each = 5)), x = rep(0:4, 8)) d$y <- 1 + 0.5 * d$x + rnorm(8)[d$g] + rnorm(40) fit <- lmm(y ~ x + (1 | g), d, control = mm_control(verbose = -1)) af <- mm_allfit(fit, optimizers = c("auto", "pattern_search", "cobyla")) summary(af)$llik
mm_bootmer() is mixeff's counterpart of lme4::bootMer(): it simulates
nsim responses from the fitted model, refits the model to each, and
evaluates FUN on every refit. The result has class c("mm_bootmer", "boot") with the fields boot::boot.ci() reads (t0, t, R, sim,
statistic, ...), so boot::boot.ci(b, type = "perc", index = 1) works
as it does for a bootMer result.
mm_bootmer( fit, FUN, nsim = 1L, seed = NULL, type = c("parametric", "semiparametric"), use.u = FALSE, verbose = FALSE )mm_bootmer( fit, FUN, nsim = 1L, seed = NULL, type = c("parametric", "semiparametric"), use.u = FALSE, verbose = FALSE )
fit |
A fitted |
FUN |
A function of a fitted |
nsim |
Number of bootstrap replicates. |
seed |
Optional seed; |
type |
Only |
use.u |
|
verbose |
Print a progress dot per replicate. |
The function is named mm_bootmer() rather than bootMer() because
lme4::bootMer() is not an S3 generic: exporting a bootMer() would mask
lme4's for merMod fits.
Replicates use the same model, REML setting, weights, and
mm_control() as fit; each refit warm-starts from the fitted
covariance parameters (as lme4's refit() does). A replicate whose refit
fails, or whose FUN errors, is recorded as an NA row and counted in
attr(, "bootFail") (lme4's convention) – never silently dropped.
An object of class c("mm_bootmer", "boot"): a list with t0
(FUN(fit)), t (an nsim x length(t0) matrix), R, data,
seed, statistic, sim = "parametric", call, and mle, plus
attributes bootFail (failed replicates) and boot.fail.msgs.
confint() with method = "bootstrap" for engine-run
fixed-effect bootstrap intervals; simulate.mm_lmm(); refit().
set.seed(1) d <- data.frame(g = factor(rep(1:8, each = 5)), x = rep(0:4, 8)) d$y <- 1 + 0.5 * d$x + rnorm(8)[d$g] + rnorm(40) fit <- lmm(y ~ x + (1 | g), d, control = mm_control(verbose = -1)) b <- mm_bootmer(fit, fixef, nsim = 20, seed = 2) apply(b$t, 2, sd) if (requireNamespace("boot", quietly = TRUE)) { boot::boot.ci(b, type = "perc", index = 2) }set.seed(1) d <- data.frame(g = factor(rep(1:8, each = 5)), x = rep(0:4, 8)) d$y <- 1 + 0.5 * d$x + rnorm(8)[d$g] + rnorm(40) fit <- lmm(y ~ x + (1 | g), d, control = mm_control(verbose = -1)) b <- mm_bootmer(fit, fixef, nsim = 20, seed = 2) apply(b$t, 2, sd) if (requireNamespace("boot", quietly = TRUE)) { boot::boot.ci(b, type = "perc", index = 2) }
mm_control() collects small R-side controls for lmm() and glmm().
verbose = -1 suppresses the pre-fit explain_model() message;
non-negative values emit it once before optimization (it travels on the
message stream, so suppressMessages() and knitr's message = FALSE
also quiet it).
mm_control( verbose = 0L, max_feval = NULL, optimizer = NULL, start = NULL, ftol_rel = NULL, ftol_abs = NULL, xtol_rel = NULL, optCtrl = NULL, disp_method = NULL, disp_dof_correction = NULL, max_phi_iter = NULL )mm_control( verbose = 0L, max_feval = NULL, optimizer = NULL, start = NULL, ftol_rel = NULL, ftol_abs = NULL, xtol_rel = NULL, optCtrl = NULL, disp_method = NULL, disp_dof_correction = NULL, max_phi_iter = NULL )
verbose |
Integer verbosity level. Use |
max_feval |
Optional positive integer capping the optimizer's objective
evaluations. Most useful for |
optimizer |
Optional optimizer name, overriding the driver's automatic
choice. One of |
start |
Optional numeric warm-start vector for the covariance
parameters (theta). Its length must match the model's theta dimension
(the engine validates this). |
ftol_rel, ftol_abs
|
Optional positive relative/absolute convergence
tolerances on the objective. |
xtol_rel |
Optional positive relative convergence tolerance on the
optimizer parameters. |
optCtrl |
Optional named list in the style of lme4's
|
disp_method, disp_dof_correction, max_phi_iter
|
lme4 2.1-0's
|
By default the fit driver selects the optimizer and its tolerances
automatically (see optimizer_certificate() to inspect what ran). The
optimizer, start, and ftol_*/xtol_rel arguments are a narrow,
opt-in escape hatch — for recourse when the default fails to converge, for
warm starts, and for explicit tolerance overrides. Any override you supply is
recorded in the optimizer certificate, so the fit stays auditable.
A list of class mm_control.
optimizer_certificate() to inspect which optimizer ran and whether
a caller override was applied.
family() returns the R family() object of a fit: gaussian() for
lmm() fits and the GLMM family (with its link) for glmm() fits. For
negative-binomial fits it is MASS::negative.binomial(theta) at the
fitted (or fixed) theta, like lme4::glmer.nb(); when MASS is not
installed an equivalent family object with the same variance, deviance and
link functions is returned.
## S3 method for class 'mm_lmm' family(object, ...) ## S3 method for class 'mm_glmm' family(object, ...) ## S3 method for class 'mm_lmm' weights(object, type = c("prior", "working"), ...) ## S3 method for class 'mm_glmm' weights(object, type = c("prior", "working"), ...)## S3 method for class 'mm_lmm' family(object, ...) ## S3 method for class 'mm_glmm' family(object, ...) ## S3 method for class 'mm_lmm' weights(object, type = c("prior", "working"), ...) ## S3 method for class 'mm_glmm' weights(object, type = c("prior", "working"), ...)
object |
A fitted |
... |
Unused. |
type |
|
weights() mirrors lme4:::weights.merMod(): type = "prior" returns the
prior weights, a vector of ones when the model was fitted without weights;
type = "working" returns the final PIRLS working weights of a GLMM.
A family object, or a numeric vector of weights.
set.seed(1) df <- data.frame(y = rnorm(60), x = rnorm(60), g = factor(rep(seq_len(10), each = 6))) fit <- lmm(y ~ x + (1 | g), df, control = mm_control(verbose = -1)) family(fit) head(weights(fit))set.seed(1) df <- data.frame(y = rnorm(60), x = rnorm(60), g = factor(rep(seq_len(10), each = 6))) fit <- lmm(y ~ x + (1 | g), df, control = mm_control(verbose = -1)) family(fit) head(weights(fit))
A versioned record of what mixeff currently supports — formula syntax
surface, schema versions per artifact type, and capability flags. The
manifest is the wrapper's machine-readable answer to "what does this
build know how to do?". Fitted objects do not carry the whole manifest:
each one stamps the narrower fit$schema record (artifact schema name and
version, crate version, package version), which the serialization and
reporting paths read back. What lets audit() describe a fit after
readRDS(), with no live Rust handle, is the durable compiled artifact
stored beside it.
mm_formula_manifest()mm_formula_manifest()
Capability flags evolve across releases; gate behavior on flags rather than on package version.
A named list with the following elements:
mixeff_rust_versionVersion of the bundled extendr crate.
crate_versionVersion of the bundled mixeff-rs upstream
crate.
schema_versionsNamed list, one entry per artifact schema the wrapper currently emits or consumes.
formula_featuresNamed list with operators,
intercept_forms, random_term_forms, and transformations —
the lme4-style syntax surface.
capabilitiesNamed list of logical flags
(parse_formula, compile_model, audit_design, explain_model,
random_options, compare_covariance, fit_lmm, fit_glmm,
audit, changes, diagnostics, fit_status,
parameterization, roles, as_json, simulate, inference,
model_comparison_table, fit_summary_payload,
marginal_quantity_table,
marginal_quantities, verify_convergence). The
marginal_quantity_table schema may be available before the
corresponding marginal_quantities verbs are implemented.
m <- mm_formula_manifest() m$schema_versions$formula m$capabilities$parse_formulam <- mm_formula_manifest() m$schema_versions$formula m$capabilities$parse_formula
These helpers provide a small native marginal-quantities surface for Gaussian LMM fits. They cover the common population-level workflow: construct a reference grid, evaluate fixed-effect predictions, average them into marginal means, and compare those means by simple differences.
mm_grid(fit, specs, by = NULL, at = list(), cov.reduce = mean, ...) ## S3 method for class 'mm_lmm' mm_grid(fit, specs, by = NULL, at = list(), cov.reduce = mean, ...) mm_predictions( fit, grid = NULL, specs = NULL, by = NULL, at = list(), method = c("auto", "satterthwaite", "kenward_roger", "bootstrap", "asymptotic", "none"), level = 0.95, target = c("population"), scale = c("response", "link"), ... ) ## S3 method for class 'mm_lmm' mm_predictions( fit, grid = NULL, specs = NULL, by = NULL, at = list(), method = c("auto", "satterthwaite", "kenward_roger", "bootstrap", "asymptotic", "none"), level = 0.95, target = c("population"), scale = c("response", "link"), ... ) mm_means( fit, specs, by = NULL, at = list(), grid = NULL, method = c("auto", "satterthwaite", "kenward_roger", "bootstrap", "asymptotic", "none"), level = 0.95, weights = c("equal", "proportional"), target = c("population"), scale = c("response", "link"), ... ) ## S3 method for class 'mm_lmm' mm_means( fit, specs, by = NULL, at = list(), grid = NULL, method = c("auto", "satterthwaite", "kenward_roger", "bootstrap", "asymptotic", "none"), level = 0.95, weights = c("equal", "proportional"), target = c("population"), scale = c("response", "link"), ... ) mm_comparisons( fit, specs, by = NULL, at = list(), grid = NULL, comparison = c("difference", "ratio", "odds_ratio"), method = c("auto", "satterthwaite", "kenward_roger", "bootstrap", "asymptotic", "none"), level = 0.95, weights = c("equal", "proportional"), target = c("population"), scale = c("response", "link"), ... ) ## S3 method for class 'mm_lmm' mm_comparisons( fit, specs, by = NULL, at = list(), grid = NULL, comparison = c("difference", "ratio", "odds_ratio"), method = c("auto", "satterthwaite", "kenward_roger", "bootstrap", "asymptotic", "none"), level = 0.95, weights = c("equal", "proportional"), target = c("population"), scale = c("response", "link"), ... )mm_grid(fit, specs, by = NULL, at = list(), cov.reduce = mean, ...) ## S3 method for class 'mm_lmm' mm_grid(fit, specs, by = NULL, at = list(), cov.reduce = mean, ...) mm_predictions( fit, grid = NULL, specs = NULL, by = NULL, at = list(), method = c("auto", "satterthwaite", "kenward_roger", "bootstrap", "asymptotic", "none"), level = 0.95, target = c("population"), scale = c("response", "link"), ... ) ## S3 method for class 'mm_lmm' mm_predictions( fit, grid = NULL, specs = NULL, by = NULL, at = list(), method = c("auto", "satterthwaite", "kenward_roger", "bootstrap", "asymptotic", "none"), level = 0.95, target = c("population"), scale = c("response", "link"), ... ) mm_means( fit, specs, by = NULL, at = list(), grid = NULL, method = c("auto", "satterthwaite", "kenward_roger", "bootstrap", "asymptotic", "none"), level = 0.95, weights = c("equal", "proportional"), target = c("population"), scale = c("response", "link"), ... ) ## S3 method for class 'mm_lmm' mm_means( fit, specs, by = NULL, at = list(), grid = NULL, method = c("auto", "satterthwaite", "kenward_roger", "bootstrap", "asymptotic", "none"), level = 0.95, weights = c("equal", "proportional"), target = c("population"), scale = c("response", "link"), ... ) mm_comparisons( fit, specs, by = NULL, at = list(), grid = NULL, comparison = c("difference", "ratio", "odds_ratio"), method = c("auto", "satterthwaite", "kenward_roger", "bootstrap", "asymptotic", "none"), level = 0.95, weights = c("equal", "proportional"), target = c("population"), scale = c("response", "link"), ... ) ## S3 method for class 'mm_lmm' mm_comparisons( fit, specs, by = NULL, at = list(), grid = NULL, comparison = c("difference", "ratio", "odds_ratio"), method = c("auto", "satterthwaite", "kenward_roger", "bootstrap", "asymptotic", "none"), level = 0.95, weights = c("equal", "proportional"), target = c("population"), scale = c("response", "link"), ... )
fit |
A fitted |
specs |
Character vector, or a one-sided formula such as |
by |
Optional character vector of grouping variables for marginal summaries or pairwise comparisons. |
at |
Named list of fixed-predictor values to force in the grid. |
cov.reduce |
Function used to reduce numeric fixed predictors that are not explicitly gridded. |
... |
Reserved for future methods. |
grid |
Optional object returned by |
method |
Requested inference method, passed to |
level |
Confidence level for intervals computed from contrast standard errors. |
target |
Prediction target. Only |
scale |
Prediction scale. Gaussian LMMs have identical |
weights |
Averaging weights for |
comparison |
Comparison scale. Only |
The returned tables use the mixedmodels.marginal_quantity_table row
contract. Inference is routed through contrast() so rows retain the same
method, status, reliability, estimability, and reason fields as fixed-effect
contrasts. Ordinary full-rank LMMs use the versioned
mixedmodels.fixed_effect_covariance_matrix payload for fixed-effect
uncertainty; rank-deficient or otherwise uncertified fits surface explicit
unavailable status and reasons instead of partial covariance numbers.
mm_grid() returns an mm_grid object. The other helpers return an
mm_marginal_quantity object with a contract-shaped table.
hatvalues() returns the diagonal of the hat matrix of the fitted mixed
model, cooks.distance() the Cook's distances computed from them, and
influence() refits the model with each case (or each level of a grouping
variable) deleted, as lme4's methods of the same names do.
## S3 method for class 'mm_lmm' hatvalues(model, fullHatMatrix = FALSE, ...) ## S3 method for class 'mm_glmm' hatvalues(model, fullHatMatrix = FALSE, ...) ## S3 method for class 'mm_lmm' cooks.distance(model, ...) ## S3 method for class 'mm_glmm' cooks.distance(model, ...) ## S3 method for class 'mm_lmm' influence(model, groups = NULL, data = NULL, do.coef = TRUE, ncores = 1L, ...) ## S3 method for class 'mm_glmm' influence(model, groups = NULL, data = NULL, do.coef = TRUE, ncores = 1L, ...) ## S3 method for class 'mm_influence' dfbeta(model, which = c("fixed", "var.cov"), ...) ## S3 method for class 'mm_influence' dfbetas(model, ...) ## S3 method for class 'mm_influence' cooks.distance(model, ...)## S3 method for class 'mm_lmm' hatvalues(model, fullHatMatrix = FALSE, ...) ## S3 method for class 'mm_glmm' hatvalues(model, fullHatMatrix = FALSE, ...) ## S3 method for class 'mm_lmm' cooks.distance(model, ...) ## S3 method for class 'mm_glmm' cooks.distance(model, ...) ## S3 method for class 'mm_lmm' influence(model, groups = NULL, data = NULL, do.coef = TRUE, ncores = 1L, ...) ## S3 method for class 'mm_glmm' influence(model, groups = NULL, data = NULL, do.coef = TRUE, ncores = 1L, ...) ## S3 method for class 'mm_influence' dfbeta(model, which = c("fixed", "var.cov"), ...) ## S3 method for class 'mm_influence' dfbetas(model, ...) ## S3 method for class 'mm_influence' cooks.distance(model, ...)
model |
A fitted |
fullHatMatrix |
If |
... |
Unused. |
groups |
For |
data |
Optional data frame with one row per observation (in model
frame order) used only to look up |
do.coef |
If |
ncores |
Number of cores for the deletion refits (via
|
which |
For |
The hat matrix is that of the penalized least-squares problem at the
optimum, H = W^{1/2} C M^{-1} C' W^{1/2} with C = [X, Z Lambda] and
M = C' W C + diag(0_p, I_q), where Lambda is the relative covariance
factor and W the weights. For an LMM, W holds the prior weights and the
result equals lme4::hatvalues() on the same fit. For a GLMM, W holds the
working (IRLS) weights at convergence, as stats::hatvalues() does for a
glm. For GLMMs with a free dispersion parameter phi (Gamma, inverse
Gaussian, Gaussian with a non-identity link) the working weights are
divided by phi, as lme4 >= 2.1-0's weights(fit, "working") are, to
match the absolute-scale Lambda; lme4 instead combines the working weights inside the factorization
with the prior weights outside it, so the two differ for GLMMs (lme4 warns
that its GLMM hat matrix "may not make sense").
cooks.distance() follows lme4: D_i = (r_i / (1 - h_i))^2 h_i / (phi p) with Pearson residuals r_i ((y - mu) sqrt(w) / sqrt(V(mu))),
dispersion phi (sigma^2 for an LMM, 1 for binomial, Poisson and
negative-binomial GLMMs, sigma^2 for Gamma, inverse-Gaussian and
Gaussian non-identity-link GLMMs) and p the rank of the
fixed-effect design.
influence() deletes one case (default) or one level of groups at a
time and refits with the original settings (REML, family, weights,
offset, method, control). Deletion refits that fail are recorded as NA
rows with converged = FALSE rather than dropped. The result has class
mm_influence and the component names of lme4's influence.merMod
result; stats::dfbeta(), stats::dfbetas() and stats::cooks.distance()
have methods for it (Cook's distance there is the deletion version based
on the change in fixed effects).
hatvalues() and cooks.distance(): a named numeric vector (or a
matrix for fullHatMatrix = TRUE). influence(): an mm_influence list.
set.seed(1) df <- data.frame( y = rnorm(40), x = rnorm(40), g = factor(rep(seq_len(8), each = 5)) ) fit <- lmm(y ~ x + (1 | g), df, control = mm_control(verbose = -1)) head(hatvalues(fit)) head(cooks.distance(fit)) infl <- influence(fit, groups = "g") dfbeta(infl) cooks.distance(infl)set.seed(1) df <- data.frame( y = rnorm(40), x = rnorm(40), g = factor(rep(seq_len(8), each = 5)) ) fit <- lmm(y ~ x + (1 | g), df, control = mm_control(verbose = -1)) head(hatvalues(fit)) head(cooks.distance(fit)) infl <- influence(fit, groups = "g") dfbeta(infl) cooks.distance(infl)
Returns the known-schema table that backs mm_json_negotiate(). The
wrapper refuses any artifact whose schema name and version are absent
from this table, so the table grows as new artifact types are added.
mm_json_known_schemas()mm_json_known_schemas()
A data frame with two character columns: name and version.
mm_json_known_schemas()mm_json_known_schemas()
mixeff supportsEvery artifact crossing the Rust-R bridge carries a header that names a
schema (e.g., formula, artifact, audit) and the version of that
schema (v0, v1, ...). mm_json_negotiate() validates a header
against the closed set of (schema_name, schema_version) pairs the
current wrapper build understands, and raises a typed
mm_schema_error on mismatch.
mm_json_negotiate(header)mm_json_negotiate(header)
header |
A list with at least |
This is the fast-fail primitive: any code path that consumes a Rust
artifact should call mm_json_negotiate() before parsing the body, so
a version skew between the Rust crate and the R wrapper produces a
single clean error rather than a confusing field-by-field decode failure.
Invisibly returns TRUE on a clean match.
Any of the following raise an mm_schema_error (also inheriting from
mm_condition and error):
header is not a list, or is missing schema_name /
schema_version, or those fields are not length-1 character.
schema_name is not in the wrapper's known set
(see mm_json_known_schemas()).
schema_name is known but schema_version does not match what
the wrapper expects.
The condition object carries the original header in its input field.
(The field is not called header because rlang reserves that name on
conditions for cnd_header() formatting.)
mm_json_known_schemas() for the closed set,
mm_formula_manifest() for the broader capability record.
mm_json_negotiate(list(schema_name = "formula", schema_version = "v0")) # Raises mm_schema_error: try(mm_json_negotiate(list(schema_name = "formula", schema_version = "v99")))mm_json_negotiate(list(schema_name = "formula", schema_version = "v0")) # Raises mm_schema_error: try(mm_json_negotiate(list(schema_name = "formula", schema_version = "v99")))
Convenience helper for the common case of testing
where c is a sparse,
named weight vector. The estimate is ,
the standard error is where V
is the model's fixed-effect covariance, the statistic is the Wald
ratio, and the interval is the symmetric Wald CI at level.
mm_lincomb(fit, weights, level = 0.95, method = NULL, ...) ## Default S3 method: mm_lincomb(fit, weights, level = 0.95, method = NULL, ...) ## S3 method for class 'mm_glmm' mm_lincomb(fit, weights, level = 0.95, method = NULL, ...) ## S3 method for class 'mm_lmm' mm_lincomb( fit, weights, level = 0.95, method = c("auto", "satterthwaite", "kenward_roger", "asymptotic"), ... )mm_lincomb(fit, weights, level = 0.95, method = NULL, ...) ## Default S3 method: mm_lincomb(fit, weights, level = 0.95, method = NULL, ...) ## S3 method for class 'mm_glmm' mm_lincomb(fit, weights, level = 0.95, method = NULL, ...) ## S3 method for class 'mm_lmm' mm_lincomb( fit, weights, level = 0.95, method = c("auto", "satterthwaite", "kenward_roger", "asymptotic"), ... )
fit |
A fitted |
weights |
A named numeric vector (or named list / single-row
data.frame coercible to one). Names must match
|
level |
Confidence level for the Wald interval. Default 0.95. |
method |
For |
... |
Reserved for future methods. |
For mm_glmm, the statistic is the asymptotic Wald z (no df). For
mm_lmm, the default is Satterthwaite-approximated t via
df_for_contrast(); pass method = "asymptotic" to force Wald z.
Weight names must be a subset of names(fixef(fit)). Coefficients
not named in weights contribute zero. Pass the long-form
contrast() front door if you need multiple contrasts or non-default
rhs.
A single-row data.frame with columns estimate, std_error,
statistic, statistic_name ("t" or "z"), df, p_value,
lower, upper, and method. The result carries an "mm_status"
attribute reflecting the underlying vcov reliability (status,
method, reliability, reason).
contrast() for the long-form, Rust-routed contrast surface
with full estimability / reliability reporting.
set.seed(1) d <- data.frame( g = factor(rep(1:12, each = 8)), trt = factor(rep(c("ctrl", "drug"), 48)), x = rnorm(96) ) d$y <- 1 + 0.5 * (d$trt == "drug") + 0.3 * d$x + 0.4 * (d$trt == "drug") * d$x + rnorm(12)[d$g] + rnorm(96) fit <- lmm(y ~ trt * x + (1 | g), d, control = mm_control(verbose = -1)) # Treatment effect at x = 1 (weights use lme4 coefficient names): mm_lincomb(fit, c(trtdrug = 1, "trtdrug:x" = 1))set.seed(1) d <- data.frame( g = factor(rep(1:12, each = 8)), trt = factor(rep(c("ctrl", "drug"), 48)), x = rnorm(96) ) d$y <- 1 + 0.5 * (d$trt == "drug") + 0.3 * d$x + 0.4 * (d$trt == "drug") * d$x + rnorm(12)[d$g] + rnorm(96) fit <- lmm(y ~ trt * x + (1 | g), d, control = mm_control(verbose = -1)) # Treatment effect at x = 1 (weights use lme4 coefficient names): mm_lincomb(fit, c(trtdrug = 1, "trtdrug:x" = 1))
mm_lmlist() is mixeff's counterpart of lme4::lmList(): it fits
lm() (or glm() when family is given) separately within each level
of a grouping factor, using lme4's response ~ predictors | group
formula. It is named mm_lmlist() so attaching mixeff does not mask
lme4::lmList() / nlme::lmList().
mm_lmlist( formula, data, family = NULL, subset = NULL, weights = NULL, na.action = stats::na.omit, pool = is.null(family) )mm_lmlist( formula, data, family = NULL, subset = NULL, weights = NULL, na.action = stats::na.omit, pool = is.null(family) )
formula |
A formula |
data |
A data frame. |
family |
Optional GLM family; |
subset, weights, na.action
|
Passed to |
pool |
Pool the residual standard deviation across groups for
inference. Defaults to |
coef() returns one row per group (lme4's shape); confint() returns a
group x (lower, upper) x coefficient array. With pool = TRUE (the
default for lm fits, as in lme4) confint() uses the residual standard
deviation pooled across groups, with the pooled residual degrees of
freedom, and sigma() returns that pooled value; confint(x, pool = FALSE) gives each group's own lm t interval (Wald z for GLMs), which
is what confint() on an lme4::lmList() fit returns. A group
whose fit fails is kept as NULL and reported, never silently dropped.
An object of class mm_lmlist: a named list of lm/glm fits
(one per group) with attributes call, pool, groups, and
failed.
set.seed(1) d <- data.frame(g = factor(rep(1:6, each = 8)), x = rep(0:7, 6)) d$y <- 2 + rnorm(6)[d$g] + (0.5 + rnorm(6, sd = 0.2)[d$g]) * d$x + rnorm(48) ml <- mm_lmlist(y ~ x | g, d) coef(ml) confint(ml)[, , "x"]set.seed(1) d <- data.frame(g = factor(rep(1:6, each = 8)), x = rep(0:7, 6)) d$y <- 2 + rnorm(6)[d$g] + (0.5 + rnorm(6, sd = 0.2)[d$g]) * d$x + rnorm(48) ml <- mm_lmlist(y ~ x | g, d) coef(ml) confint(ml)[, , "x"]
These methods provide the common lme4-style extractor surface for
lmm() fits. The required values are stored directly on the R object or
rebuilt lazily from the serialized artifact, so these methods do not require
a live Rust handle after saveRDS() / readRDS().
ngrps() returns a named integer vector giving the number of levels of each
random-effect grouping factor, mirroring lme4::ngrps().
Produces the long form returned by as.data.frame(lme4::VarCorr(.)):
one row per variance (var2 = NA) and one row per covariance
(var1, var2 both set), with a final Residual row for LMMs. vcov
holds the (co)variance and sdcor the standard deviation (diagonal) or
correlation (off-diagonal). This is the shape broom.mixed::tidy() expects.
Produces the long form returned by as.data.frame(lme4::ranef(.)): columns
grpvar, term, grp, condval, and condsd. condsd is the
conditional standard deviation, taken from the postVar attribute when the
modes were extracted with condVar = TRUE, and NA otherwise.
fixef(object, ...) ## Default S3 method: fixef(object, ...) ## S3 method for class 'mm_lmm' fixef(object, add.dropped = FALSE, ...) ## S3 method for class 'mm_glmm' fixef(object, add.dropped = FALSE, ...) ranef(object, ...) ## Default S3 method: ranef(object, ...) ## S3 method for class 'mm_lmm' ranef(object, condVar = FALSE, ...) ## S3 method for class 'mm_glmm' ranef(object, condVar = FALSE, ...) ## S3 method for class 'mm_lmm' coef(object, ...) ## S3 method for class 'mm_glmm' coef(object, ...) VarCorr(x, ...) ## Default S3 method: VarCorr(x, ...) ## S3 method for class 'mm_lmm' VarCorr(x, ...) ## S3 method for class 'mm_glmm' VarCorr(x, ...) ## S3 method for class 'mm_lmm' sigma(object, ...) ## S3 method for class 'mm_glmm' sigma(object, ...) ## S3 method for class 'mm_lmm' logLik(object, REML = NULL, ...) ## S3 method for class 'mm_glmm' logLik(object, REML = NULL, ...) ## S3 method for class 'mm_lmm' deviance(object, REML = NULL, ...) ## S3 method for class 'mm_glmm' deviance(object, ...) ## S3 method for class 'mm_lmm' AIC(object, ..., k = 2) ## S3 method for class 'mm_glmm' AIC(object, ..., k = 2) ## S3 method for class 'mm_lmm' BIC(object, ...) ## S3 method for class 'mm_glmm' BIC(object, ...) ## S3 method for class 'mm_lmm' nobs(object, ...) ## S3 method for class 'mm_glmm' nobs(object, ...) ## S3 method for class 'mm_lmm' df.residual(object, ...) ## S3 method for class 'mm_glmm' df.residual(object, ...) ## S3 method for class 'mm_lmm' formula(x, ...) ## S3 method for class 'mm_glmm' formula(x, ...) ## S3 method for class 'mm_lmm' model.frame(formula, fixed.only = FALSE, ...) ## S3 method for class 'mm_glmm' model.frame(formula, fixed.only = FALSE, ...) ngrps(object, ...) ## Default S3 method: ngrps(object, ...) ## S3 method for class 'mm_lmm' ngrps(object, ...) ## S3 method for class 'mm_glmm' ngrps(object, ...) ## S3 method for class 'mm_lmm' extractAIC(fit, scale, k = 2, ...) ## S3 method for class 'mm_glmm' extractAIC(fit, scale, k = 2, ...) ## S3 method for class 'mm_lmm' terms(x, ...) ## S3 method for class 'mm_glmm' terms(x, ...) ## S3 method for class 'mm_varcorr' as.data.frame(x, row.names = NULL, optional = FALSE, ...) ## S3 method for class 'mm_ranef' as.data.frame(x, row.names = NULL, optional = FALSE, ...) ## S3 method for class 'mm_lmm' model.matrix(object, type = c("fixed", "random"), ...) ## S3 method for class 'mm_glmm' model.matrix(object, type = c("fixed", "random"), ...) ## S3 method for class 'mm_lmm' vcov(object, type = c("fixed", "theta"), correlation = FALSE, ...) ## S3 method for class 'mm_glmm' vcov(object, type = c("fixed", "theta"), correlation = FALSE, ...)fixef(object, ...) ## Default S3 method: fixef(object, ...) ## S3 method for class 'mm_lmm' fixef(object, add.dropped = FALSE, ...) ## S3 method for class 'mm_glmm' fixef(object, add.dropped = FALSE, ...) ranef(object, ...) ## Default S3 method: ranef(object, ...) ## S3 method for class 'mm_lmm' ranef(object, condVar = FALSE, ...) ## S3 method for class 'mm_glmm' ranef(object, condVar = FALSE, ...) ## S3 method for class 'mm_lmm' coef(object, ...) ## S3 method for class 'mm_glmm' coef(object, ...) VarCorr(x, ...) ## Default S3 method: VarCorr(x, ...) ## S3 method for class 'mm_lmm' VarCorr(x, ...) ## S3 method for class 'mm_glmm' VarCorr(x, ...) ## S3 method for class 'mm_lmm' sigma(object, ...) ## S3 method for class 'mm_glmm' sigma(object, ...) ## S3 method for class 'mm_lmm' logLik(object, REML = NULL, ...) ## S3 method for class 'mm_glmm' logLik(object, REML = NULL, ...) ## S3 method for class 'mm_lmm' deviance(object, REML = NULL, ...) ## S3 method for class 'mm_glmm' deviance(object, ...) ## S3 method for class 'mm_lmm' AIC(object, ..., k = 2) ## S3 method for class 'mm_glmm' AIC(object, ..., k = 2) ## S3 method for class 'mm_lmm' BIC(object, ...) ## S3 method for class 'mm_glmm' BIC(object, ...) ## S3 method for class 'mm_lmm' nobs(object, ...) ## S3 method for class 'mm_glmm' nobs(object, ...) ## S3 method for class 'mm_lmm' df.residual(object, ...) ## S3 method for class 'mm_glmm' df.residual(object, ...) ## S3 method for class 'mm_lmm' formula(x, ...) ## S3 method for class 'mm_glmm' formula(x, ...) ## S3 method for class 'mm_lmm' model.frame(formula, fixed.only = FALSE, ...) ## S3 method for class 'mm_glmm' model.frame(formula, fixed.only = FALSE, ...) ngrps(object, ...) ## Default S3 method: ngrps(object, ...) ## S3 method for class 'mm_lmm' ngrps(object, ...) ## S3 method for class 'mm_glmm' ngrps(object, ...) ## S3 method for class 'mm_lmm' extractAIC(fit, scale, k = 2, ...) ## S3 method for class 'mm_glmm' extractAIC(fit, scale, k = 2, ...) ## S3 method for class 'mm_lmm' terms(x, ...) ## S3 method for class 'mm_glmm' terms(x, ...) ## S3 method for class 'mm_varcorr' as.data.frame(x, row.names = NULL, optional = FALSE, ...) ## S3 method for class 'mm_ranef' as.data.frame(x, row.names = NULL, optional = FALSE, ...) ## S3 method for class 'mm_lmm' model.matrix(object, type = c("fixed", "random"), ...) ## S3 method for class 'mm_glmm' model.matrix(object, type = c("fixed", "random"), ...) ## S3 method for class 'mm_lmm' vcov(object, type = c("fixed", "theta"), correlation = FALSE, ...) ## S3 method for class 'mm_glmm' vcov(object, type = c("fixed", "theta"), correlation = FALSE, ...)
object, x, formula, fit
|
A fitted |
... |
Reserved for generic compatibility. For |
add.dropped |
For |
condVar |
Logical; when |
REML |
Ignored; included for S3 compatibility with likelihood and deviance generics. |
k |
Penalty per parameter for |
fixed.only |
For |
scale |
Ignored; included for S3 compatibility with |
row.names, optional
|
Ignored; present for S3 consistency. |
type |
For |
correlation |
Logical; accepted for S3 compatibility with |
These methods follow lme4's shapes. coef() returns, per grouping factor,
every fixed-effect column (fixed-only columns repeated) plus the
conditional modes, in lme4's column order. VarCorr() returns lme4's
VarCorr.merMod structure: a named list of covariance matrices (one per
random-effect term, so VarCorr(fit)$Subject is a matrix) with
"stddev" and "correlation" attributes and list attributes "sc"
(sigma()) and "useSc" (TRUE for LMMs; FALSE for every GLMM, as in
lme4 >= 2.1-0, so GLMM random-effect SDs are absolute and no Residual row
is printed); it prints like lme4 and
as.data.frame() gives lme4's long form. mixeff's full-precision long
table remains available as VarCorr(fit)$table (with $residual_sd).
sigma() of a binomial, Poisson or negative-binomial GLMM is 1, as in
lme4 (the negative-binomial theta is getME(fit, "glmer.nb.theta")). For
GLMMs with a free dispersion parameter (Gamma, inverse Gaussian, and
Gaussian with a non-identity link) it is sqrt(phi) with
phi = sum(deviance residuals^2) / (n - rank([X, Z])), the dispersion
profiled during the fit, as in lme4 >= 2.1-0 (glmerControl() defaults
disp_method = "moment", disp_dof_correction = TRUE; lme4 < 2.1-0 used
a different, biased estimate). mm_control(disp_dof_correction = FALSE)
divides by n instead, and mm_control(max_phi_iter = ) caps the phi
iterations. With mm_control(disp_method = "old/buggy") the fit
reproduces lme4 2.1-0's disp_method = "old/buggy": PIRLS runs with
phi = 1, so weights(fit, "working") does not carry 1/phi, and
VarCorr() reports theta itself as the random-effect SD, as lme4 2.1-0
does. Under lme4 < 2.1-0 that SD was sigma() * theta. deviance() of a GLMM is the sum of squared deviance
residuals, as lme4::deviance.merMod(); -2 * logLik() is the Laplace
objective reported in anova(). model.frame() returns lme4's frame
(transformed columns such as log(y), a terms attribute, (weights)
and (offset) columns); the raw variables the engine used are in
fit$model_frame.
vcov() of a joint-Laplace GLMM is the inverse of the finite-difference
Hessian over the fixed effects and covariance parameters, glmer's default
(use.hessian = TRUE). When that Hessian is not positive definite (or
unavailable) the engine falls back to the fixed-effect block RX of the
Laplace penalized least-squares factorization at the optimum,
conditional on the covariance parameters – glmer's
vcov(fit, use.hessian = FALSE), which glmer also falls back to with a
warning. mixeff does the same: the matrix carries
attr(, "mm_method") == "laplace_rx_conditional_on_theta", reliability
"low" and the engine's notes (attr(, "mm_notes")), and vcov() warns
(class mm_vcov_rx_fallback). Such standard errors ignore the
uncertainty in the covariance parameters.
Known lme4 2.1-0 discrepancy: for GLMMs with a free dispersion parameter
(Gamma, inverse Gaussian, Gaussian with a non-identity link) the
penalized least-squares factor already carries the 1 / phi working
weights, so mixeff's RX-based vcov() (nAGQ = 0 fits, and the
fallback above) is unsc() with no further sigma^2 factor. lme4 >= 2.1-0
still multiplies by sigma()^2 there (and in ranef(condVar = TRUE)), so
those values differ from lme4 2.1's by the factor phi = sigma()^2;
Hessian-based vcov() values agree.
A named integer vector of group counts.
set.seed(1) df <- data.frame( y = rnorm(60), x = rnorm(60), g = factor(rep(seq_len(10), each = 6)) ) fit <- lmm(y ~ x + (1 | g), df, control = mm_control(verbose = -1)) fixef(fit) VarCorr(fit) head(ranef(fit)$g) sigma(fit) logLik(fit) nobs(fit)set.seed(1) df <- data.frame( y = rnorm(60), x = rnorm(60), g = factor(rep(seq_len(10), each = 6)) ) fit <- lmm(y ~ x + (1 | g), df, control = mm_control(verbose = -1)) fixef(fit) VarCorr(fit) head(ranef(fit)$g) sigma(fit) logLik(fit) nobs(fit)
glmm()
NB2 family (variance mu + mu^2/theta, log link). With theta = NULL
(the default) the size parameter is estimated alongside the model, matching
lme4::glmer.nb(). Supplying a positive theta fits conditional on that
value, matching glmer(family = MASS::negative.binomial(theta)) — which
glmm() also accepts directly.
mm_negative_binomial(theta = NULL)mm_negative_binomial(theta = NULL)
theta |
Optional positive NB2 size (dispersion) parameter. |
A family object accepted by glmm().
fam <- mm_negative_binomial() # glmer.nb-style: theta estimated fam_fixed <- mm_negative_binomial(theta = 2.5)fam <- mm_negative_binomial() # glmer.nb-style: theta estimated fam_fixed <- mm_negative_binomial(theta = 2.5)
mm_parse_formula() parses a formula string through the Rust formula
parser and returns its canonical Display rendering. Equivalent formula
spellings produce identical canonical strings, so equivalence-class testing
in R is just string comparison on the canonical form.
mm_parse_formula(formula)mm_parse_formula(formula)
formula |
A single character string (length 1, non-NA, non-empty), or
a one-sided / two-sided R |
A single character string: the canonical rendering of the parsed formula.
Parse failures are signaled as a typed mm_formula_error condition (also
inheriting from mm_condition and error). The condition object carries
the original input string in its formula field. Catch with
tryCatch(..., mm_formula_error = handler).
mm_parse_formula("y ~ x + (1 | g)") mm_parse_formula(y ~ x + (1 | g))mm_parse_formula("y ~ x + (1 | g)") mm_parse_formula(y ~ x + (1 | g))
mm_variance_components() splits the variance of a fitted mixed model
into the components used by Nakagawa and Schielzeth's R2 and the
intraclass correlation: the variance of the fixed-effect linear predictor,
the random-effect variance, and the residual (distribution-specific plus
observation-level) variance. mm_r2() returns the marginal and
conditional R2 and mm_icc() the adjusted and unadjusted ICC. The
numbers follow insight::get_variance(), performance::r2_nakagawa() and
performance::icc() on the equivalent lme4 fit.
mm_variance_components(fit, tolerance = 1e-05) mm_r2(fit, tolerance = 1e-05) mm_icc(fit, tolerance = 1e-05)mm_variance_components(fit, tolerance = 1e-05) mm_r2(fit, tolerance = 1e-05) mm_icc(fit, tolerance = 1e-05)
fit |
A fitted |
tolerance |
Variances below this value mark the fit as singular. |
When the insight and performance packages are installed, mixeff also
registers methods so that performance::icc(fit), performance::r2(fit)
and insight::get_variance(fit) work directly on mixeff fits (not
by_group = TRUE, which needs lme4 internals).
Fixed variance: var(X beta).
Random variance: for each random term whose grouping factor has fewer
levels than observations, the mean over observations of z_i' Sigma z_i,
where z_i holds the term's coefficients' columns of the fixed-effect
design (a random slope without a matching fixed column is dropped, as
insight does).
Distribution-specific variance: sigma^2 for an LMM; pi^2/3, 1 and
pi^2/6 for binomial logit, probit and cloglog links; for Gamma,
sigma^2 (inverse link) or the log-normal approximation
log1p(sigma^2) (log link), with sigma() the lme4 >= 2.1-0 dispersion
sqrt(phi); and the log-normal approximation log(1 + V(mu)/mu^2) for Poisson
(V(mu) = mu) and negative-binomial (V(mu) = mu (1 + mu/theta)) log-link
models, with mu = exp(b0 + v0/2) from the intercept b0 and the
random-effect variance v0 (observation-level terms excluded) of the
null model (y ~ 1 with the same random effects), which is refitted.
A cbind(successes, failures) binomial response divides the binomial
value by the mean number of trials. A Gaussian GLMM with a non-identity
link uses sigma^2, as insight does for every Gaussian model: note that
this is the residual variance on the response scale, while the fixed and
random variances are on the link scale, so the R2 and ICC of such a fit
depend on the units of the response. Observation-level terms of a
Gaussian GLMM do not add to the residual variance (insight treats the
model as linear). These follow insight 1.5.
Inverse-Gaussian GLMMs are refused (mm_inference_unavailable, reason
code "r2_distribution_variance_undefined"). insight 1.5 has no
inverse-Gaussian branch and falls back to sigma() itself (the square
root of the dispersion, not a variance); since the inverse-Gaussian
dispersion has units of 1/y, that value, and the R2 and ICC built on
it, change when the response is rescaled. insight::get_variance() on a
mixeff inverse-Gaussian fit therefore returns NA with a warning.
Observation-level random effects (one level per observation) count towards the residual variance of a GLMM.
If a random-effect variance is below tolerance (a singular fit), the
random variance is not computed: mm_r2() and mm_icc() return NA
for the quantities that need it and signal a warning, as performance does.
mm_variance_components(): a named list with var.fixed,
var.random, var.residual, var.distribution, var.dispersion,
var.intercept, var.slope and cor.slope_intercept (the layout of
insight::get_variance()). mm_r2(): a list with R2_conditional and
R2_marginal. mm_icc(): a one-row data frame with ICC_adjusted,
ICC_conditional and ICC_unadjusted.
set.seed(1) g <- factor(rep(seq_len(10), each = 6)) df <- data.frame(x = rnorm(60), g = g) df$y <- 1 + 0.5 * df$x + rnorm(10)[g] + rnorm(60) fit <- lmm(y ~ x + (1 | g), df, control = mm_control(verbose = -1)) mm_r2(fit) mm_icc(fit)set.seed(1) g <- factor(rep(seq_len(10), each = 6)) df <- data.frame(x = rnorm(60), g = g) df$y <- 1 + 0.5 * df$x + rnorm(10)[g] + rnorm(60) fit <- lmm(y ~ x + (1 | g), df, control = mm_control(verbose = -1)) mm_r2(fit) mm_icc(fit)
model_report() assembles a structured, publication-oriented report from
the Rust artifact fields carried by a fitted model plus R-owned provenance
such as the call and session metadata. reporting_table() extracts one
section as a data-frame-compatible object.
model_report(fit, sections = "all", ...) ## S3 method for class 'mm_fit' model_report(fit, sections = "all", ...) reporting_table(object, section = "all", view = c("compact", "audit"), ...) ## S3 method for class 'mm_fit' reporting_table(object, section = "all", view = c("compact", "audit"), ...) ## S3 method for class 'mm_model_comparison' reporting_table( object, section = "comparison_ledger", view = c("compact", "audit"), ... ) ## S3 method for class 'mm_drop1' reporting_table( object, section = "comparison_ledger", view = c("compact", "audit"), ... ) ## S3 method for class 'mm_random_effect_test' reporting_table(object, section = "all", view = c("compact", "audit"), ...)model_report(fit, sections = "all", ...) ## S3 method for class 'mm_fit' model_report(fit, sections = "all", ...) reporting_table(object, section = "all", view = c("compact", "audit"), ...) ## S3 method for class 'mm_fit' reporting_table(object, section = "all", view = c("compact", "audit"), ...) ## S3 method for class 'mm_model_comparison' reporting_table( object, section = "comparison_ledger", view = c("compact", "audit"), ... ) ## S3 method for class 'mm_drop1' reporting_table( object, section = "comparison_ledger", view = c("compact", "audit"), ... ) ## S3 method for class 'mm_random_effect_test' reporting_table(object, section = "all", view = c("compact", "audit"), ...)
fit |
A fitted |
sections |
Character vector of report sections, or |
... |
Reserved for future methods. |
object |
For |
section |
One section name, or |
view |
|
model_report() returns an mm_model_report. reporting_table()
returns an mm_reporting_table object: $table holds the section's
data frame (or $sections the named list when section = "all").
Inspect the optimizer certificate
optimizer_certificate(object, ...) ## S3 method for class 'mm_compiled' optimizer_certificate(object, ...)optimizer_certificate(object, ...) ## S3 method for class 'mm_compiled' optimizer_certificate(object, ...)
object |
A compiled |
... |
Reserved for future methods. |
An mm_optimizer_certificate object containing the raw certificate
and a compact table view.
parameterization() exposes the fitted theta/Lambda mapping recorded in the
compiler artifact. It is the R table view of the upstream theta-map and
covariance-parameter trace records.
parameterization(object, ...) ## S3 method for class 'mm_compiled' parameterization(object, ...)parameterization(object, ...) ## S3 method for class 'mm_compiled' parameterization(object, ...)
object |
A compiled |
... |
Reserved for future methods. |
An mm_theta_map object with a data-frame table and raw trace
records.
Runs the engine-certified parametric-bootstrap likelihood-ratio test
between two nested ML-fitted LMMs through the Rust
mm_bootstrap_lrt_json entry point. The smaller model (fewer estimated
parameters) is the reduced model; the larger is the alternative. The
returned object carries the engine's replicate accounting (successful and
completed replicates, boundary count, Monte-Carlo standard error, seed)
rather than a bare mean() p-value, so every reported number traces back
to a versioned Rust payload.
parametric_bootstrap( null, alternative, nsim = 100L, seed = NULL, threads = 1L, ... )parametric_bootstrap( null, alternative, nsim = 100L, seed = NULL, threads = 1L, ... )
null, alternative
|
Fitted |
nsim |
Number of bootstrap replicates. |
seed |
Optional bootstrap seed. |
threads |
Worker threads for the replicate refits (default 1). The
responses are simulated serially and each replicate refits fresh copies
of both models, so the result is identical for every value; see
|
... |
Reserved for future methods. |
The engine refuses REML fits: refit with lmm(..., REML = FALSE) before
calling. (compare(method = "bootstrap") refits REML to ML automatically.)
An mm_parametric_bootstrap object.
plot() on a fitted model draws Pearson residuals against fitted values,
the default diagnostic of lme4's plot.merMod(), using base graphics.
which = 2 draws a normal quantile-quantile plot of the Pearson residuals
instead (also available as qqnorm(fit)), and which = 3 the
scale-location plot (sqrt(|r|) against fitted values).
## S3 method for class 'mm_lmm' plot( x, which = 1L, smooth = TRUE, ask = length(which) > 1L && grDevices::dev.interactive(), main = NULL, xlab = NULL, ylab = NULL, ... ) ## S3 method for class 'mm_glmm' plot( x, which = 1L, smooth = TRUE, ask = length(which) > 1L && grDevices::dev.interactive(), main = NULL, xlab = NULL, ylab = NULL, ... ) ## S3 method for class 'mm_lmm' qqnorm(y, main = NULL, xlab = NULL, ylab = NULL, ...) ## S3 method for class 'mm_glmm' qqnorm(y, main = NULL, xlab = NULL, ylab = NULL, ...)## S3 method for class 'mm_lmm' plot( x, which = 1L, smooth = TRUE, ask = length(which) > 1L && grDevices::dev.interactive(), main = NULL, xlab = NULL, ylab = NULL, ... ) ## S3 method for class 'mm_glmm' plot( x, which = 1L, smooth = TRUE, ask = length(which) > 1L && grDevices::dev.interactive(), main = NULL, xlab = NULL, ylab = NULL, ... ) ## S3 method for class 'mm_lmm' qqnorm(y, main = NULL, xlab = NULL, ylab = NULL, ...) ## S3 method for class 'mm_glmm' qqnorm(y, main = NULL, xlab = NULL, ylab = NULL, ...)
x, y
|
A fitted |
which |
Integer vector selecting the plots: |
smooth |
If |
ask |
Ask before each new plot when several are drawn on an interactive device. |
main, xlab, ylab
|
Optional titles overriding the defaults. |
... |
Further graphical parameters passed to |
Pearson residuals follow lme4's definition, (y - mu) sqrt(w) / sqrt(V(mu))
with prior weights w and variance function V (V = 1 for an LMM), on
the response scale; they are not divided by the residual standard
deviation.
x, invisibly. qqnorm() returns the list from
stats::qqnorm() invisibly.
plot.mm_ranef() for caterpillar and Q-Q plots of the random
effects; hatvalues.mm_lmm() for leverage and Cook's distance.
set.seed(1) df <- data.frame( y = rnorm(60), x = rnorm(60), g = factor(rep(seq_len(10), each = 6)) ) fit <- lmm(y ~ x + (1 | g), df, control = mm_control(verbose = -1)) plot(fit) plot(fit, which = 2) qqnorm(fit)set.seed(1) df <- data.frame( y = rnorm(60), x = rnorm(60), g = factor(rep(seq_len(10), each = 6)) ) fit <- lmm(y ~ x + (1 | g), df, control = mm_control(verbose = -1)) plot(fit) plot(fit, which = 2) qqnorm(fit)
plot() on the result of ranef() draws a caterpillar plot (dot chart)
of the conditional modes for each grouping factor and coefficient, with
levels sorted by their value and, when the object carries conditional
variances (ranef(fit, condVar = TRUE)), level prediction intervals,
mirroring lattice::dotplot() on lme4's ranef() output. qqnorm()
draws normal Q-Q plots of the conditional modes, one panel per grouping
factor and coefficient.
## S3 method for class 'mm_ranef' plot(x, level = 0.95, type = c("caterpillar", "qq"), ...) ## S3 method for class 'mm_ranef' qqnorm(y, ...)## S3 method for class 'mm_ranef' plot(x, level = 0.95, type = c("caterpillar", "qq"), ...) ## S3 method for class 'mm_ranef' qqnorm(y, ...)
x, y
|
An |
level |
Coverage of the intervals (default 0.95). |
type |
|
... |
Further graphical parameters passed to |
When the lattice package is loaded, lattice::dotplot() and
lattice::qqmath() also work on ranef() output and return one trellis
object per grouping factor, as they do for lme4.
Intervals are omitted for coefficients whose conditional variances are not
available (for example GLMM fits where ranef(condVar = TRUE) returns
NA variances).
x (or y), invisibly.
set.seed(1) df <- data.frame( y = rnorm(60), x = rnorm(60), g = factor(rep(seq_len(10), each = 6)) ) fit <- lmm(y ~ x + (1 | g), df, control = mm_control(verbose = -1)) re <- ranef(fit, condVar = TRUE) plot(re) qqnorm(re)set.seed(1) df <- data.frame( y = rnorm(60), x = rnorm(60), g = factor(rep(seq_len(10), each = 6)) ) fit <- lmm(y ~ x + (1 | g), df, control = mm_control(verbose = -1)) re <- ranef(fit, condVar = TRUE) plot(re) qqnorm(re)
GLMM predictions are computed on the R side from the stored fixed effects
(population, re.form = NA) or fixed effects plus conditional modes
(re.form = NULL, or a subset of the random terms via a one-sided
re.form formula), then mapped through the family link. This mirrors
lme4::predict.merMod for generalized models: type = "link" returns the
linear predictor and type = "response" the mean. Offsets written in the
formula (offset(log(t))) are evaluated from newdata; an offset =
argument offset must be supplied again through predict(offset = ).
## S3 method for class 'mm_glmm' predict( object, newdata = NULL, re.form = NULL, allow.new.levels = FALSE, type = c("response", "link"), se.fit = FALSE, interval = c("none", "confidence", "prediction"), level = 0.95, na.action = stats::na.pass, offset = NULL, ... )## S3 method for class 'mm_glmm' predict( object, newdata = NULL, re.form = NULL, allow.new.levels = FALSE, type = c("response", "link"), se.fit = FALSE, interval = c("none", "confidence", "prediction"), level = 0.95, na.action = stats::na.pass, offset = NULL, ... )
object |
A fitted |
newdata |
Optional new data. Must be a |
re.form |
Random-effects conditioning, following lme4. |
allow.new.levels |
When |
type |
Prediction scale. Gaussian LMMs use the same values for
|
se.fit |
Logical; when |
interval |
Interval type: |
level |
Confidence level for |
na.action |
Missing-value handling for |
offset |
Offset for |
... |
Reserved for generic compatibility. |
In-sample response predictions reuse the engine's certified fitted values.
Standard errors and confidence intervals: population (re.form = NA)
SEs are the fixed-effect Wald SE mapped through the link by the delta
method; conditional (re.form = NULL) SEs and confidence bounds come from
the engine prediction-variance payload. The engine certifies these rows
for method = "joint_laplace" fits and for pirls_profiled fits
whose post-fit profiled-optimum certificate is issued (per-row status
"available"). Uncertified fits (e.g. singular fits, or fits whose
certificate fails) keep status "degraded", and their conditional SEs and
bounds are withheld as NA with the engine's reason in the mm_reason
attribute — consistent with the package's "no fake certainty" contract.
For a fit with an offset, conditional SEs/intervals on newdata are
available on the link scale only.
Known lme4 2.1-0 discrepancy: for GLMMs with a free dispersion parameter
(Gamma, inverse Gaussian, Gaussian with a non-identity link) lme4 >= 2.1-0
builds predict(se.fit = TRUE) from sigma()^2 times its unscaled
penalized least-squares covariance, although its PIRLS weights already
carry 1 / phi. mixeff's SEs use the engine's covariance (vcov(),
without the extra sigma^2), so they differ from lme4 2.1's by roughly a
factor of sigma().
Prediction (future-observation) intervals (interval = "prediction") are
available for conditional, response-scale predictions: the engine returns
quantiles of the plug-in predictive distribution (the family conditional
distribution mixed over link-scale fitted-mean uncertainty), so bounds are
integers for count families and support points for Bernoulli. They are
refused with a typed condition on the link scale (future observations are
response-scale objects), for population-level requests, and for grouped
binomial fits (the future trial count is not representable in newdata).
A numeric vector, or a list with fit and se.fit when
se.fit = TRUE.
Predictions follow the lme4 generic shape. In-sample predictions reuse
the cached fitted/fixed values; new-data predictions are dispatched
through the Rust predict_new contract.
## S3 method for class 'mm_lmm' predict( object, newdata = NULL, re.form = NULL, allow.new.levels = FALSE, type = c("response", "link"), se.fit = FALSE, interval = c("none", "confidence", "prediction"), level = 0.95, na.action = stats::na.pass, offset = NULL, ... ) ## S3 method for class 'mm_lmm' fitted(object, ...) ## S3 method for class 'mm_lmm' residuals( object, type = c("response", "pearson", "deviance", "working"), scaled = FALSE, ... ) ## S3 method for class 'mm_glmm' fitted(object, ...) ## S3 method for class 'mm_glmm' residuals( object, type = c("deviance", "pearson", "working", "response"), scaled = FALSE, ... )## S3 method for class 'mm_lmm' predict( object, newdata = NULL, re.form = NULL, allow.new.levels = FALSE, type = c("response", "link"), se.fit = FALSE, interval = c("none", "confidence", "prediction"), level = 0.95, na.action = stats::na.pass, offset = NULL, ... ) ## S3 method for class 'mm_lmm' fitted(object, ...) ## S3 method for class 'mm_lmm' residuals( object, type = c("response", "pearson", "deviance", "working"), scaled = FALSE, ... ) ## S3 method for class 'mm_glmm' fitted(object, ...) ## S3 method for class 'mm_glmm' residuals( object, type = c("deviance", "pearson", "working", "response"), scaled = FALSE, ... )
object |
A fitted |
newdata |
Optional new data. Must be a |
re.form |
Random-effects conditioning, following lme4. |
allow.new.levels |
When |
type |
Prediction scale. Gaussian LMMs use the same values for
|
se.fit |
Logical; when |
interval |
Interval type: |
level |
Confidence level for |
na.action |
Missing-value handling for |
offset |
Offset for |
... |
Reserved for generic compatibility. |
scaled |
Logical; when |
A numeric vector, or a list with fit and se.fit when
se.fit = TRUE.
Computes profile-likelihood intervals for the model's parameters via the
engine's certified profile payload and returns them as an mm_profile
object: $table has one row per profiled parameter (parameter,
parameter_kind, estimate, lower, upper, regularity, status,
reason_code, reason, profiled_criterion). Rows use lme4's names: .sig01,
... (kind "sd" or "cor", numbered in lme4's term order), .sigma,
and the fixed effects, all profiled on the ML deviance as lme4 does (a
REML fit is refitted by ML); the engine's relative-Cholesky theta1, ...
rows follow, profiled on the fit's own criterion. Use confint() with
method = "profile" for the matrix form.
## S3 method for class 'mm_lmm' profile(fitted, which = NULL, level = 0.95, threads = 1L, ...)## S3 method for class 'mm_lmm' profile(fitted, which = NULL, level = 0.95, threads = 1L, ...)
fitted |
A fitted |
which |
Optional character vector of parameter names to keep
(coefficient names, |
level |
Confidence level for the reported interval endpoints. |
threads |
Worker threads (default 1); see |
... |
Unused; for generic consistency. |
A parameter whose profile is irregular keeps its row: status is
"non_monotone" (the signed-root deviance is not monotone),
"not_bracketing" (the profile does not reach the cutoff on one side),
or "failed" (a constrained refit failed); reason_code holds the
matching regularity code ("non_monotone_profile",
"profile_not_bracketing", "profile_failed") and reason the engine's
explanation. Bounds the profile cannot determine are NA; a bound inside
the regular part of the profile is still reported. lme4 instead warns
and falls back to linear interpolation (often giving [-1, 1] for a
correlation); mixeff reports NA plus the reason rather than an
interpolated bound. The other parameters' intervals are unaffected.
An mm_profile object with $table, $level, $fit_criterion,
and $notes.
confint() with method = "profile" for the matrix form.
random_blocks() summarizes the random-effect block structure recorded in
the compiler artifact: grouping factor, basis, covariance family, theta
parameter count, level counts, and design-support status.
random_blocks(object, ...) ## S3 method for class 'mm_compiled' random_blocks(object, ...)random_blocks(object, ...) ## S3 method for class 'mm_compiled' random_blocks(object, ...)
object |
A compiled |
... |
Reserved for future methods. |
An mm_random_blocks object with a data-frame table.
random_options() is an opt-in map over nearby random-effect structures
for a grouping factor. It recompiles each displayed spelling through the
same upstream audit path as compile_model(), so support facts and block
meanings come from Rust-authored RandomTermCard records.
random_options(spec, group, slope = NULL)random_options(spec, group, slope = NULL)
spec |
An |
group |
Grouping factor to inspect. May be supplied bare
( |
slope |
Optional slope variable to use for nearby slope-bearing
spellings. When omitted, the function uses the first current random
slope for |
An object of class mm_random_options with an options data frame,
the upstream candidate cards, and the candidate audit reports.
refit() fits the same model to a new response, keeping every other
setting of the original fit, like lme4::refit(). For an mm_lmm it calls
lmm() with the stored model frame, REML setting and prior weights; for
an mm_glmm it calls glmm() with the stored family (negative-binomial
fits re-estimate theta when the original did), prior weights, offset,
method, nAGQ and control settings (verbosity silenced).
refit(object, newresp, ...) ## Default S3 method: refit(object, newresp, ...) ## S3 method for class 'mm_lmm' refit(object, newresp, ...) ## S3 method for class 'mm_glmm' refit(object, newresp, ...)refit(object, newresp, ...) ## Default S3 method: refit(object, newresp, ...) ## S3 method for class 'mm_lmm' refit(object, newresp, ...) ## S3 method for class 'mm_glmm' refit(object, newresp, ...)
object |
A fitted |
newresp |
The new response (see Details). |
... |
|
newresp may be a numeric vector, or a one-column data frame such as the
output of simulate() with nsim = 1. For binomial GLMMs it may also be a
two-column (successes, failures) matrix (the shape simulate() returns
for a cbind() response; the trial counts become the new prior weights),
a two-level factor, or a logical vector.
As in lme4, newresp is on the scale of the model's response: for a
transformed response such as log(y) ~ ... it replaces log(y), and the
refit's formula names it .mm_refit_response.
A new fit of the same class as object.
set.seed(1) df <- data.frame( y = rpois(60, 3), x = rnorm(60), g = factor(rep(seq_len(10), each = 6)) ) fit <- glmm(y ~ x + (1 | g), df, family = poisson(), control = mm_control(verbose = -1)) ystar <- simulate(fit, nsim = 1, seed = 2) fixef(refit(fit, ystar))set.seed(1) df <- data.frame( y = rpois(60, 3), x = rnorm(60), g = factor(rep(seq_len(10), each = 6)) ) fit <- glmm(y ~ x + (1 | g), df, family = poisson(), control = mm_control(verbose = -1)) ystar <- simulate(fit, nsim = 1, seed = 2) fixef(refit(fit, ystar))
REMLcrit() mirrors lme4::REMLcrit(): the REML criterion (-2 times the
restricted log-likelihood) at the fitted parameters. For a REML fit this
is -2 * logLik(fit). For an ML fit it is the REML criterion evaluated at
the ML estimates of the covariance parameters, computed from the
penalized least-squares decomposition (getME(fit, "devcomp")), exactly
as lme4 does. lme4::REMLcrit() is a plain function rather than a
generic, so mixeff exports its own; it forwards merMod objects to lme4.
REMLcrit(object)REMLcrit(object)
object |
A fitted |
A single number.
set.seed(1) df <- data.frame(y = rnorm(60), x = rnorm(60), g = factor(rep(seq_len(10), each = 6))) fit <- lmm(y ~ x + (1 | g), df, control = mm_control(verbose = -1)) REMLcrit(fit)set.seed(1) df <- data.frame(y = rnorm(60), x = rnorm(60), g = factor(rep(seq_len(10), each = 6))) fit <- lmm(y ~ x + (1 | g), df, control = mm_control(verbose = -1)) REMLcrit(fit)
rePCA())For each grouping factor, the singular values and left singular vectors
of the relative covariance factor (the block-diagonal Cholesky factor of
the random-effect covariance divided by the residual variance, lme4's
Lambda), returned as prcomp objects. Near-zero standard deviations
flag a random-effect structure that is over-parameterised (singular).
summary() gives each component's proportion of variance.
rePCA(x) ## Default S3 method: rePCA(x) ## S3 method for class 'mm_lmm' rePCA(x) ## S3 method for class 'mm_glmm' rePCA(x)rePCA(x) ## Default S3 method: rePCA(x) ## S3 method for class 'mm_lmm' rePCA(x) ## S3 method for class 'mm_glmm' rePCA(x)
x |
A fitted |
Singular values match lme4::rePCA(); the rotation columns are
eigenvectors of the same matrix and may differ from lme4's in sign.
An object of class c("mm_prcomplist", "prcomplist"): a named list (one entry per
grouping factor) of prcomp objects.
set.seed(1) d <- data.frame(g = factor(rep(1:10, each = 6)), x = rep(0:5, 10)) d$y <- 1 + 0.5 * d$x + rnorm(10)[d$g] + rnorm(10, sd = 0.3)[d$g] * d$x + rnorm(60) fit <- lmm(y ~ x + (x | g), d, control = mm_control(verbose = -1)) summary(rePCA(fit))set.seed(1) d <- data.frame(g = factor(rep(1:10, each = 6)), x = rep(0:5, 10)) d$y <- 1 + 0.5 * d$x + rnorm(10)[d$g] + rnorm(10, sd = 0.3)[d$g] * d$x + rnorm(60) fit <- lmm(y ~ x + (x | g), d, control = mm_control(verbose = -1)) summary(rePCA(fit))
Inspect reproducibility metadata
reproducibility(object, ...) ## S3 method for class 'mm_compiled' reproducibility(object, ...)reproducibility(object, ...) ## S3 method for class 'mm_compiled' reproducibility(object, ...)
object |
A compiled |
... |
Reserved for future methods. |
An mm_reproducibility object.
revive() restores the process-local parts of a mixeff object after
saveRDS() / readRDS() or a worker restart. The fitted artifact and flat
extractor values are the durable source of truth; the Rust handle is only a
cache and may be absent. Revival recreates the lazy R-side cache, keeps a
live native handle, and clears a dead one (an external pointer restored by
readRDS()); it does not refit the model. Without a live handle,
computations that need the engine model (contrasts, summary() tests,
predictions with intervals, profiles, bootstraps) refit it from the stored
model frame, with identical results.
revive(fit, ...) ## S3 method for class 'mm_fit' revive(fit, ...)revive(fit, ...) ## S3 method for class 'mm_fit' revive(fit, ...)
fit |
A fitted |
... |
Reserved for future methods. |
A revived mm_fit object.
roles() has two uses. With named string arguments it constructs
a declared-role object, e.g. roles(subject = "sampled_unit"). With a
compiled spec or fit as its only unnamed argument, it returns the observed
role fallback inferred from the formula and model frame.
roles(...)roles(...)
... |
Either named role strings or one unnamed |
An mm_roles object with a data-frame table.
Draws responses from a fitted mm_lmm or mm_glmm following the
semantics of lme4::simulate.merMod():
## S3 method for class 'mm_lmm' simulate(object, nsim = 1, seed = NULL, use.u = FALSE, re.form = NA, ...) ## S3 method for class 'mm_glmm' simulate(object, nsim = 1, seed = NULL, use.u = FALSE, re.form = NA, ...)## S3 method for class 'mm_lmm' simulate(object, nsim = 1, seed = NULL, use.u = FALSE, re.form = NA, ...) ## S3 method for class 'mm_glmm' simulate(object, nsim = 1, seed = NULL, use.u = FALSE, re.form = NA, ...)
object |
A fitted |
nsim |
Number of simulated responses. |
seed |
Optional random seed. |
use.u |
Logical; |
re.form |
|
... |
Reserved; lme4 arguments that cannot be honoured ( |
re.form = NA (the default) or ~0, equivalently use.u = FALSE,
draws new random effects from the fitted random-effect covariance
for every simulation (unconditional, parametric-bootstrap simulation);
re.form = NULL, equivalently use.u = TRUE, conditions on the fitted
conditional modes (BLUPs) and simulates only the response noise around
fitted(object).
Partial random-effect formulas are refused with a typed
mm_inference_unavailable error.
LMM responses are Gaussian with standard deviation sigma / sqrt(w) for
prior weights w (lme4 ignores the prior weights here). GLMM responses are
family-aware: binomial draws use the prior weights as trial counts and
return proportions (y / w, 0/1 values for Bernoulli fits), or a
two-column (successes, failures) matrix per simulation when the model was
fitted with a cbind() response, as lme4 does; Poisson and
negative-binomial (fitted theta) draws return counts. For the families
with a free dispersion phi = sigma(object)^2 the draws follow the
fitted variance function: Gamma draws use shape w / phi
(Var(y) = phi mu^2 / w), inverse-Gaussian draws use
statmod::rinvgauss() with shape w / phi (Var(y) = phi mu^3 / w;
needs the statmod package), and Gaussian non-identity-link draws have
standard deviation sigma / sqrt(w). New random effects are drawn on the
absolute scale of VarCorr(), as lme4 >= 2.1-0 does (its theta is the
absolute random-effect SD for every GLMM).
Compared with lme4 2.1-0's simulate.merMod(): Gamma draws and Gaussian
draws without prior weights agree draw for draw (same RNG use) when the
estimates agree. lme4 ignores prior weights for Gaussian responses (with a
warning); mixeff uses them, as for LMMs. For the inverse Gaussian lme4
passes shape w / sigma(object) – sqrt(phi), not phi – so its draws
have variance sigma mu^3 / w rather than the fitted phi mu^3 / w;
mixeff uses the fitted variance, as stats::inverse.gaussian()$simulate
does. A binomial fit whose response was a factor is simulated as 0/1
numeric (lme4 returns a factor).
The random-number stream is consumed in lme4's order (all random-effect
draws first, terms in lme4's internal order, then the response draws), so
when the estimates agree a seeded simulate() reproduces lme4's draws.
Unlike lme4, a supplied seed does not leave the global RNG state changed.
A data frame with one column per simulation (sim_1, ...), rows
named like the model frame. For a binomial cbind() fit each column is a
two-column matrix. Attributes seed, mm_method and mm_re_form record
the seed, the simulation route, and the resolved conditioning
("unconditional", "conditional" or "partial"). Following
stats::simulate, attribute "seed" is the .Random.seed in force
before simulation when seed = NULL, otherwise seed with the RNG kind
as attribute "kind".
set.seed(1) df <- data.frame( y = rnorm(60), x = rnorm(60), g = factor(rep(seq_len(10), each = 6)) ) fit <- lmm(y ~ x + (1 | g), df, control = mm_control(verbose = -1)) head(simulate(fit, nsim = 2, seed = 1)) # condition on the fitted random effects head(simulate(fit, nsim = 1, seed = 1, re.form = NULL)) df$count <- rpois(60, 2) gfit <- glmm(count ~ x + (1 | g), df, family = poisson(), control = mm_control(verbose = -1)) head(simulate(gfit, nsim = 2, seed = 1))set.seed(1) df <- data.frame( y = rnorm(60), x = rnorm(60), g = factor(rep(seq_len(10), each = 6)) ) fit <- lmm(y ~ x + (1 | g), df, control = mm_control(verbose = -1)) head(simulate(fit, nsim = 2, seed = 1)) # condition on the fitted random effects head(simulate(fit, nsim = 1, seed = 1, re.form = NULL)) df$count <- rpois(60, 2) gfit <- glmm(count ~ x + (1 | g), df, family = poisson(), control = mm_control(verbose = -1)) head(simulate(gfit, nsim = 2, seed = 1))
stats::step() is not a generic, so mixeff (like lmerTest) exports a
step() generic whose default method is stats::step(); the mm_lmm
method is the lmerTest-style backward elimination documented in
step.mm_lmm().
step(object, ...) ## Default S3 method: step(object, ...)step(object, ...) ## Default S3 method: step(object, ...)
object |
A fitted model. |
... |
Passed to the method (for the default, to |
See the method.
step())step() for mm_lmm fits follows lmerTest::step(): it first removes
random-effect terms one at a time while the least significant has
p > alpha.random, then removes fixed-effect terms (respecting
marginality: a term is only dropped when no higher-order term contains
it) while the least significant has p > alpha.fixed, refitting after
every removal.
## S3 method for class 'mm_lmm' step( object, ddf = c("Satterthwaite", "Kenward-Roger"), alpha.random = 0.1, alpha.fixed = 0.05, reduce.fixed = TRUE, reduce.random = TRUE, keep, ... )## S3 method for class 'mm_lmm' step( object, ddf = c("Satterthwaite", "Kenward-Roger"), alpha.random = 0.1, alpha.fixed = 0.05, reduce.fixed = TRUE, reduce.random = TRUE, keep, ... )
object |
A fitted |
ddf |
Denominator degrees of freedom for the fixed-effect F tests. |
alpha.random, alpha.fixed
|
Elimination thresholds. |
reduce.fixed, reduce.random
|
Whether to eliminate fixed / random terms. |
keep |
Character vector of fixed-effect terms never to remove. |
... |
Unused. |
Differences from lmerTest, by design: random terms are tested with
test_random_effect()'s boundary-corrected likelihood-ratio test (a
chi-bar-square mixture, so p-values are about half of lmerTest's
ranova() naive chi-square); only whole random terms are removed
(lmerTest's ranova() also tries reducing (x | g) to (1 | g) –
write the reduced term as its own term, e.g. (1 | g) + (0 + x | g), to
make that reduction available); and the last random term is never
removed (a model without random effects is not an LMM). Fixed terms are
tested with test_effect() (ddf = "Satterthwaite" or
"Kenward-Roger").
An object of class mm_step with the elimination tables
random and fixed and the final model in $model (also returned by
lmerTest::get_model() when lmerTest is loaded).
set.seed(1) d <- data.frame(g = factor(rep(1:10, each = 6)), x = rep(0:5, 10), z = rnorm(60)) d$y <- 1 + 0.5 * d$x + rnorm(10)[d$g] + rnorm(60) fit <- lmm(y ~ x + z + (1 | g) + (0 + x | g), d, control = mm_control(verbose = -1)) s <- step(fit) s s$modelset.seed(1) d <- data.frame(g = factor(rep(1:10, each = 6)), x = rep(0:5, 10), z = rnorm(60)) d$y <- 1 + 0.5 * d$x + rnorm(10)[d$g] + rnorm(60) fit <- lmm(y ~ x + z + (1 | g) + (0 + x | g), d, control = mm_control(verbose = -1)) s <- step(fit) s s$model
supported_models() returns the package's machine-readable support
registry: which GLMM family/link/estimator combinations are supported,
which features are supported, refused, or carry mixeff-specific
semantics, and the package's explicit non-goals. The registry ships as
inst/support/model-support.json and is the single source of truth for
the migration vignette's support table; the test suite asserts that the
fitting code enforces exactly this envelope (unsupported combinations
refuse with the declared condition classes and reason codes).
supported_models()supported_models()
mixeff aims for tested statistical agreement with lme4 on this envelope
— a documented, closed surface — not blanket equivalence with everything
lmer()/glmer() accept.
A list of class mm_model_support with elements
glmm_families (data frame: family, links, estimators, notes),
features (data frame: feature, lmm, glmm, notes), non_goals
(character), and registry (the parsed JSON, verbatim).
supported_models()supported_models()
test_effect() asks Rust to construct fixed-effect term hypotheses and
returns the corresponding fixed-effect inference rows.
test_effect( fit, term, method = c("auto", "satterthwaite", "kenward_roger", "bootstrap", "bootstrap_lrt", "cluster_bootstrap", "asymptotic", "boundary_lrt", "none"), bootstrap = NULL, group = NULL, ... ) ## S3 method for class 'mm_lmm' test_effect( fit, term, method = c("auto", "satterthwaite", "kenward_roger", "bootstrap", "bootstrap_lrt", "cluster_bootstrap", "asymptotic", "boundary_lrt", "none"), bootstrap = NULL, group = NULL, ... )test_effect( fit, term, method = c("auto", "satterthwaite", "kenward_roger", "bootstrap", "bootstrap_lrt", "cluster_bootstrap", "asymptotic", "boundary_lrt", "none"), bootstrap = NULL, group = NULL, ... ) ## S3 method for class 'mm_lmm' test_effect( fit, term, method = c("auto", "satterthwaite", "kenward_roger", "bootstrap", "bootstrap_lrt", "cluster_bootstrap", "asymptotic", "boundary_lrt", "none"), bootstrap = NULL, group = NULL, ... )
fit |
A fitted |
term |
A fixed-effect term label. |
method |
Requested inference method. |
bootstrap |
Optional |
group |
Optional grouping factor for |
... |
Reserved for future methods. |
An mm_effect_test object.
test_random_effect() exposes the boundary-aware likelihood-ratio route for
random-effect variance components. The v1 certified route is a nested ML
comparison that adds exactly one variance parameter and reports the
Self-Liang 50:50 mixture reference distribution; a comparison that adds
only correlation parameters (e.g. || versus |) is referred to the
ordinary chi-square, since a zero correlation is interior to the
parameter space (method = "boundary_lrt_ordinary_chisq"). It is intentionally
separate from test_effect(), which tests fixed effects.
test_random_effect( fit, term, method = c("boundary_lrt"), refit_for_comparison = c("auto", "error", "ml"), ... ) ## S3 method for class 'mm_lmm' test_random_effect( fit, term, method = c("boundary_lrt"), refit_for_comparison = c("auto", "error", "ml"), ... )test_random_effect( fit, term, method = c("boundary_lrt"), refit_for_comparison = c("auto", "error", "ml"), ... ) ## S3 method for class 'mm_lmm' test_random_effect( fit, term, method = c("boundary_lrt"), refit_for_comparison = c("auto", "error", "ml"), ... )
fit |
A fitted |
term |
Random-effect term to test. This can be the term id ( |
method |
Currently |
refit_for_comparison |
How to handle REML fits. |
... |
Reserved for future methods. |
An mm_random_effect_test object with a one-row table.
update() re-fits an mm_lmm or mm_glmm with a modified
model specification, mirroring stats::update() and lme4's update() for
the common cases: changing the formula (. ~ . - x), toggling REML,
swapping weights/offset/family/control, or supplying new data.
## S3 method for class 'mm_lmm' update(object, formula., ..., evaluate = TRUE) ## S3 method for class 'mm_glmm' update(object, formula., ..., evaluate = TRUE)## S3 method for class 'mm_lmm' update(object, formula., ..., evaluate = TRUE) ## S3 method for class 'mm_glmm' update(object, formula., ..., evaluate = TRUE)
object |
A fitted |
formula. |
A formula-change applied with |
... |
Arguments to override on the re-fit. For |
evaluate |
If |
The re-fit reuses the fitted model frame (model.frame()) as the default
data source, so formula edits that remove terms or change estimation
options work without re-supplying data. A formula edit that introduces a
new variable absent from the original model frame requires an explicit
data = argument.
A new fitted model of the same class as object, or an unevaluated
call when evaluate = FALSE.
set.seed(1) df <- data.frame( y = rnorm(80), x = rnorm(80), z = rnorm(80), g = factor(rep(seq_len(10), each = 8)) ) fit <- lmm(y ~ x + z + (1 | g), df, control = mm_control(verbose = -1)) # drop a fixed term fit2 <- update(fit, . ~ . - z) # refit by ML for a likelihood-ratio comparison fit_ml <- update(fit, REML = FALSE) fixef(fit2)set.seed(1) df <- data.frame( y = rnorm(80), x = rnorm(80), z = rnorm(80), g = factor(rep(seq_len(10), each = 8)) ) fit <- lmm(y ~ x + z + (1 | g), df, control = mm_control(verbose = -1)) # drop a fixed term fit2 <- update(fit, . ~ . - z) # refit by ML for a likelihood-ratio comparison fit_ml <- update(fit, REML = FALSE) fixef(fit2)
verify_convergence() re-runs the fit under the engine's bounded
verification workflow and reports whether the extra runs agree with the
fitted optimum: a restart from the optimum, one or more jittered restarts,
and (LMM-only, opt-in) an alternate-optimizer consensus pass. Agreement is
judged by the engine against the objective/theta/beta tolerances below;
the verdict (status), the per-run deltas, and the wording are all owned
by the Rust contract — R only formats them.
verify_convergence(fit, ...) ## Default S3 method: verify_convergence(fit, ...) ## S3 method for class 'mm_lmm' verify_convergence( fit, ..., restart = TRUE, jitter_starts = 1L, jitter_scale = 1e-04, consensus = FALSE, max_feval = 500L, objective_tolerance = 1e-05, theta_tolerance = 0.001, beta_tolerance = 1e-04 ) ## S3 method for class 'mm_glmm' verify_convergence( fit, ..., restart = TRUE, jitter_starts = 1L, jitter_scale = 1e-04, consensus = FALSE, max_feval = 1000L, objective_tolerance = 1e-04, theta_tolerance = 0.001, beta_tolerance = 0.001 )verify_convergence(fit, ...) ## Default S3 method: verify_convergence(fit, ...) ## S3 method for class 'mm_lmm' verify_convergence( fit, ..., restart = TRUE, jitter_starts = 1L, jitter_scale = 1e-04, consensus = FALSE, max_feval = 500L, objective_tolerance = 1e-05, theta_tolerance = 0.001, beta_tolerance = 1e-04 ) ## S3 method for class 'mm_glmm' verify_convergence( fit, ..., restart = TRUE, jitter_starts = 1L, jitter_scale = 1e-04, consensus = FALSE, max_feval = 1000L, objective_tolerance = 1e-04, theta_tolerance = 0.001, beta_tolerance = 0.001 )
fit |
|
... |
Reserved for future methods. |
restart |
Logical; re-optimize starting from the fitted optimum and compare against it. |
jitter_starts |
Number of restarts from jittered copies of the fitted covariance parameters. |
jitter_scale |
Relative scale of the jitter applied to theta. |
consensus |
Logical; also refit with an engine-chosen alternate
optimizer and compare. Default |
max_feval |
Positive integer cap on objective evaluations per verification run. |
objective_tolerance, theta_tolerance, beta_tolerance
|
Positive agreement tolerances on the objective value, the covariance parameters, and the fixed effects. |
The verifier refits the model from the stored specification before it
starts, so a call costs roughly 2 + jitter_starts fits (plus consensus
runs when enabled). GLMM verification uses wider default tolerances than
the LMM route (objective 1e-4, beta 1e-3): each objective evaluation
carries inner-PIRLS noise, and the joint path's derivative-free beta
search bounds beta reproducibility at its ftol stop. A GLMM whose
requested joint_laplace estimator was substituted by the labelled
fast-PIRLS fallback (see optimizer_certificate()) re-requests the joint
route; when the verification refit falls back the same way — the expected
case — every run verifies the profiled objective the fitted numbers came
from, with ordinary objective deltas. Runs are only reported as
substitution runs (no objective delta) in the asymmetric case where the
reference refit certifies the joint route but an individual verification
run falls back.
An object of class mm_convergence_verification carrying:
statusthe engine verdict: not_run, restart_agrees,
optimizer_consensus, fragile, or unstable
messagethe engine's one-line summary
tablea data frame with one row per verification run (label, optimizer, return code, objective/theta/beta deltas, agreement)
referencethe reference optimum the runs were compared to
tolerancesthe agreement tolerances that were applied
rawthe parsed engine payload
optimizer_certificate() for what the original fit ran;
mm_control() to refit with a different optimizer or tolerances.
set.seed(1) df <- data.frame(t = rep(0:4, 8), s = factor(rep(1:8, each = 5))) df$y <- 1 + 0.5 * df$t + rnorm(8)[df$s] + rnorm(40) fit <- lmm(y ~ t + (1 | s), df, control = mm_control(verbose = -1)) verify_convergence(fit)set.seed(1) df <- data.frame(t = rep(0:4, 8), s = factor(rep(1:8, each = 5))) df$y <- 1 + 0.5 * df$t + rnorm(8)[df$s] + rnorm(40) fit <- lmm(y ~ t + (1 | s), df, control = mm_control(verbose = -1)) verify_convergence(fit)