Create levels of
moderators to be used by
indirect_effect()
,
cond_indirect_effects()
, and
cond_indirect()
.
Usage
mod_levels(
w,
fit,
w_type = c("auto", "numeric", "categorical"),
w_method = c("sd", "percentile"),
sd_from_mean = c(-1, 0, 1),
percentiles = c(0.16, 0.5, 0.84),
extract_gp_names = TRUE,
prefix = NULL,
values = NULL,
reference_group_label = NULL,
descending = TRUE
)
mod_levels_list(
...,
fit,
w_type = "auto",
w_method = "sd",
sd_from_mean = NULL,
percentiles = NULL,
extract_gp_names = TRUE,
prefix = NULL,
descending = TRUE,
merge = FALSE
)
Arguments
- w
Character. The names of the moderator. If the moderator is categorical with 3 or more groups, this is the vector of the indicator variables.
- fit
The fit object. Can be a lavaan::lavaan object or a list of
lm()
outputs. It can also be alavaan.mi
object returned bysemTools::runMI()
or its wrapper, such assemTools::sem.mi()
. If it is a single model fitted bylm()
, it will be automatically converted to a list bylm2list()
.- w_type
Character. Whether the moderator is a
"numeric"
variable or a"categorical"
variable. If"auto"
, the function will try to determine the type automatically.- w_method
Character, either
"sd"
or"percentile"
. If"sd"
, the levels are defined by the distance from the mean in terms of standard deviation. if"percentile"
, the levels are defined in percentiles.- sd_from_mean
A numeric vector. Specify the distance in standard deviation from the mean for each level. Default is
c(-1, 0, 1)
formod_levels()
. Formod_levels_list()
, the default isc(-1, 0, 1)
when there is only one moderator, andc(-1, 1)
when there are more than one moderator. Ignored ifw_method
is not equal to"sd"
.- percentiles
A numeric vector. Specify the percentile (in proportion) for each level. Default is
c(.16, .50, .84)
formod_levels()
, corresponding approximately to one standard deviation below mean, mean, and one standard deviation above mean in a normal distribution. Formod_levels_list()
, default isc(.16, .50, .84)
if there is one moderator, andc(.16, .84)
when there are more than one moderator. Ignored ifw_method
is not equal to"percentile"
.- extract_gp_names
Logical. If
TRUE
, the default, the function will try to determine the name of each group from the variable names.- prefix
Character. If
extract_gp_names
isTRUE
andprefix
is supplied, it will be removed from the variable names to create the group names. Default isNULL
, and the function will try to determine the prefix automatically.- values
For numeric moderators, a numeric vector. These are the values to be used and will override other options. For categorical moderators, a named list of numeric vector, each vector has length equal to the number of indicator variables. If the vector is named, the names will be used to label the values. For example, if set to
list(gp1 = c(0, 0), gp3 = c(0, 1)
, two levels will be returned, one namedgp1
with the indicator variables equal to 0 and 0, the other namedgp3
with the indicator variables equal to 0 and 1. Default isNULL
.- reference_group_label
For categorical moderator, if the label for the reference group (group with all indicators equal to zero) cannot be determined, the default label is
"Reference"
. To change it, setreference_group_label
to the desired label. Ignored ifvalues
is set.- descending
If
TRUE
(default), the rows are sorted in descending order for numerical moderators: The highest value on the first row and the lowest values on the last row. For user supplied values, the first value is on the last row and the last value is on the first row. IfFALSE
, the rows are sorted in ascending order.- ...
The names of moderators variables. For a categorical variable, it should be a vector of variable names.
- merge
If
TRUE
,mod_levels_list()
will callmerge_mod_levels()
and return the merged levels. Default isFALSE
.
Value
mod_levels()
returns a
wlevels
-class object which is a
data frame with additional attributes
about the levels.
mod_levels_list()
returns a list of
wlevels
-class objects, or a
wlevels
-class object which is a
data frame of the merged levels if
merge = TRUE
.
Details
It creates values of a moderator that can be used to compute conditional effect or conditional indirect effect. By default, for a numeric moderator, it uses one standard deviation below mean, mean, and one standard deviation above mean. The percentiles of these three levels in a normal distribution (16th, 50th, and 84th) can also be used. For categorical variable, it will simply collect the unique categories in the data.
The generated levels are then used by
cond_indirect()
and
cond_indirect_effects()
.
If a model has more than one
moderator, mod_levels_list()
can be
used to generate combinations of
levels. The output can then passed to
cond_indirect_effects()
to compute
the conditional effects or
conditional indirect effects for all
the combinations.
Functions
mod_levels()
: Generate levels for one moderator.mod_levels_list()
: Generate levels for several moderators.
See also
cond_indirect_effects()
for computing conditional
indiret effects; merge_mod_levels()
for merging
levels of moderators.
Examples
library(lavaan)
data(data_med_mod_ab)
dat <- data_med_mod_ab
# Form the levels from a list of lm() outputs
lm_m <- lm(m ~ x*w1 + c1 + c2, dat)
lm_y <- lm(y ~ m*w2 + x + w1 + c1 + c2, dat)
lm_out <- lm2list(lm_m, lm_y)
w1_levels <- mod_levels(lm_out, w = "w1")
w1_levels
#> w1
#> M+1.0SD 6.173157
#> Mean 5.105602
#> M-1.0SD 4.038047
w2_levels <- mod_levels(lm_out, w = "w2")
w2_levels
#> w2
#> M+1.0SD 4.040487
#> Mean 3.047789
#> M-1.0SD 2.055091
# Indirect effect from x to y through m, at the first levels of w1 and w2
cond_indirect(x = "x", y = "y", m = "m",
fit = lm_out,
wvalues = c(w1 = w1_levels$w1[1],
w2 = w2_levels$w2[1]))
#>
#> == Conditional Indirect Effect ==
#>
#> Path: x -> m -> y
#> Moderators: w1, w2
#> Conditional Indirect Effect: 0.398
#> When: w1 = 6.173, w2 = 4.040
#>
#> Computation Formula:
#> (b.m~x + (b.x:w1)*(w1))*(b.y~m + (b.m:w2)*(w2))
#>
#> Computation:
#> ((-0.66304) + (0.20389)*(6.17316))*((-0.14996) + (0.20267)*(4.04049))
#>
#> Coefficients of Component Paths:
#> Path Conditional Effect Original Coefficient
#> m~x 0.596 -0.663
#> y~m 0.669 -0.150
#>
# Can form the levels based on percentiles
w1_levels2 <- mod_levels(lm_out, w = "w1", w_method = "percentile")
w1_levels2
#> w1
#> 84% 6.207972
#> 50% 5.215974
#> 16% 3.932444
# Form the levels from a lavaan output
# Compute the product terms before fitting the model
dat$mw2 <- dat$m * dat$w2
mod <-
"
m ~ x + w1 + x:w1 + c1 + c2
y ~ m + x + w1 + w2 + mw2 + c1 + c2
"
fit <- sem(mod, dat, fixed.x = FALSE)
cond_indirect(x = "x", y = "y", m = "m",
fit = fit,
wvalues = c(w1 = w1_levels$w1[1],
w2 = w2_levels$w2[1]))
#>
#> == Conditional Indirect Effect ==
#>
#> Path: x -> m -> y
#> Moderators: w1, w2
#> Conditional Indirect Effect: 0.398
#> When: w1 = 6.173, w2 = 4.040
#>
#> Computation Formula:
#> (b.m~x + (b.x:w1)*(w1))*(b.y~m + (b.mw2)*(w2))
#>
#> Computation:
#> ((-0.66304) + (0.20389)*(6.17316))*((-0.14996) + (0.20267)*(4.04049))
#>
#> Coefficients of Component Paths:
#> Path Conditional Effect Original Coefficient
#> m~x 0.596 -0.663
#> y~m 0.669 -0.150
#>
# Can pass all levels to cond_indirect_effects()
# First merge the levels by merge_mod_levels()
w1w2_levels <- merge_mod_levels(w1_levels, w2_levels)
cond_indirect_effects(x = "x", y = "y", m = "m",
fit = fit,
wlevels = w1w2_levels)
#>
#> == Conditional indirect effects ==
#>
#> Path: x -> m -> y
#> Conditional on moderator(s): w1, w2
#> Moderator(s) represented by: w1, w2
#>
#> [w1] [w2] (w1) (w2) ind m~x y~m
#> 1 M+1.0SD M+1.0SD 6.173 4.040 0.398 0.596 0.669
#> 2 M+1.0SD Mean 6.173 3.048 0.279 0.596 0.468
#> 3 M+1.0SD M-1.0SD 6.173 2.055 0.159 0.596 0.267
#> 4 Mean M+1.0SD 5.106 4.040 0.253 0.378 0.669
#> 5 Mean Mean 5.106 3.048 0.177 0.378 0.468
#> 6 Mean M-1.0SD 5.106 2.055 0.101 0.378 0.267
#> 7 M-1.0SD M+1.0SD 4.038 4.040 0.107 0.160 0.669
#> 8 M-1.0SD Mean 4.038 3.048 0.075 0.160 0.468
#> 9 M-1.0SD M-1.0SD 4.038 2.055 0.043 0.160 0.267
#>
#> - The 'ind' column shows the conditional indirect effects.
#> - ‘m~x’,‘y~m’ is/are the path coefficient(s) along the path conditional
#> on the moderator(s).
#>
# mod_levels_list() forms a combinations of levels in one call
# It returns a list, by default.
# Form the levels from a list of lm() outputs
# "merge = TRUE" is optional. cond_indirect_effects will merge the levels
# automatically.
w1w2_levels <- mod_levels_list("w1", "w2", fit = fit, merge = TRUE)
w1w2_levels
#> w1 w2
#> w1: M+1.0SD; w2: M+1.0SD 6.173157 4.040487
#> w1: M+1.0SD; w2: M-1.0SD 6.173157 2.055091
#> w1: M-1.0SD; w2: M+1.0SD 4.038047 4.040487
#> w1: M-1.0SD; w2: M-1.0SD 4.038047 2.055091
cond_indirect_effects(x = "x", y = "y", m = "m",
fit = fit, wlevels = w1w2_levels)
#>
#> == Conditional indirect effects ==
#>
#> Path: x -> m -> y
#> Conditional on moderator(s): w1, w2
#> Moderator(s) represented by: w1, w2
#>
#> [w1] [w2] (w1) (w2) ind m~x y~m
#> 1 M+1.0SD M+1.0SD 6.173 4.040 0.398 0.596 0.669
#> 2 M+1.0SD M-1.0SD 6.173 2.055 0.159 0.596 0.267
#> 3 M-1.0SD M+1.0SD 4.038 4.040 0.107 0.160 0.669
#> 4 M-1.0SD M-1.0SD 4.038 2.055 0.043 0.160 0.267
#>
#> - The 'ind' column shows the conditional indirect effects.
#> - ‘m~x’,‘y~m’ is/are the path coefficient(s) along the path conditional
#> on the moderator(s).
#>
# Can work without merge = TRUE:
w1w2_levels <- mod_levels_list("w1", "w2", fit = fit)
w1w2_levels
#> [[1]]
#> w1
#> M+1.0SD 6.173157
#> M-1.0SD 4.038047
#>
#> [[2]]
#> w2
#> M+1.0SD 4.040487
#> M-1.0SD 2.055091
#>
cond_indirect_effects(x = "x", y = "y", m = "m",
fit = fit, wlevels = w1w2_levels)
#>
#> == Conditional indirect effects ==
#>
#> Path: x -> m -> y
#> Conditional on moderator(s): w1, w2
#> Moderator(s) represented by: w1, w2
#>
#> [w1] [w2] (w1) (w2) ind m~x y~m
#> 1 M+1.0SD M+1.0SD 6.173 4.040 0.398 0.596 0.669
#> 2 M+1.0SD M-1.0SD 6.173 2.055 0.159 0.596 0.267
#> 3 M-1.0SD M+1.0SD 4.038 4.040 0.107 0.160 0.669
#> 4 M-1.0SD M-1.0SD 4.038 2.055 0.043 0.160 0.267
#>
#> - The 'ind' column shows the conditional indirect effects.
#> - ‘m~x’,‘y~m’ is/are the path coefficient(s) along the path conditional
#> on the moderator(s).
#>