--- 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