View source: R/esem.from.mods.R
| esem.from.mods | R Documentation |
esem.from.keys runs exploratory structural equation models (ESEM) in lavaan
where the exploratory factor analysis (EFA) factors predict confirmatory
factor analysis (CFA) factors and/or bifactor factors in separate models
for each CFA or bifactor model.
The function takes a fitted lavaan object from an EFA and lists of fitted
CFA and/or bifactor lavaan model objects as inputs so will typically
use outputs from efa.from.keys(), and cfa.from.keys() or
bifactor.from.keys().
esem.from.mods(
efa_fit,
cfa_fit = NULL,
bif_fit = NULL,
data,
fit_save = FALSE,
fit_measures = "all",
miss = "ML",
est = "default",
name = "esem",
check = FALSE,
save_out = FALSE
)
efa_fit |
A fitted lavaan object of an EFA model. |
cfa_fit |
A named list of fitted lavaan objects of CFA models.
Can be |
bif_fit |
A named list of fitted lavaan objects of bifactor models.
Can be |
data |
A dataframe or object coercible to a dataframe. Data must include all observed variables used in any of the models. |
fit_save |
Logical.
|
fit_measures |
A vector of fit measures to save or 'all' to select all fit measures,
as per the |
miss |
A string.
Sets the |
est |
A string.
Sets the |
name |
A string indicating a subdirectory where model outputs will be saved when
|
check |
Logical.
|
save_out |
Logical.
|
The function was designed to streamline running exploratory structural equation models (ESEM) where EFA factors predict a series of latent variables in separate models using Burt's (1976) 2-stage procedure to prevent interpretational confounding. The function is designed to run analyses equivalent to that of Bainbridge, Ludeke, and Smillie (2022).
The function requires fitted lavaan objects as inputs in order to properly
employ the 2-stage procedure.
Using efa.from.keys(), cfa.from.keys(), and/or bifactor.from.keys()
should make this relatively straight-forward.
Matching the philosophy of the package, the function is designed to run for multiple models with a similar design. If you are using the function for a single model, transform inputs into lists as appropriate.
The model relies on sem.check() for the back-end of running the models.
This enables saving inputs and outputs from model runs
(with save_out = TRUE) and checking to see if anything has changed from
prior runs before running again (with check = TRUE).
The functionality was included for a number of very slow models or a lot of
faster models, such that time spent rerunning them would be onerous.
For further details on how this works, see the sem.check() function
documentation.
Although the function will take any lavaan models that have successfully
produced standard lavaan outputs,
it will not complain if these have poor fit or other undesirable
characteristics (beyond warnings and errors produced by lavaan).
If this matters to you, it would be worth checking the outputs of upstream
functions prior to running esem.from.mods().
The 2-stage procedure employed mitigates some of the problems of poor fitting
measurement models but, depending on your purpose and research
question(s), it could nevertheless be important to update models to ensure
good fit prior to running this function. There is currently no capability
within semFromKeys to add modifications to CFA or bifactor models
(beyond removing items by removing them from the keys).
For bifactor models predicted by ESEM factors, a complication is that fixing orthogonal relationships between general and group factors is not possible if any of the factors are regressed on any others. This is because, in SEM, fixing correlations with a factor that is an outcome fixes correlations with the residual, which is, of course, not the requirement of a bifactor model.
There are three solutions to this problem.
First, avoid using bifactor models.
This may be possible sometimes, but it frequently is not.
Second, avoid using regressions in models with bifactor models and compute
regressions based on latent variable correlations.
(This can be done by, e.g., creating a correlation matrix from the factor
correlations and using the psych::setCor() function).
This method produces accurate point estimates in the regressions,
but standard errors are biased as the method cannot account for uncertainty
in the correlations.
This is an adequate solution if p-values and confidence intervals are not
required.
Finally, if the 2-stage procedure is employed, then there is little room for
measurement models to change to allow factor correlations to change.
Therefore, the parameter can be relaxed and implied correlations between the
group and general factors ought to remain close to zero.
This is the method employed by esem.from.mods().
Returns a list of length 4 (if fit_save = FALSE) or
5 (if fit_save = TRUE).
The elements of the list are: a list of lavaan model output objects;
a list of parameter estimates from the models (standardized if std = TRUE);
if fit_save = TRUE, a matrix of fit measures for each model;
a list of regression beta parameters from each model;
and a dataframe of R-squared values from each model.
Bainbridge, T. F., Ludeke, S. G., & Smillie, L. D. (2022). Evaluating the Big Five as an organizing framework for commonly used psychological trait scales. Journal of Personality and Social Psychology, 122(4), 749-777. https://doi.org/10.1037/pspp0000395.
Burt, R. S. (1976). Interpretational confounding of unobserved variables in Structural Equation Models. Sociological Methods & Research, 5(1), 3-52. https://doi.org/10.1177/004912417600500101.
Eid, M., Geiser, C., Koch, T., & Heene, M. (2017). Anomalous results in G-factor models: Explanations and alternatives. Psychological Methods, 22(3), 541-562. https://doi.org/10.1037/met0000083.
sem.check(), which this function uses for all the back-end;
cfa.from.keys(), efa.from.keys(), and bifactor.from.keys(),
which are useful functions for creating inputs into esem.from.mods(); and
lavaan::sem(), which is used to estimate the models.
# Create CFA keys
keys0 <- c("grit_c", "grit_p", "hope_a", "hope_p")
keys <- sapply(
keys0, function(x) names(BFIGritHope)[grep(x, names(BFIGritHope))]
)
# Create bifactor keys
keys_g0 <- c("grit", "hope")
keys_g <- sapply(
keys_g0, function(x) names(BFIGritHope)[grep(x, names(BFIGritHope))]
)
keys_b1 <- sapply(
keys_g0, function(x) keys0[grep(x, keys0)], simplify = FALSE
)
# Avoid fit problems with an S-1 model (Eid et al., 2017)
keys_b <- keys_b1
keys_b$hope <- keys_b1$hope[-1]
# Create EFA keys
# Using only 3 factors and fewer items to save time for a simple example
# (This results in a less than ideal solution but it doesn't matter for an
# example)
keys_e0 <- paste0("bfi_", c("e", "a", "c"))
keys_e <- sapply(
keys_e0,
function(x) {
names(BFIGritHope)[grep(paste0(x, "\\d_[1-2]"), names(BFIGritHope))]
},
simplify = FALSE
)
# Create fitted objects to use as inputs
cfa_fit <- cfa.from.keys(keys, BFIGritHope, fit_save = FALSE)
efa_fit <- efa.from.keys(keys_e, BFIGritHope, fit_save = FALSE)
bif_fit <- bifactor.from.keys(
keys_g, keys_b, keys, BFIGritHope, fit_save = FALSE
)
# Run models
esem_fit <- esem.from.mods(
efa_fit$fit$efa, cfa_fit$fit, bif_fit$fit, data = BFIGritHope,
fit_save = FALSE, check = FALSE
)
# Examine results
summary(esem_fit$fit$grit_c) # Standard lavaan summary
esem_fit$r2 # R-squareds
esem_fit$b # Betas
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.