Title: | Helper Functions for Structural Equation Modeling |
---|---|
Description: | An assortment of helper functions for doing structural equation modeling, mainly by 'lavaan' for now. Most of them are time-saving functions for common tasks in doing structural equation modeling and reading the output. This package is not for functions that implement advanced statistical procedures. It is a light-weight package for simple functions that do simple tasks conveniently, with as few dependencies as possible. |
Authors: | Shu Fai Cheung [aut, cre] |
Maintainer: | Shu Fai Cheung <[email protected]> |
License: | GPL (>= 3) |
Version: | 0.1.12 |
Built: | 2025-01-31 05:25:05 UTC |
Source: | https://github.com/sfcheung/semhelpinghands |
It generates the
'lavaan' model syntax for exogenous
variables in a lavaan
model.
add_exo_cov(model, FUN = "sem", print = TRUE) auto_exo_cov(model, FUN = "sem", print = TRUE)
add_exo_cov(model, FUN = "sem", print = TRUE) auto_exo_cov(model, FUN = "sem", print = TRUE)
model |
The model syntax to which the covariances are to be added. |
FUN |
Name (as string) of the
|
print |
Logical. Whether the
generated syntax should also be
printed by |
The function lavaan::sem()
usually will set covariances between
"exogenous" variables free when
fixed.x = FALSE
("exogenous" is
defined here as variables that appear
on the right hand side but not on the
left hand side of the ~
operator').
However, if a covariance between the
residual term of an endogenous
variable and an exogenous variable is
manually set to free, lavaan::sem()
may not set the aforementioned
covariances free. Users will need to
free them manually, and there may be
a lot of them in some models.
This function gets a model syntax and generates the syntax for these covariances. Users can then inspect it, modify it if necessary, and then copy and paste it to the model syntax.
add_exo_cov()
returns a one-element
character vector of the syntax, with
lines separated by "\n". The
generated syntax is appended to the
input model syntax.
auto_exo_cov()
returns a
one-element character vector of the
generated syntax, with lines
separated by "\n".
add_exo_cov()
: Add covariances
between exogenous variables to the
model syntax and than return the
modified model syntax.
auto_exo_cov()
: Generate the
model syntax for the covariances
between exogenous variables.
Shu Fai Cheung https://orcid.org/0000-0002-9871-9448
library(lavaan) set.seed(8976223) n <- 100 x <- rnorm(n) m <- .5 * x + rnorm(n, 0, sqrt(.4)) z <- rnorm(n) y <- .4 * m + .3 * z * m + rnorm(n, 0, .5) dat <- data.frame(x, m, z, y) dat$zm <- dat$z * dat$m mod0 <- " m ~ x y ~ m + z + zm m ~~ z + zm " fit <- sem(mod0, dat, fixed.x = FALSE) # Add covariances. Also printed by default. mod0_cov <- add_exo_cov(mod0) # Fit the model fit_cov <- sem(mod0_cov, dat, fixed.x = FALSE) # Manually adding the covariances mod1 <- " m ~ x y ~ m + z + zm m ~~ z + zm z ~~ zm + x zm ~~ x " fit1 <- sem(mod1, dat, meanstructure = TRUE, fixed.x = FALSE) # Compare the results # No manual covariances fit # Automatically generated covariances fit_cov # Manually added covariances fit1
library(lavaan) set.seed(8976223) n <- 100 x <- rnorm(n) m <- .5 * x + rnorm(n, 0, sqrt(.4)) z <- rnorm(n) y <- .4 * m + .3 * z * m + rnorm(n, 0, .5) dat <- data.frame(x, m, z, y) dat$zm <- dat$z * dat$m mod0 <- " m ~ x y ~ m + z + zm m ~~ z + zm " fit <- sem(mod0, dat, fixed.x = FALSE) # Add covariances. Also printed by default. mod0_cov <- add_exo_cov(mod0) # Fit the model fit_cov <- sem(mod0_cov, dat, fixed.x = FALSE) # Manually adding the covariances mod1 <- " m ~ x y ~ m + z + zm m ~~ z + zm z ~~ zm + x zm ~~ x " fit1 <- sem(mod1, dat, meanstructure = TRUE, fixed.x = FALSE) # Compare the results # No manual covariances fit # Automatically generated covariances fit_cov # Manually added covariances fit1
It inserts columns to denote whether a parameter is significant.
add_sig(object, ..., standardized = FALSE, na_str = "", use = "pvalue")
add_sig(object, ..., standardized = FALSE, na_str = "", use = "pvalue")
object |
A 'lavaan'-class object
or the output of
|
... |
Optional arguments to be
passed to
|
standardized |
Whether
standardized solution is needed. If
|
na_str |
The string to be used
for parameters with no significant
tests. For example, fixed parameters.
Default is |
use |
A character vector of one
or more strings. If |
The function calls
lavaan::parameterEstimates()
or
lavaan::standardizedSolution()
and
checks the columns pvalue
,
ci.lower
and ci.upper
, and/or
boot.ci.lower
and boot.ci.upper
and then inserts columns to denote
for each parameter estimate whether
it is significant based on the
requested criteria.
The output of
lavaan::parameterEstimates()
or
lavaan::standardizedSolution()
,
with one or two columns inserted
after the parameter estimates to
denote the significant test results.
Shu Fai Cheung https://orcid.org/0000-0002-9871-9448
lavaan::parameterEstimates()
and
lavaan::standardizedSolution()
library(lavaan) set.seed(5478374) n <- 50 x <- runif(n) - .5 m <- .40 * x + rnorm(n, 0, sqrt(1 - .40)) y <- .30 * m + rnorm(n, 0, sqrt(1 - .30)) dat <- data.frame(x = x, y = y, m = m) model <- ' m ~ a*x y ~ b*m ab := a*b ' fit <- sem(model, data = dat, fixed.x = FALSE) # Add "*" based on 'pvalue' add_sig(fit) # Add "*" for standardized solution add_sig(fit, standardized = TRUE) # Add "*" based on confidence interval add_sig(fit, use = "ci") # Add "*" for standardized solution based on confidence interval add_sig(fit, standardized = TRUE, use = "ci") # Add "*" for standardized solution based on confidence interval # and 'pvalue'. add_sig(fit, standardized = TRUE, use = c("ci", "pvalue")) # Can also accept a parameter estimates table est <- parameterEstimates(fit) add_sig(est) # So it can be used with some other functions in semhelpinghands add_sig(filter_by(est, op = "~")) # Piping can also be used est |> filter_by(op = "~") |> add_sig()
library(lavaan) set.seed(5478374) n <- 50 x <- runif(n) - .5 m <- .40 * x + rnorm(n, 0, sqrt(1 - .40)) y <- .30 * m + rnorm(n, 0, sqrt(1 - .30)) dat <- data.frame(x = x, y = y, m = m) model <- ' m ~ a*x y ~ b*m ab := a*b ' fit <- sem(model, data = dat, fixed.x = FALSE) # Add "*" based on 'pvalue' add_sig(fit) # Add "*" for standardized solution add_sig(fit, standardized = TRUE) # Add "*" based on confidence interval add_sig(fit, use = "ci") # Add "*" for standardized solution based on confidence interval add_sig(fit, standardized = TRUE, use = "ci") # Add "*" for standardized solution based on confidence interval # and 'pvalue'. add_sig(fit, standardized = TRUE, use = c("ci", "pvalue")) # Can also accept a parameter estimates table est <- parameterEstimates(fit) add_sig(est) # So it can be used with some other functions in semhelpinghands add_sig(filter_by(est, op = "~")) # Piping can also be used est |> filter_by(op = "~") |> add_sig()
Label the elements of the model matrices in a lavaan model.
annotate_matrices(fit) ## S3 method for class 'annotate_matrices' print(x, ...)
annotate_matrices(fit) ## S3 method for class 'annotate_matrices' print(x, ...)
fit |
The output of
|
x |
A 'annotate_matrices'-class
object. The output of
|
... |
Optional arguments. To be passed to the default print method. |
This function annotates the model matrices in a 'lavaan'-class object. This function is not to be used in analysis. It is a learning tool, for learners to understand the relation between the model matrices and the model parameters.
It currently supports a single-level single-group model only.
annotate_matrices()
returns an
annotate_matrices
-class object,
which is a list of model matrices,
with elements annotated:
If a parameter is free, then it is
represented by "lhs-op-rhs"
according to the parameter estimate
data frame.
If a parameter is fixed but appears
in the parameter table, it is
represented by "(lhs-op-rhs = x)"
, x the value it is fixed to.
If a parameter is fixed to zero but not in the parameter table, then it is represented by 0.
The print-method return the input,
x
. It was called for its
side-effect.
print(annotate_matrices)
: The
print method of the output of
annotate_matrices()
Shu Fai Cheung https://orcid.org/0000-0002-9871-9448
# Adapted from https://lavaan.ugent.be/tutorial/cfa.html library(lavaan) HS.model <- ' visual =~ x1 + x2 + x3 textual =~ x4 + x5 + x6 speed =~ x7 + x8 + x9 ' fit_cfa <- cfa(HS.model, data = HolzingerSwineford1939) annotate_matrices(fit_cfa)
# Adapted from https://lavaan.ugent.be/tutorial/cfa.html library(lavaan) HS.model <- ' visual =~ x1 + x2 + x3 textual =~ x4 + x5 + x6 speed =~ x7 + x8 + x9 ' fit_cfa <- cfa(HS.model, data = HolzingerSwineford1939) annotate_matrices(fit_cfa)
Refit a model in 'lavaan' by several lavaan-supported estimators
compare_estimators(object, estimators = NULL) se_ratios(fit_list, reference = NULL)
compare_estimators(object, estimators = NULL) se_ratios(fit_list, reference = NULL)
object |
A 'lavaan'-class object. |
estimators |
A character vector
of the estimator supported by the
|
fit_list |
The output
of |
reference |
The name
of the reference method
(ratios will be equal to one).
Must be one of the estimator
used on |
The function simply uses
lapply()
and update()
to rerun
the analysis once for each of the
estimator using update(object, estimator = "x"
, x
being the
estimator.
The results can then be compared
using group_by_models()
.
A list of lavaan
outputs,
each of them is an update of the
original output using one of the
estimators.
compare_estimators()
: Refit the model with different estimators.
se_ratios()
: A wrapper of group_by_models()
that
computes the ratios of standard errors of different methods
to those of one method.
Shu Fai Cheung https://orcid.org/0000-0002-9871-9448.
library(lavaan) set.seed(5478374) n <- 50 x <- runif(n) - .5 m <- .40 * x + rnorm(n, 0, sqrt(1 - .40)) y <- .30 * m + rnorm(n, 0, sqrt(1 - .30)) dat <- data.frame(x = x, y = y, m = m) model <- ' m ~ a*x y ~ b*m ab := a*b ' fit <- sem(model, data = dat, fixed.x = FALSE) # Refit the model by three different estimators fit_more <- compare_estimators(fit, estimator = c("GLS", "MLR", "ML")) # Use group_by_models to compare the estimates group_by_models(fit_more, col_names = c("est", "pvalue")) # Use se_ratios to compare standard errors se_ratios(fit_more, reference = "ML")
library(lavaan) set.seed(5478374) n <- 50 x <- runif(n) - .5 m <- .40 * x + rnorm(n, 0, sqrt(1 - .40)) y <- .30 * m + rnorm(n, 0, sqrt(1 - .30)) dat <- data.frame(x = x, y = y, m = m) model <- ' m ~ a*x y ~ b*m ab := a*b ' fit <- sem(model, data = dat, fixed.x = FALSE) # Refit the model by three different estimators fit_more <- compare_estimators(fit, estimator = c("GLS", "MLR", "ML")) # Use group_by_models to compare the estimates group_by_models(fit_more, col_names = c("est", "pvalue")) # Use se_ratios to compare standard errors se_ratios(fit_more, reference = "ML")
A path model with three predictors and three outcomes, for illustration.
dvs_ivs
dvs_ivs
A data frame with 100 rows and 7 variables:
Outcome variable 1. Numeric.
Outcome variable 2. Numeric.
Outcome variable 3. Numeric.
Predictor 1. Numeric.
Predictor 2. Numeric.
Predictor 3. Numeric.
Group variable: "gp1" or "gp2". String.
data(dvs_ivs) library(lavaan) mod <- " y1 ~ x1 + x2 + x3 y2 ~ x1 + x3 y3 ~ y2 + x2 " fit <- sem(mod, dvs_ivs) parameterEstimates(fit) fit_gp <- sem(mod, dvs_ivs, group = "gp") parameterEstimates(fit_gp)
data(dvs_ivs) library(lavaan) mod <- " y1 ~ x1 + x2 + x3 y2 ~ x1 + x3 y3 ~ y2 + x2 " fit <- sem(mod, dvs_ivs) parameterEstimates(fit) fit_gp <- sem(mod, dvs_ivs, group = "gp") parameterEstimates(fit_gp)
Filter parameter
estimates table and similar tables
inlavaan
by common fields such as
op
(operator).
filter_by(object, op = NULL, lhs = NULL, rhs = NULL, group = NULL, fit = NULL)
filter_by(object, op = NULL, lhs = NULL, rhs = NULL, group = NULL, fit = NULL)
object |
The output of
|
op |
A character vector of the
operators ( |
lhs |
A character vector of
names in the |
rhs |
A character vector of
names in the |
group |
A vector of either the
group numbers in the |
fit |
The original fit object.
Usd when |
This functions accepts the
output of
lavaan::parameterEstimates()
and
lavaan::standardizedSolution()
and
filter the rows by commonly used
field.
The filtered version of the input object.
Shu Fai Cheung https://orcid.org/0000-0002-9871-9448
library(lavaan) set.seed(5478374) n <- 50 x <- runif(n) - .5 m <- .40 * x + rnorm(n, 0, sqrt(1 - .40)) y <- .30 * m + rnorm(n, 0, sqrt(1 - .30)) dat <- data.frame(x = x, y = y, m = m) model <- ' m ~ a*x y ~ b*m ab := a*b ' fit <- sem(model, data = dat, fixed.x = FALSE) model_gp <- ' m ~ c(a1, a2)*x y ~ c(b1, b2)*m a1b1 := a1*b1 a2b2 := a2*b2 ' dat$gp <- sample(c("gp1", "gp2"), n, replace = TRUE) fit_gp <- sem(model_gp, dat, group = "gp", warn = FALSE) est <- parameterEstimates(fit) est_gp <- parameterEstimates(fit_gp) filter_by(est, op = "~") filter_by(est, op = "~", lhs = "y") filter_by(est, rhs = c("m", "x"), op = "~") filter_by(est_gp, group = 2) # If the fit object is supplied, can filter # by group label filter_by(est_gp, group = "gp2", fit = fit_gp) filter_by(est_gp, group = "gp2", fit = fit_gp, op = "~") # Select user-defined parameters filter_by(est_gp, op = ":=") # Can be used with some other functions in semhelpinghands # Piping can also be used est_gp |> filter_by(op = "~", group = "gp2", fit = fit_gp) |> add_sig()
library(lavaan) set.seed(5478374) n <- 50 x <- runif(n) - .5 m <- .40 * x + rnorm(n, 0, sqrt(1 - .40)) y <- .30 * m + rnorm(n, 0, sqrt(1 - .30)) dat <- data.frame(x = x, y = y, m = m) model <- ' m ~ a*x y ~ b*m ab := a*b ' fit <- sem(model, data = dat, fixed.x = FALSE) model_gp <- ' m ~ c(a1, a2)*x y ~ c(b1, b2)*m a1b1 := a1*b1 a2b2 := a2*b2 ' dat$gp <- sample(c("gp1", "gp2"), n, replace = TRUE) fit_gp <- sem(model_gp, dat, group = "gp", warn = FALSE) est <- parameterEstimates(fit) est_gp <- parameterEstimates(fit_gp) filter_by(est, op = "~") filter_by(est, op = "~", lhs = "y") filter_by(est, rhs = c("m", "x"), op = "~") filter_by(est_gp, group = 2) # If the fit object is supplied, can filter # by group label filter_by(est_gp, group = "gp2", fit = fit_gp) filter_by(est_gp, group = "gp2", fit = fit_gp, op = "~") # Select user-defined parameters filter_by(est_gp, op = ":=") # Can be used with some other functions in semhelpinghands # Piping can also be used est_gp |> filter_by(op = "~", group = "gp2", fit = fit_gp) |> add_sig()
Groups fit measures into a table with models as columns.
fitMeasures_by_models(object_list, ...)
fitMeasures_by_models(object_list, ...)
object_list |
A named list of 'lavaan'-class objects. |
... |
Optional arguments to be
passed to
|
It call lavaan::fitMeasures()
to
compute for each model the fit
measures supported by lavaan
, and
combine them into a data frame. Users
can then use the print method
(print.fit_by_models()
) to customize
the printout.
To be consist with full lavaan
output, the names used in
lavaan::fitMeasures()
are used.
This function is intended for
a simple and compact table of
fit measures for quick preview.
For a well-organized
layout, call lavaan::fitMeasures()
and set output
to "text"
.
A data-frame-like object of
the class fit_by_models
, which
has a print
method (see
print.fit_by_models()
).
Shu Fai Cheung https://orcid.org/0000-0002-9871-9448.
library(lavaan) set.seed(5478374) n <- 50 x <- runif(n) - .5 m <- .40 * x + rnorm(n, 0, sqrt(1 - .40)) y <- .30 * m + rnorm(n, 0, sqrt(1 - .30)) dat <- data.frame(x = x, y = y, m = m) model1 <- ' m ~ a*x y ~ b*m ab := a*b ' fit1 <- sem(model1, data = dat, fixed.x = FALSE) model2 <- ' m ~ a*x y ~ b*m + x ab := a*b ' fit2 <- sem(model2, data = dat, fixed.x = FALSE) fitMeasures_by_models(list(no_direct = fit1, direct = fit2))
library(lavaan) set.seed(5478374) n <- 50 x <- runif(n) - .5 m <- .40 * x + rnorm(n, 0, sqrt(1 - .40)) y <- .30 * m + rnorm(n, 0, sqrt(1 - .30)) dat <- data.frame(x = x, y = y, m = m) model1 <- ' m ~ a*x y ~ b*m ab := a*b ' fit1 <- sem(model1, data = dat, fixed.x = FALSE) model2 <- ' m ~ a*x y ~ b*m + x ab := a*b ' fit2 <- sem(model2, data = dat, fixed.x = FALSE) fitMeasures_by_models(list(no_direct = fit1, direct = fit2))
Groups parameter estimates or other information such as p-values into a table with groups as columns and parameters as rows.
group_by_groups( object, ..., col_names = "est", group_first = TRUE, group_labels = NULL, fit = NULL, use_standardizedSolution = FALSE )
group_by_groups( object, ..., col_names = "est", group_first = TRUE, group_labels = NULL, fit = NULL, use_standardizedSolution = FALSE )
object |
A 'lavaan'-class object
or the output of
|
... |
Optional arguments to be
passed to
|
col_names |
A vector of the
column names in the parameter
estimate tables to be included.
Default is |
group_first |
If |
group_labels |
A character
vector of group labels. Will be
assigned to group id = 1, 2, 3, etc.
If not provided. will try to be
retrieved from |
fit |
Optional. A
lavaan::lavaan object.
If |
use_standardizedSolution |
If |
A data-frame-like object of
the class est_table
.
Shu Fai Cheung https://orcid.org/0000-0002-9871-9448
library(lavaan) set.seed(5478374) n <- 100 x <- runif(n) - .5 m <- .40 * x + rnorm(n, 0, sqrt(1 - .40)) y <- .30 * m + rnorm(n, 0, sqrt(1 - .30)) city <- sample(c("City Alpha", "City Beta"), 100, replace = TRUE) dat <- data.frame(x = x, y = y, m = m, city = city) model <- ' m ~ c(a1, a2)*x y ~ c(b1, b2)*m a1b1 := a1*b1 a2b2 := a2*b2 ' fit <- sem(model, data = dat, fixed.x = FALSE, group = "city") (est <- parameterEstimates(fit)) # Group them by groups group_by_groups(fit) # Can also work on a parameter estimates table # To have group labels, need to supply the fit object group_by_groups(est, fit = fit) # Can be used with some other functions in semhelpinghands # when used on a parameter estimates table group_by_groups(filter_by(est, op = "~"), fit = fit) # Also support piping est |> filter_by(op = "~") |> group_by_groups(fit = fit)
library(lavaan) set.seed(5478374) n <- 100 x <- runif(n) - .5 m <- .40 * x + rnorm(n, 0, sqrt(1 - .40)) y <- .30 * m + rnorm(n, 0, sqrt(1 - .30)) city <- sample(c("City Alpha", "City Beta"), 100, replace = TRUE) dat <- data.frame(x = x, y = y, m = m, city = city) model <- ' m ~ c(a1, a2)*x y ~ c(b1, b2)*m a1b1 := a1*b1 a2b2 := a2*b2 ' fit <- sem(model, data = dat, fixed.x = FALSE, group = "city") (est <- parameterEstimates(fit)) # Group them by groups group_by_groups(fit) # Can also work on a parameter estimates table # To have group labels, need to supply the fit object group_by_groups(est, fit = fit) # Can be used with some other functions in semhelpinghands # when used on a parameter estimates table group_by_groups(filter_by(est, op = "~"), fit = fit) # Also support piping est |> filter_by(op = "~") |> group_by_groups(fit = fit)
Groups parameter estimates or other information such as p-values into a table with models as columns.
group_by_models( object_list, ..., col_names = "est", group_first = FALSE, model_first = TRUE, use_standardizedSolution = FALSE )
group_by_models( object_list, ..., col_names = "est", group_first = FALSE, model_first = TRUE, use_standardizedSolution = FALSE )
object_list |
A named list of
'lavaan'-class objects, a named list
of the output of
|
... |
Optional arguments to be
passed to
|
col_names |
A vector of the
column names in the parameter
estimate tables to be included.
Default is |
group_first |
If |
model_first |
If |
use_standardizedSolution |
If |
A data-frame-like object of
the class est_table
.
Shu Fai Cheung
https://orcid.org/0000-0002-9871-9448
Inspired by the proposal Rönkkö posted in a GitHub
https://github.com/simsem/semTools/issues/24#issue-235172313
for semTools
. I want something
simple for a quick overview and so
I wrote this function.
library(lavaan) set.seed(5478374) n <- 50 x <- runif(n) - .5 m <- .40 * x + rnorm(n, 0, sqrt(1 - .40)) y <- .30 * m + rnorm(n, 0, sqrt(1 - .30)) dat <- data.frame(x = x, y = y, m = m) model1 <- ' m ~ a*x y ~ b*m ab := a*b ' fit1 <- sem(model1, data = dat, fixed.x = FALSE) model2 <- ' m ~ a*x y ~ b*m + x ab := a*b ' fit2 <- sem(model2, data = dat, fixed.x = FALSE) parameterEstimates(fit1) parameterEstimates(fit2) group_by_models(list(no_direct = fit1, direct = fit2), col_names = c("est", "pvalue")) # Can also be used with some other functions in # semhelpinghands group_by_models(list(no_direct = fit1, direct = fit2), col_names = c("est", "pvalue")) |> filter_by(op = "~")
library(lavaan) set.seed(5478374) n <- 50 x <- runif(n) - .5 m <- .40 * x + rnorm(n, 0, sqrt(1 - .40)) y <- .30 * m + rnorm(n, 0, sqrt(1 - .30)) dat <- data.frame(x = x, y = y, m = m) model1 <- ' m ~ a*x y ~ b*m ab := a*b ' fit1 <- sem(model1, data = dat, fixed.x = FALSE) model2 <- ' m ~ a*x y ~ b*m + x ab := a*b ' fit2 <- sem(model2, data = dat, fixed.x = FALSE) parameterEstimates(fit1) parameterEstimates(fit2) group_by_models(list(no_direct = fit1, direct = fit2), col_names = c("est", "pvalue")) # Can also be used with some other functions in # semhelpinghands group_by_models(list(no_direct = fit1, direct = fit2), col_names = c("est", "pvalue")) |> filter_by(op = "~")
Groups parameter estimates or other information such as p-values into a table with dependent variables as columns and independent variables as rows, or a transpose of this table.
group_by_dvs( object, ..., col_name = "est", add_prefix = TRUE, group_first = FALSE, use_standardizedSolution = FALSE ) group_by_ivs( object, ..., col_name = "est", add_prefix = TRUE, group_first = FALSE, use_standardizedSolution = FALSE )
group_by_dvs( object, ..., col_name = "est", add_prefix = TRUE, group_first = FALSE, use_standardizedSolution = FALSE ) group_by_ivs( object, ..., col_name = "est", add_prefix = TRUE, group_first = FALSE, use_standardizedSolution = FALSE )
object |
A 'lavaan'-class object
or the output of
|
... |
Optional arguments to be
passed to
|
col_name |
The column name of
information to be grouped. Default is
|
add_prefix |
If |
group_first |
If |
use_standardizedSolution |
If |
It gets a 'lavaan'-class
object or the output of
lavaan::parameterEstimates()
or
lavaan::standardizedSolution()
and
group selected columns by "dependent"
variables group_by_dvs()
or by
"independent" variables
group_by_ivs()
.
"Dependent" variables are defined
as variables on the left hand side
of the operator ~
.
"Independent" variables are defined
as variables on the right hand side
of the operator ~
.
Note that a variable can both be a "dependent" variable and an "independent" variable in a model.
A data-frame-like object of
the class est_table
.
Shu Fai Cheung https://orcid.org/0000-0002-9871-9448
library(lavaan) set.seed(5478374) n <- 50 x <- runif(n) - .5 m <- .40 * x + rnorm(n, 0, sqrt(1 - .40)) y <- .30 * m + rnorm(n, 0, sqrt(1 - .30)) dat <- data.frame(x = x, y = y, m = m) model <- ' m ~ a*x y ~ b*m ab := a*b ' fit <- sem(model, data = dat, fixed.x = FALSE) parameterEstimates(fit) # Group by DVs group_by_dvs(fit) # Group by IVs group_by_ivs(fit)
library(lavaan) set.seed(5478374) n <- 50 x <- runif(n) - .5 m <- .40 * x + rnorm(n, 0, sqrt(1 - .40)) y <- .30 * m + rnorm(n, 0, sqrt(1 - .30)) dat <- data.frame(x = x, y = y, m = m) model <- ' m ~ a*x y ~ b*m ab := a*b ' fit <- sem(model, data = dat, fixed.x = FALSE) parameterEstimates(fit) # Group by DVs group_by_dvs(fit) # Group by IVs group_by_ivs(fit)
Plots for examining the
distribution of bootstrap estimates
in a model fitted by lavaan
.
plot_boot( object, param, standardized = NULL, nclass = NULL, hist_color = "lightgrey", hist_linewidth = 1, density_line_type = "solid", density_line_color = "blue", density_line_linewidth = 2, est_line_type = "dotted", est_line_color = "red", est_line_linewidth = 2, qq_dot_size = 2, qq_dot_color = "black", qq_dot_pch = 16, qq_line_linewidth = 2, qq_line_color = "black", qq_line_linetype = "solid" )
plot_boot( object, param, standardized = NULL, nclass = NULL, hist_color = "lightgrey", hist_linewidth = 1, density_line_type = "solid", density_line_color = "blue", density_line_linewidth = 2, est_line_type = "dotted", est_line_color = "red", est_line_linewidth = 2, qq_dot_size = 2, qq_dot_color = "black", qq_dot_pch = 16, qq_line_linewidth = 2, qq_line_color = "black", qq_line_linetype = "solid" )
object |
Either
a lavaan::lavaan
object with bootstrap estimates
stored, or the output of
|
param |
String. The name of
the parameter to be plotted, which
should be the name as appeared in
a call to |
standardized |
Logical. Whether
the estimates from the standardized
solution are to be plotted. Default
is |
nclass |
The number of breaks.
This argument will be passed to
|
hist_color |
String. The color of the
bars in the histogram. It will be
passed to |
hist_linewidth |
The width of the borders of the bars in the histogram. Default is 1. |
density_line_type |
String.
The type of the line of the density
curve in the histogram. It will be
passed to |
density_line_color |
String.
The color of the density curve in
the histogram. It will be
passed to |
density_line_linewidth |
The width
of the density curve in the histogram.
It will be
passed to |
est_line_type |
String. The
type of the vertical line in the
histogram showing the point estimate
of the parameter. It will be
passed to |
est_line_color |
String. The
color of the vertical line showing
the point estimate in the histogram.
It will be
passed to |
est_line_linewidth |
The width
of the vertical line showing the
point estimate in the histogram.
It will be
passed to |
qq_dot_size |
The size of the
points in the normal QQ-plot.
It will be
passed to |
qq_dot_color |
String. The color
of the points in the normal QQ-plot.
It will be
passed to |
qq_dot_pch |
Numeric. The shape
of the points in the normal QQ-plot.
It will be
passed to |
qq_line_linewidth |
The width
of the diagonal line to be drawn in
the normal QQ-plot.
It will be
passed to |
qq_line_color |
String. The color
of the diagonal line to be drawn in
the normal QQ-plot.
It will be
passed to |
qq_line_linetype |
The type of
the diagonal line to be drawn in the
normal QQ-plot. Default is |
Rousselet, Pernet, and Wilcox (2021)
argued that when using bootstrapping,
it is necessary to examine the distribution
of bootstrap estimates. This can be
done when boot::boot()
is used
because it has a plot
method for
its output. This cannot be easily
done in model fitted by lavaan::lavaan()
.
The function plot_boot()
is used for
plotting the distribution of bootstrap
estimates for a model fitted by
lavaan
in a format similar to that
of the output of boot::boot()
, with
a histogram on the left and a normal
QQ-plot on the right.
For free parameters in a model
(unstandardized), it can be called
directly on the output of lavaan
and retrieves the stored estimates.
For estimates of user-defined parameters,
call store_boot_def()
first to compute
and store the bootstrap estimates
first.
For estimates in standardized solution,
for both free and user-defined
parameters, call store_boot_est_std()
first to compute and store the bootstrap
estimates in the standardized solution.
Since Version 0.1.11.2, it can also
plot bootstrap estimates in the output
of standardizedSolution_boot_ci()
.
Return the original lavaan::lavaan object invisibly. Called for its side-effect (plotting the graphs).
Shu Fai Cheung https://orcid.org/0000-0002-9871-9448
Rousselet, G. A., Pernet, C. R., & Wilcox, R. R. (2021). The percentile bootstrap: A primer with step-by-step instructions in R. Advances in Methods and Practices in Psychological Science, 4(1), 1–10. doi:10.1177/2515245920911881
lavaan::fitMeasures()
, store_boot_est_std()
,
and store_boot_def()
.
library(lavaan) data(simple_mediation) mod <- " m ~ a * x y ~ b * m + x ab := a * b " fit <- sem(mod, simple_mediation, se = "bootstrap", bootstrap = 50, iseed = 985714) # Can plot bootstrap estimates for # free parameters directly # Note that 'standardized' must be always be set to # either TRUE or FALSE. No default value. plot_boot(fit, "a", standardized = FALSE) # For estimates of user-defined parameters, # call store_boot_def() first. fit <- store_boot_def(fit) plot_boot(fit, "ab", standardized = FALSE) # For estimates in standardized solution, # call store_boot_est_std() first. fit <- store_boot_est_std(fit) plot_boot(fit, "a", standardized = TRUE) plot_boot(fit, "ab", standardized = TRUE) # It can also plot the estimates stored # in the output of standardizedSolution_boot_ci(). std_boot <- standardizedSolution_boot_ci(fit) plot_boot(std_boot, "ab") plot_boot(fit, "ab", standardized = TRUE)
library(lavaan) data(simple_mediation) mod <- " m ~ a * x y ~ b * m + x ab := a * b " fit <- sem(mod, simple_mediation, se = "bootstrap", bootstrap = 50, iseed = 985714) # Can plot bootstrap estimates for # free parameters directly # Note that 'standardized' must be always be set to # either TRUE or FALSE. No default value. plot_boot(fit, "a", standardized = FALSE) # For estimates of user-defined parameters, # call store_boot_def() first. fit <- store_boot_def(fit) plot_boot(fit, "ab", standardized = FALSE) # For estimates in standardized solution, # call store_boot_est_std() first. fit <- store_boot_est_std(fit) plot_boot(fit, "a", standardized = TRUE) plot_boot(fit, "ab", standardized = TRUE) # It can also plot the estimates stored # in the output of standardizedSolution_boot_ci(). std_boot <- standardizedSolution_boot_ci(fit) plot_boot(std_boot, "ab") plot_boot(fit, "ab", standardized = TRUE)
Plot models on a graph with model chi-square against model the degrees of freedom, with lines for equal fit measures.
plot_models_fm( ..., fit_measure = c("cfi", "tli", "rmsea"), fit_values, line_size = 1, label_size = 8, point_size = 5, position_dodge = 0.5, include_model_values = FALSE, include_baseline = FALSE )
plot_models_fm( ..., fit_measure = c("cfi", "tli", "rmsea"), fit_values, line_size = 1, label_size = 8, point_size = 5, position_dodge = 0.5, include_model_values = FALSE, include_baseline = FALSE )
... |
The lavaan::lavaan objects to be plotted. Can also be a named list of the lavaan::lavaan objects. If it is as list, it must be named and the names will be used in the plot. |
fit_measure |
A length-one
character vector of the fit measures
to use to plot the lines. Only
supports |
fit_values |
A numeric vector
of the values of the fit measure
used to plot the lines. The default
values are |
line_size |
The size of the lines. Default is 1. |
label_size |
The size of the model names. Default is 8. |
point_size |
The size of the point representing a model. Default is 2. |
position_dodge |
Offsetting the
label of a model from the point.
Default is .5. Used by
|
include_model_values |
If |
include_baseline |
If |
This function plots models based on their model chi-squares and model degrees of freedoms.It can also add lines for chi-square-df combination with equal values on selected fit measures. Currently supports CFI, TLI, and RMSEA.
Return a ggplot2::ggplot()
output that can be further modified.
Shu Fai Cheung https://orcid.org/0000-0002-9871-9448
library(lavaan) # From the help page of modificationIndices HS.model <- ' visual =~ x1 + x2 + x3 textual =~ x4 + x5 + x6 speed =~ x7 + x8 + x9 ' fit <- cfa(HS.model, data = HolzingerSwineford1939) modindices(fit, sort = TRUE, op = "=~") fit2 <- update(fit, add = "visual =~ x9") fit3 <- update(fit, add = "textual =~ x3\nvisual =~ x7") models <- list(Initial = fit, Model_2 = fit2, Model_3 = fit3) fit_cfi <- sapply(models, fitMeasures, fit.measures = "cfi") fit_tli <- sapply(models, fitMeasures, fit.measures = "tli") fit_rmsea <- sapply(models, fitMeasures, fit.measures = "rmsea") # Supply the models as arguments plot_models_fm(fit, fit2, fit3) # Plot lines for selected values on a fit measure (CFI by default) plot_models_fm(fit, fit2, fit3, fit_values = c(.90, .925, .95, fit_cfi)) # Plot the models' values on the fit measures plot_models_fm(fit, fit2, fit3, include_model_values = TRUE) # Supply the models as a named list plot_models_fm(list(A = fit, B = fit2, C = fit3), fit_values = c(.90, .925, .95)) # Plot the models, fit measure set to TLI plot_models_fm(fit, fit2, fit3, fit_measure = "tli") plot_models_fm(fit, fit2, fit3, fit_measure = "tli", fit_values = c(.90, .925, .95, fit_tli)) plot_models_fm(fit, fit2, fit3, fit_measure = "tli", include_model_values = TRUE) # Plot the models, fit measure set to RMSEA plot_models_fm(fit, fit2, fit3, fit_measure = "rmsea") plot_models_fm(fit, fit2, fit3, fit_measure = "rmsea", include_model_values = TRUE)
library(lavaan) # From the help page of modificationIndices HS.model <- ' visual =~ x1 + x2 + x3 textual =~ x4 + x5 + x6 speed =~ x7 + x8 + x9 ' fit <- cfa(HS.model, data = HolzingerSwineford1939) modindices(fit, sort = TRUE, op = "=~") fit2 <- update(fit, add = "visual =~ x9") fit3 <- update(fit, add = "textual =~ x3\nvisual =~ x7") models <- list(Initial = fit, Model_2 = fit2, Model_3 = fit3) fit_cfi <- sapply(models, fitMeasures, fit.measures = "cfi") fit_tli <- sapply(models, fitMeasures, fit.measures = "tli") fit_rmsea <- sapply(models, fitMeasures, fit.measures = "rmsea") # Supply the models as arguments plot_models_fm(fit, fit2, fit3) # Plot lines for selected values on a fit measure (CFI by default) plot_models_fm(fit, fit2, fit3, fit_values = c(.90, .925, .95, fit_cfi)) # Plot the models' values on the fit measures plot_models_fm(fit, fit2, fit3, include_model_values = TRUE) # Supply the models as a named list plot_models_fm(list(A = fit, B = fit2, C = fit3), fit_values = c(.90, .925, .95)) # Plot the models, fit measure set to TLI plot_models_fm(fit, fit2, fit3, fit_measure = "tli") plot_models_fm(fit, fit2, fit3, fit_measure = "tli", fit_values = c(.90, .925, .95, fit_tli)) plot_models_fm(fit, fit2, fit3, fit_measure = "tli", include_model_values = TRUE) # Plot the models, fit measure set to RMSEA plot_models_fm(fit, fit2, fit3, fit_measure = "rmsea") plot_models_fm(fit, fit2, fit3, fit_measure = "rmsea", include_model_values = TRUE)
Print method for an 'est_table' object
## S3 method for class 'est_table' print(x, ..., nd = 3, empty_cells = "--", group_first = FALSE)
## S3 method for class 'est_table' print(x, ..., nd = 3, empty_cells = "--", group_first = FALSE)
x |
Object of the class
|
... |
Optional arguments to be
passed to |
nd |
The number of digits to be printed. Default is 3. (Scientific notation will never be used.) |
empty_cells |
String to be
printed for empty cells or cells with
no values. Default is |
group_first |
Not used. |
x
is returned invisibly. Called for its side effect.
Shu Fai Cheung https://orcid.org/0000-0002-9871-9448
Print method for a 'fit_by_models' object
## S3 method for class 'fit_by_models' print( x, ..., nd = 3, type = c("compact"), remove_all_na = TRUE, measures_compact = c("npar", "chisq", "chisq.scaled", "df", "df.scaled", "pvalue", "pvalue.scaled", "chisq.scaling.factor", "cfi", "cfi.robust", "tli", "tli.robust", "aic", "bic", "bic2", "rmsea", "rmsea.ci.level", "rmsea.ci.lower", "rmsea.ci.upper", "rmsea.close.h0", "rmsea.pvalue", "rmsea.robust", "rmsea.ci.lower.robust", "rmsea.ci.upper.robust", "rmsea.pvalue.robust", "srmr", "srmr_nomean") )
## S3 method for class 'fit_by_models' print( x, ..., nd = 3, type = c("compact"), remove_all_na = TRUE, measures_compact = c("npar", "chisq", "chisq.scaled", "df", "df.scaled", "pvalue", "pvalue.scaled", "chisq.scaling.factor", "cfi", "cfi.robust", "tli", "tli.robust", "aic", "bic", "bic2", "rmsea", "rmsea.ci.level", "rmsea.ci.lower", "rmsea.ci.upper", "rmsea.close.h0", "rmsea.pvalue", "rmsea.robust", "rmsea.ci.lower.robust", "rmsea.ci.upper.robust", "rmsea.pvalue.robust", "srmr", "srmr_nomean") )
x |
Object of the class
|
... |
Optional arguments to be
passed to |
nd |
The number of digits to be printed. Default is 3. (Scientific notation will never be used.) |
type |
String. The type of the
output. Currently only supports one
type, |
remove_all_na |
Logical. Whether
rows with |
measures_compact |
If output
|
This function is intended to
print the fit measures of one or
more groups in a simple and
compact table for quick preview.
For a well-organized
layout, call lavaan::fitMeasures()
and set output
to "text"
. For
comparing the models with notations
on models with the best fit on
each measures, use
semTools::compareFit()
.
x
is returned invisibly. Called for its side effect.
Shu Fai Cheung https://orcid.org/0000-0002-9871-9448
library(lavaan) set.seed(5478374) n <- 50 x <- runif(n) - .5 m <- .40 * x + rnorm(n, 0, sqrt(1 - .40)) y <- .30 * m + rnorm(n, 0, sqrt(1 - .30)) dat <- data.frame(x = x, y = y, m = m) model1 <- ' m ~ a*x y ~ b*m ab := a*b ' fit1 <- sem(model1, data = dat, fixed.x = FALSE) model2 <- ' m ~ a*x y ~ b*m + x ab := a*b ' fit2 <- sem(model2, data = dat, fixed.x = FALSE) out <- fitMeasures_by_models(list(no_direct = fit1, direct = fit2)) out print(out, nd = 4, measures_compact = c("chisq", "cfi", "rmsea"))
library(lavaan) set.seed(5478374) n <- 50 x <- runif(n) - .5 m <- .40 * x + rnorm(n, 0, sqrt(1 - .40)) y <- .30 * m + rnorm(n, 0, sqrt(1 - .30)) dat <- data.frame(x = x, y = y, m = m) model1 <- ' m ~ a*x y ~ b*m ab := a*b ' fit1 <- sem(model1, data = dat, fixed.x = FALSE) model2 <- ' m ~ a*x y ~ b*m + x ab := a*b ' fit2 <- sem(model2, data = dat, fixed.x = FALSE) out <- fitMeasures_by_models(list(no_direct = fit1, direct = fit2)) out print(out, nd = 4, measures_compact = c("chisq", "cfi", "rmsea"))
Print method for an
'std_solution_boot' object, which
is the output of
standardizedSolution_boot_ci()
.
## S3 method for class 'std_solution_boot' print(x, ..., nd = 3, output = c("table", "text"), standardized_only = TRUE)
## S3 method for class 'std_solution_boot' print(x, ..., nd = 3, output = c("table", "text"), standardized_only = TRUE)
x |
Object of the class
|
... |
Optional arguments to be
passed to |
nd |
The number of digits after the decimal place. Default is 3. |
output |
String. How the results
are printed. Default is |
standardized_only |
Logical.
If |
The default format of the printout
is that of lavaan::standardizedSolution()
,
which is compact but not easy to
read. Users can request a format
similar to that of the printout
of the summary of a lavaan
output
by setting output
to "text"
.
For the "text"
format, users can
also select whether
only the standardized solution is
printed (the default) or whether
the standardized solution is appended
to the right of the printout.
x
is returned invisibly. Called for its side effect.
Shu Fai Cheung https://orcid.org/0000-0002-9871-9448
standardizedSolution_boot_ci()
library(lavaan) set.seed(5478374) n <- 50 x <- runif(n) - .5 m <- .40 * x + rnorm(n, 0, sqrt(1 - .40)) y <- .30 * m + rnorm(n, 0, sqrt(1 - .30)) dat <- data.frame(x = x, y = y, m = m) model <- ' m ~ a*x y ~ b*m ab := a*b ' # Should set bootstrap to at least 2000 in real studies fit <- sem(model, data = dat, fixed.x = FALSE, se = "boot", bootstrap = 50) std_out <- standardizedSolution_boot_ci(fit) std_out print(std_out, output = "text") print(std_out, output = "text", standardized_only = FALSE)
library(lavaan) set.seed(5478374) n <- 50 x <- runif(n) - .5 m <- .40 * x + rnorm(n, 0, sqrt(1 - .40)) y <- .30 * m + rnorm(n, 0, sqrt(1 - .30)) dat <- data.frame(x = x, y = y, m = m) model <- ' m ~ a*x y ~ b*m ab := a*b ' # Should set bootstrap to at least 2000 in real studies fit <- sem(model, data = dat, fixed.x = FALSE, se = "boot", bootstrap = 50) std_out <- standardizedSolution_boot_ci(fit) std_out print(std_out, output = "text") print(std_out, output = "text", standardized_only = FALSE)
It tries to generate a
'lavaan' model syntax from a
lavaan
parameter table.
ptable_to_syntax(object, allow_incomplete = FALSE) compare_ptables(object1, object2)
ptable_to_syntax(object, allow_incomplete = FALSE) compare_ptables(object1, object2)
object |
If set to a |
allow_incomplete |
Whether
incomplete parameter table formed
by |
object1 |
The first |
object2 |
The second |
This function tries to convert
a lavaan
parameter table to a
text representation of the lavaan
model specified in model syntax.
When users call lavaan::sem()
,
in addition to the model syntax,
other arguments not stored in the
syntax are also used to produce
the final model (e.g.,
meanstructure
, fixed.x
, and
std.lv
). To produce exactly the
same model, these arguments are also
needed to be specified, which is
difficult to generate using only
the parameter table.
Therefore, the model syntax produced
will state all aspects of a model
explicitly, even for those aspects
that usually can be omitted due to
the default values of these arguments.
This approach requires users to call
lavaan::lavaan()
directly, instead
of its wrappers (e.g, lavaan::sem()
),
to produce the same parameter table.
The model syntax produced this way is more difficult to read. However, it ensures that original model can be reproduced, without the need to know the arguments to set.
Due to the nearly unlimited possibilities
in the form of a model, it is
recommended to compare the model
generated by the model syntax with
the original parameter table using
compare_ptables()
. It
only compares the forms of the
two models, including user starting
values, if any. It does not compare
parameter estimates and standard
errors.
lavaan::lavParseModelString()
There may be cases in which the
parameter table is the "incomplete"
table generated by lavaan::lavParseModelString()
,
with as.data.frame. = TRUE
.
This table is "incomplete" because
it is formed merely by parsing the
model syntax. There is no guarantee
that the model is valid.
The function ptable_to_syntax()
has basic support for this kind
of tables but it is disabled by
default. To process an incomplete
parameter table formed by
lavaan::lavParseModelString()
,
set allow_incomplete
to TRUE
.
The function ptable_to_syntax()
does not yet support the following
models:
Multiple-group models.
Multilevel models.
Models with categorical variables.
Models with user-specified lower or upper bounds.
Models with the operator <~
.
Models with constraints imposed by
equal()
.
Models with labels having spaces.
Models with labels having syntax
operators (e.g., ~
, =~
, etc.).
ptable_to_syntax()
returns a
length-one character vector that stores
the generated lavaan
model syntax.
compare_ptables()
returns a
length-one logical vector. TRUE
if the two models are identical
in form. FALSE
if they are
not identical.
ptable_to_syntax()
: Convert
a lavaan parameter a lavaan model
syntax.
compare_ptables()
: Compare two lavaan parameter tables.
Shu Fai Cheung https://orcid.org/0000-0002-9871-9448. This function is inspired by a discussion at the Google Group https://groups.google.com/g/lavaan/c/1ueFiue9qLM/m/cJhxDoqeBAAJ.
lavaan::lavaan()
, lavaan::parameterTable()
library(lavaan) mod <- " visual =~ x3 + x1 + x2 textual =~ x4 + x6 + x5 speed =~ x7 + x8 + x9 + start(0.1) * x6 visual ~ a*textual speed ~ b*visual ab := a * b " fit <- sem(mod, data = HolzingerSwineford1939) mod_chk <- ptable_to_syntax(fit) cat(mod_chk, sep = "\n") # Need to call lavaan() directly fit_chk <- lavaan(mod_chk, data = HolzingerSwineford1939) fit_chk fit # Compare the parameter table: (ptable1 <- parameterTable(fit)) (ptable2 <- parameterTable(fit_chk)) compare_ptables(ptable1, ptable2)
library(lavaan) mod <- " visual =~ x3 + x1 + x2 textual =~ x4 + x6 + x5 speed =~ x7 + x8 + x9 + start(0.1) * x6 visual ~ a*textual speed ~ b*visual ab := a * b " fit <- sem(mod, data = HolzingerSwineford1939) mod_chk <- ptable_to_syntax(fit) cat(mod_chk, sep = "\n") # Need to call lavaan() directly fit_chk <- lavaan(mod_chk, data = HolzingerSwineford1939) fit_chk fit # Compare the parameter table: (ptable1 <- parameterTable(fit)) (ptable2 <- parameterTable(fit_chk)) compare_ptables(ptable1, ptable2)
Record the minimization
history when a model is fitted by
lavaan::lavaan()
or its wrappers
(e.g., lavaan::sem()
or
lavaan::cfa()
).
record_history(object) ## S3 method for class 'fit_history' plot(x, params, last_n = -1, orientation = c("horizontal", "vertical"), ...) ## S3 method for class 'fit_history' print(x, n_iterations = 10, digits = 3, ...)
record_history(object) ## S3 method for class 'fit_history' plot(x, params, last_n = -1, orientation = c("horizontal", "vertical"), ...) ## S3 method for class 'fit_history' print(x, n_iterations = 10, digits = 3, ...)
object |
A 'lavaan'-class object. |
x |
A |
params |
A character vector of
the names of parameters to be
plotted. Must be the names of one or
more columns in |
last_n |
The lass |
orientation |
The orientation of
the plot. Either |
... |
Optional arguments. To be passed to the print method of data frame. |
n_iterations |
The number of iterations to print. Default is 10, printing the first 10 iterations (or all iterations, if the number of iterations is less than 10). |
digits |
The number of digits to be displayed. Default is 3. |
It records the minimization
history when a model is fitted by
lavaan::lavaan()
or its wrappers
(e.g., lavaan::sem()
or
lavaan::cfa()
). The recorded
history can then be plotted or
displayed, for visualizing how the
estimates of free parameters is
found.
It will refit the model by the
update
method of
lavaan::lavaan, setting se = "none"
and test = "standard"
because they have no impact on the
minimization process.
This and related functions are
adapted from the package semunpack
.
The version in this package will be
revised to be an advanced version
intended for diagnostic purpose in
real studies.
A fit_history
-class object
with a plot
method
(plot.fit_history()
).
plot(fit_history)
: The plot
method for the output of
record_history()
.
print(fit_history)
: The print
method for the output of
record_history()
.
Shu Fai Cheung https://orcid.org/0000-0002-9871-9448
# Adapted from the example for CFA in lavaan::cfa(). # Using only two of the factors library(lavaan) HS.model <- ' visual =~ x1 + x2 + x3 textual =~ x4 + x5 + x6 ' fit <- cfa(HS.model, data = HolzingerSwineford1939) # Refit the model with the history recorded fit_h <- record_history(fit) fit_h # Plot the history for selected parameters plot(fit_h, params = c("visual=~x2", "visual=~x3", "visual~~textual"), last_n = 10) plot(fit_h, params = c("visual=~x2", "visual=~x3", "visual~~textual"), last_n = 10, orientation = "vertical")
# Adapted from the example for CFA in lavaan::cfa(). # Using only two of the factors library(lavaan) HS.model <- ' visual =~ x1 + x2 + x3 textual =~ x4 + x5 + x6 ' fit <- cfa(HS.model, data = HolzingerSwineford1939) # Refit the model with the history recorded fit_h <- record_history(fit) fit_h # Plot the history for selected parameters plot(fit_h, params = c("visual=~x2", "visual=~x3", "visual~~textual"), last_n = 10) plot(fit_h, params = c("visual=~x2", "visual=~x3", "visual~~textual"), last_n = 10, orientation = "vertical")
Show how CFI and TLI are computed using a graph of model chi-square vs. model degrees of freedom.
show_cfi(fit, ...) show_tli(fit, ...) show_ifi(fit, fit_measures = c("cfi", "tli"), test = c("standard"))
show_cfi(fit, ...) show_tli(fit, ...) show_ifi(fit, fit_measures = c("cfi", "tli"), test = c("standard"))
fit |
An output of
|
... |
Arguments to be passed to |
fit_measures |
The fit measures
to be plotted. Acceptable values are
|
test |
The type of model
chi-square test. It corresponds
to the |
This function receives an
output of lavaan::lavaan()
or its
wrappers (e.g., lavaan::cfa()
and lavaan::sem()
) and
illustrates how CFI is computed.
An output of
ggplot2::ggplot()
that can be
further modified.
show_cfi()
: A wrapper of show_ifi()
with fit_measures = "cfi"
.
show_tli()
: A wrapper of show_ifi()
with fit_measures = "tli"
.
Shu Fai Cheung https://orcid.org/0000-0002-9871-9448
library(lavaan) # From the help page of lavaan::cfa(). HS.model <- ' visual =~ x1 + x2 + x3 textual =~ x4 + x5 + x6 speed =~ x7 + x8 + x9 ' fit <- cfa(HS.model, data = HolzingerSwineford1939) # By default show how CFI is computed show_ifi(fit) # Show how TLI is computed show_ifi(fit, fit_measures = "tli") # Wrappers show_cfi(fit) show_tli(fit)
library(lavaan) # From the help page of lavaan::cfa(). HS.model <- ' visual =~ x1 + x2 + x3 textual =~ x4 + x5 + x6 speed =~ x7 + x8 + x9 ' fit <- cfa(HS.model, data = HolzingerSwineford1939) # By default show how CFI is computed show_ifi(fit) # Show how TLI is computed show_ifi(fit, fit_measures = "tli") # Wrappers show_cfi(fit) show_tli(fit)
Display the values of
more major options in a model fitted
by lavaan::lavaan()
or its
wrappers (e.g., lavaan::sem or
lavaan::cfa()
).
show_more_options(fit) ## S3 method for class 'show_more_options' print(x, ...)
show_more_options(fit) ## S3 method for class 'show_more_options' print(x, ...)
fit |
An output of
|
x |
The output of |
... |
Additional arguments. Ignored. |
It extracts the values of
major options in the output of
lavaan::lavaan()
or its wrappers
(e.g., lavaan::sem or
lavaan::cfa()
. Most of the values
are also reported in the summary of
a 'lavaan'-class object. This
function is used to show the values
in one single table for a quick
overview.
It checks the actual values, not the
call used. This is useful for
understanding how a prepackaged
estimator such as ML
, MLM
, and
MLR
set other options. It supports
the following options:
Estimator (estimator
)
Standard error (se
)
Model chi-square test(s) (test
)
Missing data method (missing
)
Information matrix used for
computing standard errors
(information
)
Information matrix used for
computing model chi-square
(information
)
Whether the mean structure is included.
It is named show_more_options()
to
differentiate it from
show_options()
, originally in the
semunpack
package, which is
intended for new users of lavaan``. The code is adapted from
show_options' with more advanced
options added.
A show_more_options
-class
object with a print method that
formats the output.
print(show_more_options)
: The print method of the output of show_more_options()
.
Shu Fai Cheung https://orcid.org/0000-0002-9871-9448
library(lavaan) # From the help page of lavaan::cfa(). HS.model <- ' visual =~ x1 + x2 + x3 textual =~ x4 + x5 + x6 speed =~ x7 + x8 + x9 ' fit <- cfa(HS.model, data = HolzingerSwineford1939) tmp <- show_more_options(fit) tmp fit <- cfa(HS.model, data = HolzingerSwineford1939, estimator = "MLR") show_more_options(fit) fit <- cfa(HS.model, data = HolzingerSwineford1939, estimator = "MLM") show_more_options(fit)
library(lavaan) # From the help page of lavaan::cfa(). HS.model <- ' visual =~ x1 + x2 + x3 textual =~ x4 + x5 + x6 speed =~ x7 + x8 + x9 ' fit <- cfa(HS.model, data = HolzingerSwineford1939) tmp <- show_more_options(fit) tmp fit <- cfa(HS.model, data = HolzingerSwineford1939, estimator = "MLR") show_more_options(fit) fit <- cfa(HS.model, data = HolzingerSwineford1939, estimator = "MLM") show_more_options(fit)
Display the values of
major options in a model fitted
by lavaan::lavaan()
or its
wrappers (e.g., lavaan::sem()
or
lavaan::cfa()
).
show_options(fit) ## S3 method for class 'show_options' print(x, ...)
show_options(fit) ## S3 method for class 'show_options' print(x, ...)
fit |
An output of
|
x |
The output of |
... |
Additional arguments. Ignored. |
It extracts the values of
major options in the output of
lavaan::lavaan()
or its wrappers
(e.g., lavaan::sem()
or
lavaan::cfa()
.
It checks the actual values, not
the call used. This is useful for
understanding how a prepackaged
estimator such as ML
, MLM
, and
MLR
set other options. It
supports the following options:
Estimator (estimator
)
Standard error (se
)
Model chi-square test(s) (test
)
Missing data method (missing
)
Information matrix used for
computing standard errors
(information
)
Information matrix used for
computing model chi-square
(information
)
Whether the mean structure is included.
A show_options
-class object with a
print method that formats the output.
print(show_options)
: The print method of the output of show_options()
.
Shu Fai Cheung https://orcid.org/0000-0002-9871-9448
library(lavaan) # From the help page of lavaan::cfa(). HS.model <- ' visual =~ x1 + x2 + x3 textual =~ x4 + x5 + x6 speed =~ x7 + x8 + x9 ' fit <- cfa(HS.model, data = HolzingerSwineford1939) tmp <- show_options(fit) tmp fit <- cfa(HS.model, data = HolzingerSwineford1939, estimator = "MLR") show_options(fit) fit <- cfa(HS.model, data = HolzingerSwineford1939, estimator = "MLM") show_options(fit)
library(lavaan) # From the help page of lavaan::cfa(). HS.model <- ' visual =~ x1 + x2 + x3 textual =~ x4 + x5 + x6 speed =~ x7 + x8 + x9 ' fit <- cfa(HS.model, data = HolzingerSwineford1939) tmp <- show_options(fit) tmp fit <- cfa(HS.model, data = HolzingerSwineford1939, estimator = "MLR") show_options(fit) fit <- cfa(HS.model, data = HolzingerSwineford1939, estimator = "MLM") show_options(fit)
A simple mediation model.
simple_mediation
simple_mediation
A data frame with 100 rows and 5 variables:
Predictor. Numeric.
Mediator. Numeric.
Outcome variable. Numeric.
Group variable: "City A" or "City B". String.
library(lavaan) data(simple_mediation) mod <- " m ~ a * x y ~ b * m + x ab := a * b " fit <- sem(mod, simple_mediation, fixed.x = FALSE) parameterEstimates(fit) mod_gp <- " m ~ c(a1, a2) * x y ~ c(b1, b2) * m + x a1b1 := a1 * b1 a2b2 := a2 * b2 ab_diff := a1b1 - a2b2 " fit_gp <- sem(mod_gp, simple_mediation, fixed.x = FALSE, group = "city") parameterEstimates(fit_gp)
library(lavaan) data(simple_mediation) mod <- " m ~ a * x y ~ b * m + x ab := a * b " fit <- sem(mod, simple_mediation, fixed.x = FALSE) parameterEstimates(fit) mod_gp <- " m ~ c(a1, a2) * x y ~ c(b1, b2) * m + x a1b1 := a1 * b1 a2b2 := a2 * b2 ab_diff := a1b1 - a2b2 " fit_gp <- sem(mod_gp, simple_mediation, fixed.x = FALSE, group = "city") parameterEstimates(fit_gp)
Sort a parameter
estimates table or a similar table
inlavaan
by common fields such as
op
(operator) and lhs
(left-
hand side).
sort_by( object, by = c("op", "lhs", "rhs"), op_priority = c("=~", "~", "~~", ":=", "~1", "|", "~*~"), number_rows = TRUE )
sort_by( object, by = c("op", "lhs", "rhs"), op_priority = c("=~", "~", "~~", ":=", "~1", "|", "~*~"), number_rows = TRUE )
object |
The output of
|
by |
A character vector of the
columns for filtering. Default
is |
op_priority |
How rows are
sorted by |
number_rows |
Whether the row
names will be set to row numbers
after sorting if the row names
of |
This functions accepts the
output of
lavaan::parameterEstimates()
and
lavaan::standardizedSolution()
and
filter the rows by commonly used
field.
The sorted version of the input object.
Shu Fai Cheung https://orcid.org/0000-0002-9871-9448
library(lavaan) set.seed(5478374) n <- 50 x <- runif(n) - .5 m <- .40 * x + rnorm(n, 0, sqrt(1 - .40)) y <- .30 * m + rnorm(n, 0, sqrt(1 - .30)) dat <- data.frame(x = x, y = y, m = m) model1 <- ' m ~ a*x y ~ b*m ab := a*b ' fit1 <- sem(model1, data = dat, fixed.x = FALSE) model2 <- ' m ~ a*x y ~ b*m + x ab := a*b ' fit2 <- sem(model2, data = dat, fixed.x = FALSE) parameterEstimates(fit1) parameterEstimates(fit2) out <- group_by_models(list(no_direct = fit1, direct = fit2), col_names = c("est", "pvalue")) out sort_by(out) sort_by(out, op_priority = c("~", ":=")) sort_by(out, by = c("op", "rhs"))
library(lavaan) set.seed(5478374) n <- 50 x <- runif(n) - .5 m <- .40 * x + rnorm(n, 0, sqrt(1 - .40)) y <- .30 * m + rnorm(n, 0, sqrt(1 - .30)) dat <- data.frame(x = x, y = y, m = m) model1 <- ' m ~ a*x y ~ b*m ab := a*b ' fit1 <- sem(model1, data = dat, fixed.x = FALSE) model2 <- ' m ~ a*x y ~ b*m + x ab := a*b ' fit2 <- sem(model2, data = dat, fixed.x = FALSE) parameterEstimates(fit1) parameterEstimates(fit2) out <- group_by_models(list(no_direct = fit1, direct = fit2), col_names = c("est", "pvalue")) out sort_by(out) sort_by(out, op_priority = c("~", ":=")) sort_by(out, by = c("op", "rhs"))
Functions for forming bootstrap confidence intervals for the standardized solution.
standardizedSolution_boot_ci( object, level = 0.95, type = "std.all", save_boot_est_std = TRUE, force_run = FALSE, boot_delta_ratio = FALSE, boot_ci_type = c("perc", "bc", "bca.simple"), ... ) store_boot_est_std(object, type = "std.all", force_run = FALSE, ...) get_boot_est_std(object)
standardizedSolution_boot_ci( object, level = 0.95, type = "std.all", save_boot_est_std = TRUE, force_run = FALSE, boot_delta_ratio = FALSE, boot_ci_type = c("perc", "bc", "bca.simple"), ... ) store_boot_est_std(object, type = "std.all", force_run = FALSE, ...) get_boot_est_std(object)
object |
A 'lavaan'-class object, fitted with 'se = "boot"'. |
level |
The level of confidence of the confidence intervals. Default is .95. |
type |
The type of standard
estimates. The same argument of
|
save_boot_est_std |
Whether the
bootstrap estimates of the
standardized solution are saved. If
saved, they will be stored in the
attribute |
force_run |
If |
boot_delta_ratio |
The ratio of
(a) the distance of the bootstrap
confidence limit from the point
estimate to (b) the distance of the
delta-method limit from the point
estimate. Default is |
boot_ci_type |
The type of the
bootstrapping confidence intervals.
Support percentile confidence intervals
( |
... |
Other arguments to be
passed to
|
standardizedSolution_boot_ci()
receives a
lavaan::lavaan object fitted
with bootstrapping standard errors
requested and forms the confidence
intervals for the standardized
solution.
It works by calling
lavaan::standardizedSolution()
with the bootstrap estimates
of free parameters in each bootstrap sample
to compute the standardized estimates
in each sample.
A more reliable way is to use
function like
lavaan::bootstrapLavaan()
.
Nevertheless, this simple function is
good enough for some simple scenarios,
and does not require repeating
the bootstrapping step.
store_boot_est_std()
computes the
standardized solution for each bootstrap
sample, stores them the
lavaan::lavaan object, and
returns it. These estimates can be used
by other functions, such as plot_boot()
,
to examine the
estimates, without the need
to repeat the computation.
get_boot_est_std()
retrieves
the bootstrap estimates of the
standardized solution stored by
store_boot_est_std()
.
The output of
lavaan::standardizedSolution()
,
with bootstrap confidence intervals
appended to the right, with class
set to std_solution_boot
(since
version 0.1.8.4). It has
a print method
(print.std_solution_boot()
) that
can be used to print the standardized
solution in a format similar to
that of the printout of
the summary()
of a lavaan::lavaan object.
store_boot_est_std()
returns
the fit object set to
object
, with the bootstrap values
of standardized solution in the
bootstrap samples, as a matrix,
stored in the
slot external
under the name
shh_boot_est_std
.
get_boot_est_std()
returns a matrix
of the stored bootstrap estimates
of standardized solution. If none is
stored, NULL
is returned.
store_boot_est_std()
is usually used
with diagnostic functions such
as plot_boot()
.
Shu Fai Cheung
https://orcid.org/0000-0002-9871-9448.
Originally proposed in an issue at GitHub
https://github.com/simsem/semTools/issues/101#issue-1021974657,
inspired by a discussion at
the Google group for lavaan
https://groups.google.com/g/lavaan/c/qQBXSz5cd0o/m/R8YT5HxNAgAJ.
boot::boot.ci()
is used to form the
percentile confidence intervals in
this version.
lavaan::standardizedSolution()
, plot_boot()
library(lavaan) set.seed(5478374) n <- 50 x <- runif(n) - .5 m <- .40 * x + rnorm(n, 0, sqrt(1 - .40)) y <- .30 * m + rnorm(n, 0, sqrt(1 - .30)) dat <- data.frame(x = x, y = y, m = m) model <- ' m ~ a*x y ~ b*m ab := a*b ' # Should set bootstrap to at least 2000 in real studies fit <- sem(model, data = dat, fixed.x = FALSE, se = "boot", bootstrap = 100) summary(fit) std <- standardizedSolution_boot_ci(fit) std # Print in a friendly format with only standardized solution print(std, output = "text") # Print in a friendly format with both unstandardized # and standardized solution print(std, output = "text", standardized_only = FALSE) # plot_boot() can be used to examine the bootstrap estimates # of a parameter plot_boot(std, param = "ab") # store_boot_est_std() is usually used with plot_boot() # First, store the bootstrap estimates of the # standardized solution fit_with_boot_std <- store_boot_est_std(fit) # Second, plot the distribution of the bootstrap estimates of # standardized 'ab' plot_boot(fit_with_boot_std, "ab", standardized = TRUE)
library(lavaan) set.seed(5478374) n <- 50 x <- runif(n) - .5 m <- .40 * x + rnorm(n, 0, sqrt(1 - .40)) y <- .30 * m + rnorm(n, 0, sqrt(1 - .30)) dat <- data.frame(x = x, y = y, m = m) model <- ' m ~ a*x y ~ b*m ab := a*b ' # Should set bootstrap to at least 2000 in real studies fit <- sem(model, data = dat, fixed.x = FALSE, se = "boot", bootstrap = 100) summary(fit) std <- standardizedSolution_boot_ci(fit) std # Print in a friendly format with only standardized solution print(std, output = "text") # Print in a friendly format with both unstandardized # and standardized solution print(std, output = "text", standardized_only = FALSE) # plot_boot() can be used to examine the bootstrap estimates # of a parameter plot_boot(std, param = "ab") # store_boot_est_std() is usually used with plot_boot() # First, store the bootstrap estimates of the # standardized solution fit_with_boot_std <- store_boot_est_std(fit) # Second, plot the distribution of the bootstrap estimates of # standardized 'ab' plot_boot(fit_with_boot_std, "ab", standardized = TRUE)
It receives a lavaan::lavaan object fitted with bootstrapping standard errors requested, computes the user-defined parameters in each bootstrap samples, and returns a lavaan::lavaan object with the estimates stored.
store_boot_def(object, force_run = FALSE) get_boot_def(object)
store_boot_def(object, force_run = FALSE) get_boot_def(object)
object |
A 'lavaan'-class object, fitted with 'se = "boot"'. |
force_run |
If |
lavaan::lavaan()
and its wrappers,
such as lavaan::sem()
and
lavaan::cfa()
, stores the estimates
of free parameters in each bootstrap
sample if bootstrapping is requested.
However, if a model has user-defined
parameters, their values in each
bootstrap sample are not stored.
store_boot_def()
computes the
retrieves the stored bootstrap
estimates and computes the values
of user-defined parameters. The
values are then stored in the slot
external
of the object,
in the element shh_boot_def
.
The bootstrap estimates can then be
used by other functions for diagnostics
purposes.
get_boot_def()
extracts the
bootstrap estimates of user-defined
parameters from a 'lavaan'-class
object. If none is stored, NULL
is returned.
store_boot_def()
is usually used
with diagnostic functions such
as plot_boot()
.
store_boot_def()
returns
the fit object set to
object
, with the bootstrap values
of user-defined parameters in the
bootstrap samples, as a matrix,
stored in the
slot external
of object
under
the name
shh_boot_def
.
get_boot_def()
returns a matrix
of the stored bootstrap estimates
of user-defined parameters
Shu Fai Cheung https://orcid.org/0000-0002-9871-9448.
library(lavaan) set.seed(5478374) n <- 50 x <- runif(n) - .5 m <- .40 * x + rnorm(n, 0, sqrt(1 - .40)) y <- .30 * m + rnorm(n, 0, sqrt(1 - .30)) dat <- data.frame(x = x, y = y, m = m) model <- ' m ~ a*x y ~ b*m ab := a*b ' # Should set bootstrap to at least 2000 in real studies fit <- sem(model, data = dat, fixed.x = FALSE, se = "boot", bootstrap = 100) summary(fit) # store_boot_def() is usually used with plot_boot() # First, store the bootstrap estimates of user-defined # parameters fit_with_boot_def <- store_boot_def(fit) # Second, plot the distribution of the bootstrap estimates of # 'ab' plot_boot(fit_with_boot_def, "ab", standardized = FALSE)
library(lavaan) set.seed(5478374) n <- 50 x <- runif(n) - .5 m <- .40 * x + rnorm(n, 0, sqrt(1 - .40)) y <- .30 * m + rnorm(n, 0, sqrt(1 - .30)) dat <- data.frame(x = x, y = y, m = m) model <- ' m ~ a*x y ~ b*m ab := a*b ' # Should set bootstrap to at least 2000 in real studies fit <- sem(model, data = dat, fixed.x = FALSE, se = "boot", bootstrap = 100) summary(fit) # store_boot_def() is usually used with plot_boot() # First, store the bootstrap estimates of user-defined # parameters fit_with_boot_def <- store_boot_def(fit) # Second, plot the distribution of the bootstrap estimates of # 'ab' plot_boot(fit_with_boot_def, "ab", standardized = FALSE)
A set of wrapper functions
to extract information from a
lavaan
-class object and return
a named vector.
vec_rsquare(object) vec_sample_vcov(object) vec_sample_var(object) vec_est_var(object) vec_est_se(object) vec_def_var(object) vec_def_se(object) vec_lavTestLRT( object, ..., method = "default", A.method = "delta", scaled.shifted = TRUE, H1 = TRUE, model.names = NULL ) vec_lavTestScore( object, add = NULL, release = NULL, univariate = TRUE, information = "expected" ) vec_lavTestWald(object, constraints = NULL, prefix = NULL) vec_compRelSEM(object, ...)
vec_rsquare(object) vec_sample_vcov(object) vec_sample_var(object) vec_est_var(object) vec_est_se(object) vec_def_var(object) vec_def_se(object) vec_lavTestLRT( object, ..., method = "default", A.method = "delta", scaled.shifted = TRUE, H1 = TRUE, model.names = NULL ) vec_lavTestScore( object, add = NULL, release = NULL, univariate = TRUE, information = "expected" ) vec_lavTestWald(object, constraints = NULL, prefix = NULL) vec_compRelSEM(object, ...)
object |
A |
... |
Additional arguments to be passed to the original function. |
method |
An argument to be
passed to |
A.method |
An argument to be
passed |
scaled.shifted |
An argument to
be
passed to |
H1 |
An argument to be passed
to
|
model.names |
An argument to
be
passed to |
add |
An argument to be passed
to |
release |
An argument to be passed
to |
univariate |
An argument to be passed
to |
information |
An argument to be passed
to |
constraints |
An argument to be passed
to |
prefix |
Optional. A character
string to be added as a prefix to
names of the output. Default is
|
This set of wrapper
functions are for functions like
lavaan::bootstrapLavaan()
that
require users to supply a function
that receives
a lavaan
-class object and returns
a vector of values.
All wrappers functions are designed to have the same form of output: a named numeric vector.
Many of the tasks of this set of wrappers can be performed by writing our own functions. The wrapper functions are developed just to save the coding time for some commonly requested information.
The wrapper functions are designed to be as simple to use as possible, with as few arguments as possible. If advanced control is needed, users are recommended to write their own wrappers.
All of them return a named numeric vector.
vec_rsquare()
: Get R-squares in a model.
vec_sample_vcov()
: Get sample variances and covariances.
vec_sample_var()
: Get sample variances.
vec_est_var()
: Sampling variances of free parameters.
vec_est_se()
: Standard errors of free parameters.
vec_def_var()
: Sampling variances of user-defined parameters.
vec_def_se()
: Standard errors of user-defined parameters.
vec_lavTestLRT()
: Get sample variances.
vec_lavTestScore()
: Do score tests.
vec_lavTestWald()
: Do a Wald test.
vec_compRelSEM()
: Composite reliability.
Shu Fai Cheung https://orcid.org/0000-0002-9871-9448
# From the help page of lavaan::cfa(). library(lavaan) HS.model <- ' visual =~ x1 + x2 + x3 textual =~ x4 + x5 + x6 speed =~ x7 + x8 + x9 ' fit <- cfa(HS.model, data = HolzingerSwineford1939) vec_rsquare(fit) vec_sample_vcov(fit) vec_sample_var(fit) vec_est_var(fit) vec_est_se(fit) HS.model.sem1 <- ' visual =~ x1 + x2 + x3 textual =~ x4 + x5 + x6 speed =~ x7 + x8 + x9 textual ~ a * visual speed ~ b * textual ab := a * b ' fit_sem1 <- sem(HS.model.sem1, data = HolzingerSwineford1939) HS.model.sem2 <- ' visual =~ x1 + x2 + x3 textual =~ x4 + x5 + x6 speed =~ x7 + x8 + x9 textual ~ a * visual speed ~ b * textual + cp * visual ab := a * b ' fit_sem2 <- sem(HS.model.sem2, data = HolzingerSwineford1939) vec_def_var(fit_sem1) vec_def_se(fit_sem1) vec_lavTestLRT(fit_sem1, fit_sem2, model.names = c("No Direct", "Direct")) vec_lavTestScore(fit_sem1, add = "speed ~ visual") vec_lavTestWald(fit_sem2, constraints = "cp == 0") if (requireNamespace("semTools")) { vec_compRelSEM(fit) }
# From the help page of lavaan::cfa(). library(lavaan) HS.model <- ' visual =~ x1 + x2 + x3 textual =~ x4 + x5 + x6 speed =~ x7 + x8 + x9 ' fit <- cfa(HS.model, data = HolzingerSwineford1939) vec_rsquare(fit) vec_sample_vcov(fit) vec_sample_var(fit) vec_est_var(fit) vec_est_se(fit) HS.model.sem1 <- ' visual =~ x1 + x2 + x3 textual =~ x4 + x5 + x6 speed =~ x7 + x8 + x9 textual ~ a * visual speed ~ b * textual ab := a * b ' fit_sem1 <- sem(HS.model.sem1, data = HolzingerSwineford1939) HS.model.sem2 <- ' visual =~ x1 + x2 + x3 textual =~ x4 + x5 + x6 speed =~ x7 + x8 + x9 textual ~ a * visual speed ~ b * textual + cp * visual ab := a * b ' fit_sem2 <- sem(HS.model.sem2, data = HolzingerSwineford1939) vec_def_var(fit_sem1) vec_def_se(fit_sem1) vec_lavTestLRT(fit_sem1, fit_sem2, model.names = c("No Direct", "Direct")) vec_lavTestScore(fit_sem1, add = "speed ~ visual") vec_lavTestWald(fit_sem2, constraints = "cp == 0") if (requireNamespace("semTools")) { vec_compRelSEM(fit) }