knitr::opts_chunk$set( collapse = TRUE, comment = "#>" )
This article is a brief illustration of how
to use mod_levels()
,
mod_levels_list()
, and merge_mod_levels()
from the package
manymome
(Cheung & Cheung, 2023)
to generate a table of moderator levels for use
by cond_indirect_effects()
. No need to use these
functions if the default levels generated by
cond_indirect_effects()
is appropriated,
as illustrated in vignette("manymome")
.
Use these functions only when users want to use levels of the moderators other than those default levels.
We first use the sample data set data_med_mod_ab
:
library(manymome) dat <- data_med_mod_ab print(head(dat), digits = 3)
Suppose this is the model being fitted:
library(lavaan) dat$w1x <- dat$w1 * dat$x dat$w2m <- dat$w2 * dat$m mod <- " m ~ x + w1 + w1x y ~ m + w2 + w2m m ~~ w2 + w2m w2 ~~ w2m + x + w1 + w1x w2m ~~ x + w1 + w1x x ~~ w1 + w1x w1 ~~ w1x " fit <- sem(model = mod, data = dat)
It has two numeric moderators, w1
and w2
. To
generate these three levels for w1
, one standard
deviation (SD) below mean, mean, and one SD above
mean, just call mod_levels()
:
w1levels <- mod_levels(w = "w1", fit = fit) w1levels
This is not necessary in calling cond_indirect_effects()
because it will automatically generate these default
levels.
Suppose we want to use only two levels, one SD below and
one SD above mean, we can set the argument sd_from_mean
to a vector of distances from means, which are -1
and
1
in this example:
w1levels <- mod_levels(w = "w1", fit = fit, sd_from_mean = c(-1, 1)) w1levels
To generate the levels based on percentiles, set the
argument w_method
to "percentile"
:
w1levels <- mod_levels(w = "w1", fit = fit, w_method = "percentile") w1levels
The default percentiles are 16th, 50th, and 84th, corresponding to one SD below mean, mean, and one SD above mean in a normal distribution.
Suppose we want to change the percentiles to be used,
for example, 25th and 75th, set the argument percentiles
as shown below:
w1levels <- mod_levels(w = "w1", fit = fit, w_method = "percentile", percentiles = c(.25, .75)) w1levels
If there are values that are meaningful for a moderator,
they can be used by setting values
to a vector of values:
w1levels <- mod_levels(w = "w1", fit = fit, values = c(2, 4, 8)) w1levels
The output of mod_levels
can be used when calling
cond_indirect_effects()
:
out <- cond_indirect_effects(wlevels = w1levels, x = "x", y = "m", fit = fit) out
cond_indirect_effects()
will determine the moderators
automatically from the object assigned to wlevels
.
In the previous example, there are two moderators.
We can
call mod_levels()
once for each of them, or call
mod_levels_list()
:
wlevels_list <- mod_levels_list("w1", "w2", fit = fit) wlevels_list
The output is a list of the output of mod_levels()
.
With two or more moderators, the default levels are
two: one SD below mean and one SD above mean.
The function mod_levels_list()
can merge the output into one table by setting merge
to TRUE
:
wlevels_list <- mod_levels_list("w1", "w2", fit = fit, merge = TRUE) wlevels_list
Calling mod_levels_list()
is useful when the same settings will
be used for all moderators. Most arguments of mod_levels()
can be used in mod_levels_list()
. For example, if we want to use
25th and 75th percentiles for both w1
and w2
, use w_method
and percentiles
as before:
wlevels_list <- mod_levels_list("w1", "w2", fit = fit, w_method = "percentile", percentiles = c(.25, .75), merge = TRUE) wlevels_list
If we need to use different settings for the two moderators,
then we need to call mod_levels()
once for each of them,
and merge the results by merge_mod_levels()
:
w1levels <- mod_levels(w = "w1", fit = fit) w1levels w2levels <- mod_levels(w = "w2", fit = fit, values = c(2, 5)) w2levels wlevels_all <- merge_mod_levels(w1levels, w2levels) wlevels_all
We use the dataset data_med_mod_serial_cat
for illustration:
dat <- data_med_mod_serial_cat print(head(dat), digits = 3)
It has two categorical moderators, w1
with three categories
and w2
with two categories. We use only w1
here
for illustration.
To fit a model using path analysis, two dummy variables need
to be created for w1
. This can be done by factor2var()
or similar functions from other packages.
w1dummies <- factor2var(dat$w1, prefix = "w1") head(w1dummies) # Add them to the dataset dat[, c("w1group2", "w1group3")] <- w1dummies print(head(dat), digits = 3)
This is the model:
dat$w1group2x <- dat$w1group2 * dat$x dat$w1group3x <- dat$w1group3 * dat$x mod <- " m1 ~ x + w1group2 + w1group3 + w1group2x + w1group3x y ~ m1 + x " fit <- sem(model = mod, data = dat)
The levels of a categorical moderator are just the
categories (unique combinations of the coding). This
can be generated by mod_levels()
.
w
should be a vector of the dummy variables:
w1levels <- mod_levels(w = c("w1group2", "w1group3"), fit = fit) w1levels
The names of group2
and group3
are 2
and 3
because they
are inferred from the names of the dummy variables. The common part,
"w1group"
, is removed.
To tell mod_levels
which part to be removed, set prefix
to the
part to be removed:
w1levels <- mod_levels(w = c("w1group2", "w1group3"), fit = fit, prefix = "w1") w1levels
By default, the group with 0s on all dummy variables is
labelled Reference
because its name cannot be determined
from the names of the dummy variables.
The label can be changed by setting reference_group_label
:
w1levels <- mod_levels(w = c("w1group2", "w1group3"), fit = fit, prefix = "w1", reference_group_label = "group1") w1levels
The output can then be used in cond_indirect_effects()
:
out <- cond_indirect_effects(wlevels = w1levels, x = "x", y = "y", m = "m1", fit = fit) out
To have full control on the labels and coding, use values
and supply a named list of numeric vectors:
the name is the group label and the vector is the coding:
w1levels <- mod_levels(w = c("w1group2", "w1group3"), fit = fit, values = list(group1 = c(0, 0), group2 = c(1, 0), group3 = c(0, 1))) w1levels
Numeric and categorical moderators can be mixed but they
need to be generated separately and then merged by
merge_mod_levels()
.
Using the example in the previous section, pretending that
x
is a numeric moderator:
xlevels <- mod_levels(w = "x", fit = fit, sd_from_mean = c(-1, 1)) xlevels w1levels <- mod_levels(w = c("w1group2", "w1group3"), fit = fit, prefix = "w1", reference_group_label = "group1") w1levels wlevels_all <- merge_mod_levels(xlevels, w1levels) wlevels_all
The function mod_levels()
and mod_levels_list()
usually can determine the type correctly. However,
if the detected type is wrong or users want to
specify explicitly the type, set the argument w_type
to either "numeric"
or "categorical"
.
For further information on mod_levels()
,
mod_levels_list()
, and merge_mod_levels()
,
please refer to their help pages.
Cheung, S. F., & Cheung, S.-H. (2023). manymome: An R package for computing the indirect effects, conditional effects, and conditional indirect effects, standardized or unstandardized, and their bootstrap confidence intervals, in many (though not all) models. Behavior Research Methods. https://doi.org/10.3758/s13428-023-02224-z
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.