---
title: "Set Moderator Levels"
author: "Shu Fai Cheung & Sing-Hang Cheung"
date: "`r Sys.Date()`"
output:
rmarkdown::html_vignette:
number_sections: true
vignette: >
%\VignetteIndexEntry{Set Moderator Levels}
%\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{UTF-8}
---
```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>"
)
```
# Introduction
This article is a brief illustration of how
to use `mod_levels()`,
`mod_levels_list()`, and `merge_mod_levels()`
from the package
[manymome](https://sfcheung.github.io/manymome/)
([Cheung & Cheung, 2023](https://doi.org/10.3758/s13428-023-02224-z))
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.
# Numeric Moderators
We first use the sample data set `data_med_mod_ab`:
```{r}
library(manymome)
dat <- data_med_mod_ab
print(head(dat), digits = 3)
```
Suppose this is the model being fitted:
```{r}
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)
```
## SD and Mean
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()`:
```{r}
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:
```{r}
w1levels <- mod_levels(w = "w1", fit = fit,
sd_from_mean = c(-1, 1))
w1levels
```
## Percentiles
To generate the levels based on percentiles, set the
argument `w_method` to `"percentile"`:
```{r}
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:
```{r}
w1levels <- mod_levels(w = "w1", fit = fit,
w_method = "percentile",
percentiles = c(.25, .75))
w1levels
```
## Specific Values
If there are values that are meaningful for a moderator,
they can be used by setting `values` to a vector of values:
```{r}
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()`:
```{r}
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`.
## Merging the Levels of Two Or More Moderators
In the previous example, there are two moderators.
We can
call `mod_levels()` once for each of them, or call
`mod_levels_list()`:
```{r}
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`:
```{r}
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:
```{r}
wlevels_list <- mod_levels_list("w1", "w2", fit = fit,
w_method = "percentile",
percentiles = c(.25, .75),
merge = TRUE)
wlevels_list
```
## Different Settings For Moderators
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()`:
```{r}
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
```
# Categorical Moderators
We use the dataset `data_med_mod_serial_cat` for illustration:
```{r}
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.
## Create Dummy Variables and Fit the Model
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.
```{r}
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:
```{r}
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)
```
## Default Levels
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:
```{r}
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:
```{r}
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`:
```{r}
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()`:
```{r}
out <- cond_indirect_effects(wlevels = w1levels,
x = "x", y = "y", m = "m1",
fit = fit)
out
```
## User-Supplied Levels
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:
```{r}
w1levels <- mod_levels(w = c("w1group2", "w1group3"), fit = fit,
values = list(group1 = c(0, 0),
group2 = c(1, 0),
group3 = c(0, 1)))
w1levels
```
# Mixing Numeric and Categorical Moderators
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:
```{r}
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
```
# Determining The Type of a Moderator
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"`.
# Further Information
For further information on `mod_levels()`,
`mod_levels_list()`, and `merge_mod_levels()`,
please refer to their help pages.
# Reference
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