| esem | R Documentation |
Fits ESEM using lavaan's native efa() block. For continuous
data (default), estimation and rotation are integrated in lavaan's ML
optimiser—the same single-step approach as Mplus (*1) syntax. For
ordered indicators, supply ordered and the call is routed to
esem_ordered (set-ESEM / WLSMV; not identical to continuous
esem()).
esem(
data,
nfactors,
indicators = NULL,
rotation = "geomin",
target = NULL,
estimator = "MLR",
std.lv = TRUE,
ordered = NULL,
group = NULL,
group_equal = NULL,
missing = "listwise",
factor_names = NULL,
rotation_args = list(),
heywood_fix = TRUE,
...
)
data |
A |
nfactors |
Integer. Number of latent factors. |
indicators |
Character vector of item names to include. If |
rotation |
Character. Rotation criterion. Passed to
The full list of lavaan-supported rotations is in
|
target |
A numeric matrix (items x factors) for target rotation.
Create with |
estimator |
Character. lavaan estimator. Default |
std.lv |
Logical. Fix factor variances to 1 for identification?
Default |
ordered |
Character vector of ordinal item names.
When non- |
group |
Character. Name of a grouping variable in |
group_equal |
Character vector of lavaan parameter labels to constrain
equal across groups, e.g. |
missing |
Character. Missing data handling for continuous fits.
Default |
factor_names |
Optional character vector of length |
rotation_args |
Named list of extra arguments passed to the rotation
function (e.g. |
heywood_fix |
Logical. Retry rotation with Cholesky unrotation if a
standardised loading exceeds 1 (single-group continuous fits only).
Default |
... |
Additional arguments passed to |
| Mplus syntax | bifactory equivalent |
F1-F3 BY y1-y15 (*1); | esem(data, nfactors = 3) |
(*1) with geomin (default) | rotation = "geomin" |
(*1) with target | rotation = "target", target = tgt |
GROUPING = g; | group = "g" |
| Metric invariance | group_equal = "loadings" |
| Scalar invariance | group_equal = c("loadings", "intercepts") |
Adding cross-loadings stepwise from modification indices is a different (exploratory CFA) approach and is not recommended: it capitalises on chance, inflates Type I error, and produces a different model on every dataset. ESEM instead estimates all cross-loadings simultaneously, with rotation acting as a mathematical penalty for complexity – giving a reproducible, theory-neutral solution.
An object of class "esem_fit" containing:
lavaan_fitThe lavaan fit object for continuous ESEM.
For ordered / custom WLSMV paths see esem_ordered and
The lavaan_fit slot on custom WLSMV fits.
syntaxThe lavaan model string that was estimated.
nfactorsNumber of factors.
rotationRotation method used.
factor_namesFactor names.
indicatorsItem names included in the model.
callThe matched call.
Many R implementations run EFA first, extract the loading matrix, then paste
it into a CFA as starting values. That is an approximation. bifactory
instead uses lavaan's efa() block syntax (available since
lavaan 0.6-12), which estimates the rotation and the SEM parameters
simultaneously – exactly as Mplus does with the (*1) syntax.
esem and besem use lavaan::cfa() with a
native efa() block (integrated MLR estimation and rotation).
esem(ordered = ...) calls esem_ordered. Default
method = "lavaan" (lavaan WLSMV, efa() block, post-hoc rotation).
method = "rotation" uses a custom DWLS pipeline (polychoric correlations
+ GPArotation).
besem(ordered = ...) calls besem_ordered. Default
method = "rotation" (custom DWLS/WLSMV + orthogonal targetT; this
is what run_comparison uses for ordered data). method = "set-esem"
fits a lavaan WLSMV bifactor CFA with non-primary specific loadings fixed at
zero; it does not match Mplus B-ESEM loadings.
esem_invariance uses lavaan multi-group efa() models plus
explicit syntax patches for ordered B-ESEM. See that help page for scope limits.
Defaults differ by entry point; pass missing explicitly when fitting ESEM and
B-ESEM separately on the same ordered dataset.
specify_model / run_comparison: "pairwise"
for ordered data, "listwise" for continuous.
esem_ordered: "pairwise".
besem_ordered: "listwise" (pipeline still passes
missing from the spec when used via run_comparison).
esem / besem (continuous): "listwise".
When heywood_fix = TRUE (default on single-group esem and
esem_ordered), std_loadings may reflect a post-hoc
rotation correction while lavaan_fit still holds the pre-correction lavaan
solution. Prefer std_loadings(x) for reported loadings in that case.
make_target for target matrices,
esem_ordered for ordinal data,
esem_compare for ESEM vs CFA comparison,
std_loadings for the standardised loading matrix.
data("HolzingerSwineford1939", package = "lavaan")
d <- HolzingerSwineford1939[, paste0("x", 1:9)]
# Basic ESEM: 3 factors, geomin rotation (Mplus default)
fit <- esem(d, nfactors = 3)
round(std_loadings(fit), 2)
lavaan::fitMeasures(lavaan_fit(fit), c("cfi", "tli", "rmsea", "srmr"))
# Named factors
fit2 <- esem(d, nfactors = 3,
factor_names = c("Visual", "Textual", "Speed"))
# Target rotation
tgt <- make_target(list(Vis = 1:3, Txt = 4:6, Spd = 7:9), nitems = 9)
fit3 <- esem(d, nfactors = 3, rotation = "target", target = tgt)
# Multi-group configural ESEM
fit_mg <- esem(HolzingerSwineford1939, nfactors = 3,
indicators = paste0("x", 1:9), group = "sex")
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.