
Empirical Equivalent Models
eq_models.RdIdentify model(s) in a list of models (parameter tables) empirically equivalent to the original model.
Usage
eq_models(
partables = NULL,
original_model = NULL,
...,
se = "none",
parallel = TRUE,
ncores = max(parallel::detectCores(logical = FALSE) - 1, 1),
make_cluster_args = list(),
progress = interactive(),
tolerance = c(chisq = 1e-05),
eq_df_models_args = list()
)
is_eq(
partables = NULL,
original_model = NULL,
...,
se = "none",
parallel = TRUE,
ncores = max(parallel::detectCores(logical = FALSE) - 1, 1),
make_cluster_args = list(),
progress = interactive(),
tolerance = c(chisq = 1e-05),
eq_df_models_args = list()
)Arguments
- partables
A list of the class
partables. IfNULL,eq_models()will try to generate the models by callingeq_df_models()on the argument oforiginal_model. For[is_eq()], this argument cannot beNULL.- original_model
The original model, fitted by
lavaan::lavaan()or its wrapper, such aslavaan::sem(). If it is alavaanparameter table (the output oflavaan::parameterTable()), data will be simulated to fit the model. If it isNULL, then the first model inpartableswill be used.- ...
Optional arguments to be used when fitting models to the data, to be passed to
lavaan::sem(). Usually can be omitted.- se
How standard errors are to be computed. To be passed to
lavaan::sem(). The default,"none", is sufficient because the standard errors are not needed to check whether two models are empirically equivalent.- parallel
Whether parallel processing will be used when fitting models. Default is
TRUE. To be passed tomodelbpp::fit_many().- ncores
The number of CPU cores to use when parallel processing is used. To be passed to
modelbpp::fit_many().- make_cluster_args
Additional arguments to be passed to
modelbpp::fit_many()when creating a cluster for parallel processing. To be passed tomodelbpp::fit_many().- progress
Whether the testing progress will be displayed on screen.
- tolerance
The maximum absolute difference in a fit measure for two models to be considered empirically equivalent. It should be a named numeric vector, with the names being an acceptable value of the name of fit measures in
lavaan::fitMeasures(). For example, the default fit measure is"chisq", model chi-square. If set toc(chisq = 1e-5, cfi = .01), then two models are considered empirically equivalent if their differences on model chi-square and CFI are at most 1e-5 and .01, respectively.- eq_df_models_args
If
partablesis not supplied (NULL) butoriginal_modelis set,eq_df_models()will be called to generate the models. This argument must be a named list of additional arguments to be passed toeq_df_models().
Value
The function eq_models()
returns a list of the class eq_partables
(a subclass of partables)
of models that are empirically
equivalent to the original model.
The function is_eq() returns a
logical vector of the same length
of patables, with TRUE denoting
that a model is empirically equivalent
to original_model.
Details
eq_models()
The function eq_models()
checks the model degrees of freedom
and model chi-squares of a list of
models (represented by lavaan
parameter tables) against an original model,
fitted to a sample, to identify models
that are empirically equivalent
to the original model in this sample.
Two models are empirically equivalent
if they (a) have the same model degrees
of freedom and (b) have a difference
in model chi-squares equal to or less
than a tolerance (controlled by the
argument tolerance).
If two models are mathematically equivalent, then they must be empirically equivalent.
However, even if two models are not mathematically equivalent, they may still be empirically equivalent for a sample.
How to Generate the List of Models to Check
Usually, the alternative models can be generated
automatically by leaving partables
at its default value (NULL). The function
eq_df_models() will be called using
original_model as the original model.
The generation can be customized by setting
the argument eq_df_models_args.
Alternatively, the function eq_df_models()
can be called directly to generate
an initial list of models. This list
can then be filtered by helpers
in partable_select, such as
must_be_y() or must_not_have_paths(),
and use the resulting list as partables.
References
Pesigan, I. J. A., Cheung, S. F., Wu, H., Chang, F., & Leung, S. O. (2026). How plausible is my model? Assessing model plausibility of structural equation models using Bayesian posterior probabilities (BPP). Behavior Research Methods, 58(3), 73. doi:10.3758/s13428-025-02921-x
See also
modelbpp::fit_many() for
the function used to fit the models.
Examples
library(lavaan)
# For illustration, only a few models are generated below,
# using drop_k() and add_k manually.
# These two functions are usually not used directly.
# Model 1
mod1 <-
"
fx =~ x1 + x2 + x3
fm =~ m1 + m2 + m3
fy =~ y1 + y2 + y3
fm ~ fx
fy ~ fm + fx
"
fit1 <- sem(
model = mod1,
data = data_test_3_factor_3_item
)
fit1_1_more <- drop_k(fit1)
fit1_1_more_1_less <- lapply(
fit1_1_more,
add_k
)
# Model 3
mod3 <-
"
fx =~ x1 + x2 + x3
fm =~ m1 + m2 + m3
fy =~ y1 + y2 + y3
fm ~ fx
fy ~ fm
"
fit3 <- sem(
model = mod3,
data = data_test_3_factor_3_item
)
fit3_1_more <- drop_k(fit3)
fit3_1_more_1_less <- lapply(
fit3_1_more,
add_k
)
# All equivalent
partables1 <- combine_partables(fit1_1_more_1_less)
# Some equivalent
partables3 <- combine_partables(fit3_1_more_1_less)
eq_out_1 <- eq_models(
partables1,
original_model = fit1,
parallel = FALSE
)
eq_out_3 <- eq_models(
partables3,
original_model = fit3,
parallel = FALSE
)
# The usual way to use eq_models:
# 'parallel' should be set to TRUE or omitted
# eq_out_all <- eq_models(
# original_model = fit1
# )
# eq_out_all
# Using is_eq()
is_eq(
partables1,
original_model = fit1,
parallel = FALSE
)
#> drop: fm~fx.add: fx~~fm drop: fm~fx.add: fx~fm drop: fy~fm.add: fm~~fy
#> TRUE TRUE TRUE
#> drop: fy~fm.add: fm~fy
#> TRUE
is_eq(
partables3,
original_model = fit3,
parallel = FALSE
)
#> drop: fm~fx.add: fx~~fm drop: fm~fx.add: fx~~fy drop: fy~fm.add: fx~~fy
#> TRUE FALSE FALSE
#> drop: fy~fm.add: fm~~fy
#> FALSE