compare: Compare Bayesian Models Fitted with INLAvaan

compareR Documentation

Compare Bayesian Models Fitted with INLAvaan

Description

Compare two or more Bayesian SEM fitted with INLAvaan, reporting model-fit statistics and (optionally) fit indices side by side.

Usage

compare(x, y, ..., fit.measures = NULL, loo = FALSE)

## S4 method for signature 'INLAvaan'
compare(x, y, ..., fit.measures = NULL, loo = FALSE)

## S4 method for signature 'INLAvaan'
anova(object, ...)

Arguments

x, y, ...

Two or more INLAvaan (or inlavaan_internal) objects fitted to the same data.

fit.measures

Character vector of additional fit-measure names to include (e.g. "BRMSEA", "BCFI"). Use "all" to include every measure returned by fitMeasures(). The default (NULL) shows only the core comparison statistics.

loo

Logical; if TRUE, compare models by leave-one-out cross-validation with paired standard errors (see Details). Defaults to FALSE.

object

An INLAvaan object (the anova() method, which is disabled and redirects to compare()).

Details

All models appear in the comparison table. When incremental fit indices (BCFI, BTLI, BNFI) are requested via fit.measures, they are scaled against the independence (null) model, fitted once on the data of the first model and shared by every model in the table (see bfit_indices()).

The default table always includes:

  • npar: Number of free parameters.

  • Marg.Loglik: Approximated marginal log-likelihood.

  • logBF: Natural-log Bayes factor relative to the best model.

  • DIC / pD: Deviance Information Criterion and effective number of parameters (when the fit computed the DIC, i.e. test included "dic" during fitting; the default "standard" does).

Set fit.measures to a character vector of measure names (anything returned by fitMeasures()) to append extra columns. Use fit.measures = "all" to include every available measure.

Set loo = TRUE to compare models by leave-one-out cross-validation (see loo()). This appends ELPD / SE (the Taylor expected log predictive density and its standard error), p_loo, and, against the best-ELPD model, the difference elpd_diff with its paired standard error se_diff computed from the pointwise contributions (the appropriate uncertainty for nested or same-data comparisons). Every model is scored at one common Taylor order, the lowest any of them can supply: if some unit of some model has no second-order term, all models are compared at first order, since otherwise a change of estimator between models would read as a difference between the models themselves. The order used is stated when the table is printed. The table is then sorted by descending ELPD. All models must be fitted to the same data with matching units; units are paired by id rather than by row order, so fits that stack groups differently – a pooled fit against a multigroup fit, or multigroup fits with different group orderings – still pair up unit by unit. For missing-data (FIML) fits, "the same data" also means the same observed entries: each unit is scored on the entries it has, so comparisons require identical missingness patterns across models. All models must also share the score flavour (see loo()): mixing fits with modelled covariates (fixed.x = FALSE, joint scores) and fixed covariates (fixed.x = TRUE, conditional scores) is refused. Joint scores additionally require identical variable sets across models, while conditional scores require only matching outcome variables – covariate sets may differ, which is the covariate-selection setting. Stored LOO results (test including "loo" or "full", or add_loo()) are reused.

anova() is disabled for INLAvaan fits – there is no direct Bayesian analogue of the classical likelihood-ratio test – and points here instead.

Value

A data frame of class compare.inlavaan_internal containing model fit statistics, sorted by descending marginal log-likelihood (or by descending ELPD when loo = TRUE).

References

https://lavaan.ugent.be/tutorial/groups.html

See Also

fitmeasures(), bfit_indices()

Examples


# Model comparison on multigroup analysis (measurement invariance)
HS.model <- "
  visual  =~ x1 + x2 + x3
  textual =~ x4 + x5 + x6
  speed   =~ x7 + x8 + x9
"
utils::data("HolzingerSwineford1939", package = "lavaan")

# Configural invariance
fit1 <- acfa(HS.model, data = HolzingerSwineford1939, group = "school")

# Weak invariance
fit2 <- acfa(
  HS.model,
  data = HolzingerSwineford1939,
  group = "school",
  group.equal = "loadings"
)

# Strong invariance
fit3 <- acfa(
  HS.model,
  data = HolzingerSwineford1939,
  group = "school",
  group.equal = c("intercepts", "loadings")
)

# Compare models (fit1 = configural = baseline, always first argument)
compare(fit1, fit2, fit3)

# With extra fit measures
compare(fit1, fit2, fit.measures = c("BRMSEA", "BMc"))

# With incremental indices (baseline = fit1, passed to fitMeasures())
compare(fit1, fit2, fit3, fit.measures = c("BCFI", "BTLI"))


INLAvaan documentation built on Oct. 2, 2026, 1:07 a.m.