
Mediation Analysis for Structural Equation Models
Source:R/rmedsem.R, R/rmedsem_blavaan.R, R/rmedsem_csem.R, and 3 more
rmedsem.RdTests the indirect effect of an independent variable X on a dependent variable Y through a mediator M in a fitted structural equation model (SEM), and determines the type of mediation using the Baron and Kenny (1986) and/or Zhao, Lynch & Chen (2010) approaches. Models estimated with lavaan (covariance-based SEM), cSEM and plssem (PLS-SEM), blavaan (Bayesian SEM) and modsem (models with latent interactions) are supported. The model must contain the regression paths X -> M, M -> Y and X -> Y.
Usage
rmedsem(
mod,
indep,
med,
dep,
approach = c("bk", "zlc"),
p.threshold = 0.05,
effect.size = c("RIT", "RID", "upsilon"),
...
)
# Default S3 method
rmedsem(mod, indep, med, dep, ...)
# S3 method for class 'blavaan'
rmedsem(
mod,
indep,
med,
dep,
approach = c("bk", "zlc"),
p.threshold = 0.05,
effect.size = c("RIT", "RID", "upsilon"),
ci.two.tailed = 0.95,
hdi = FALSE,
...
)
# S3 method for class 'cSEMResults'
rmedsem(
mod,
indep,
med,
dep,
approach = c("bk", "zlc"),
p.threshold = 0.05,
effect.size = c("RIT", "RID", "upsilon"),
nbootstrap = 1000,
ci.two.tailed = 0.95,
seed = NULL,
...
)
# S3 method for class 'lavaan'
rmedsem(
mod,
indep,
med,
dep,
approach = c("bk", "zlc"),
p.threshold = 0.05,
effect.size = c("RIT", "RID", "upsilon"),
standardized = TRUE,
mcreps = 5000,
ci.two.tailed = 0.95,
...
)
# S3 method for class 'modsem'
rmedsem(
mod,
indep,
med,
dep,
approach = c("bk", "zlc"),
p.threshold = 0.05,
effect.size = c("RIT", "RID", "upsilon"),
moderator = NULL,
standardized = TRUE,
mcreps = 5000,
ci.two.tailed = 0.95,
...
)
# S3 method for class 'PlsModel'
rmedsem(
mod,
indep,
med,
dep,
approach = c("bk", "zlc"),
p.threshold = 0.05,
effect.size = c("RIT", "RID", "upsilon"),
mcreps = 5000,
ci.two.tailed = 0.95,
...
)Arguments
- mod
a fitted SEM: an object of class
lavaan,cSEMResults,blavaan,modsemorPlsModel(plssem).blavaanmodels containing latent variables must be fitted withsave.lvs = TRUE;PlsModelobjects must be fitted withbootstrap = TRUE.- indep
a string, the name of the independent variable (X). For
modsemandPlsModelmodels, this can be an interaction term such as"W:X".- med
a string, the name of the mediator (M)
- dep
a string, the name of the dependent variable (Y)
- approach
approach(es) to determine the type of mediation:
"bk"(Baron and Kenny),"zlc"(Zhao, Lynch & Chen), or both (default). Ignored forblavaanmodels.- p.threshold
a number between 0 and 1, the p-value threshold for significance (default 0.05). A p-value equal to the threshold counts as not significant.
- effect.size
character vector with the effect sizes to compute; one or more of
"RIT"(ratio of indirect to total effect),"RID"(ratio of indirect to direct effect) and"upsilon"(Lachowicz et al., 2018); see effect-sizes.- ...
additional arguments passed to methods (currently unused)
- ci.two.tailed
a number between 0 and 1, the level of all confidence (or, for
blavaan, credible) intervals (default 0.95)- hdi
(
blavaan) a logical. IfFALSE(default), equal-tailed credible intervals are computed; ifTRUE, highest density intervals (requires the HDInterval package). Applies to the indirect, direct and total effects and to Upsilon.- nbootstrap
(
cSEM) the number of bootstrap samples (default 1000)- seed
(
cSEM)NULL(default) or a non-negative integer, the seed for the bootstrap. IfNULL, the seed is drawn from R's random number generator, so that results can be reproduced withset.seed().- standardized
(
lavaan,modsem) a logical, whether to use standardized coefficients (defaultTRUE).cSEMandblavaanresults are always standardized.- mcreps
(
lavaan,modsem,PlsModel) the number of Monte-Carlo samples, a positive integer (default 5000). ForPlsModelobjects, only used for MC-PLS models with delta-method standard errors (see section 'Backends').- moderator
(
modsem)NULL(default) or a string, the name of the moderator W for moderated mediation. The model must contain an interaction of the moderator withindepand/ormed.
Value
an object of class c("rmedsem_<pkg>", "rmedsem"), where <pkg>
identifies the backend (lavaan, cSEM, blavaan, modsem or
plssem). See
rmedsem-methods for functions to print, summarize and extract results,
effect-sizes for effect sizes and plot.rmedsem() for plots. The
structure of the object is described in section 'Adding a backend'.
Backends
lavaanThe indirect effect is tested with the Sobel, Delta and Monte-Carlo methods. The Zhao, Lynch & Chen approach is based on the Monte-Carlo test.
cSEMResultsThe model is re-estimated with
nbootstrapbootstrap samples. The indirect effect is tested with the Sobel, Delta and bootstrap methods, and the Zhao, Lynch & Chen approach is based on the bootstrap test. Only single-group, first-order models are supported.blavaanEstimates are based on the (standardized) posterior samples. The output reports posterior means, standard deviations, posterior probabilities of a positive and negative indirect effect, evidence ratios and credible intervals; the Baron and Kenny and Zhao, Lynch & Chen approaches are not applied.
modsemAs for
lavaan. In addition, moderated mediation (viamoderator) and mediated moderation (an interaction term asindep) are supported.PlsModelModels estimated with
plssem::pls()(PLS-SEM and consistent PLSc-SEM, including models with interaction terms and ordinal indicators). The model must be estimated withbootstrap = TRUE; the number of bootstrap samples is set inplssem::pls()(boot.R), and results are reproducible with itsboot.iseedargument. The indirect effect is tested with the Sobel, Delta and bootstrap methods, where the bootstrap test uses the bootstrap samples of plssem. The Zhao, Lynch & Chen approach is based on the bootstrap test. Mediated moderation (an interaction term asindep) is supported. For MC-PLS models (e.g., interaction models with ordinal indicators) estimated with delta-method standard errors (the defaultmc.delta.se = TRUEinplssem::pls()), the bootstrap samples of plssem do not refer to the Monte-Carlo corrected estimates; a Monte-Carlo test based on the estimates and their variance-covariance matrix (mcrepssamples) is used instead of the bootstrap test, also for the Zhao, Lynch & Chen approach. For ordinal indicators, all effects refer to the standardized latent variables.
Multi-group and multilevel models are not supported.
Adding a backend
Support for further model classes is added by writing a method
rmedsem.<class>() that returns a list of class
c("rmedsem_<pkg>", "rmedsem"). For the default print.rmedsem(),
plot.rmedsem() and as.data.frame.rmedsem() methods to work, the list
must contain the following elements:
packagename of the estimating package (character).
standardizedwhether the coefficients are standardized (logical).
varslist with elements
indep,medanddep.est.methodscharacter vector naming the estimation methods for the indirect effect, e.g.
c("sobel", "delta", "montc").- one element per entry in
est.methods a named numeric vector with elements
coef,se,zval,pval,lowerandupper. The Baron and Kenny approach requires the elementsobel.zlc.method(optional) the entry of
est.methodswhose p-value is used for the Zhao, Lynch & Chen approach; defaults to the last entry ofest.methods.direct.effectnamed numeric vector with elements
coef,se,pval,lowerandupper.total.effectnamed numeric vector with elements
coef,se,lowerandupper.med.approachcharacter vector, a subset of
c("bk", "zlc").med.datalist with elements
sig_thresh(the p-value threshold),coefsandpvals; the latter two are lists with elementsmoi(X -> M),dom(M -> Y) anddoi(X -> Y).effect.sizelist with (a subset of) elements
RIT,RIDandupsilon, as returned by the built-in backends.nobs(optional) number of observations, used by
stats::nobs().ci.level(optional) level of the stored intervals, used by
stats::confint()andsummary(); defaults to 0.95.ci.type(optional) label of the stored intervals,
"CI"(default) or"HDI".
A backend whose output does not fit this scheme can provide its own
print.rmedsem_<pkg>() method, either replacing the default output (as
for blavaan) or extending it via NextMethod() (as for modsem).
References
Baron, R. M., & Kenny, D. A. (1986). The moderator-mediator variable distinction in social psychological research: Conceptual, strategic, and statistical considerations. Journal of Personality and Social Psychology, 51(6), 1173–1182. doi:10.1037/0022-3514.51.6.1173
Lachowicz, M. J., Preacher, K. J., & Kelley, K. (2018). A novel measure of effect size for mediation analysis. Psychological Methods, 23(2), 244–261. doi:10.1037/met0000165
Zhao, X., Lynch, J. G., & Chen, Q. (2010). Reconsidering Baron and Kenny: Myths and truths about mediation analysis. Journal of Consumer Research, 37(2), 197–206. doi:10.1086/651257
Examples
## lavaan: observed variables
mod.txt <- "
read ~ math
science ~ read + math
"
mod <- lavaan::sem(mod.txt, data = rmedsem::hsbdemo)
out <- rmedsem(mod, indep = "math", med = "read", dep = "science")
out
#> Significance testing of indirect effect (standardized)
#> Model estimated with package 'lavaan'
#> Mediation effect: 'math' -> 'read' -> 'science'
#>
#> Sobel Delta Monte-Carlo
#> Indirect effect 0.251 0.251 0.251
#> Std. Err. 0.046 0.046 0.046
#> z-value 5.501 5.446 5.453
#> p-value 3.79e-08 5.15e-08 4.95e-08
#> CI [0.161, 0.340] [0.160, 0.341] [0.164, 0.342]
#>
#> Baron and Kenny approach to testing mediation
#> STEP 1 - 'math' -> 'read' (X -> M) with B=0.662 and p<0.001
#> STEP 2 - 'read' -> 'science' (M -> Y) with B=0.378 and p<0.001
#> STEP 3 - 'math' -> 'science' (X -> Y) with B=0.380 and p<0.001
#> As STEP 1, STEP 2 and STEP 3 as well as the Sobel's test above
#> are significant the mediation is partial.
#>
#> Zhao, Lynch & Chen's approach to testing mediation
#> Based on p-value estimated using Monte-Carlo
#> STEP 1 - 'math' -> 'science' (X -> Y) with B=0.380 and p<0.001
#> As the Monte-Carlo test above is significant, STEP 1 is
#> significant and their coefficients point in same direction,
#> there is complementary mediation (partial mediation).
#>
#> Effect sizes
#> RIT = (Indirect effect / Total effect)
#> (0.251/0.631) = 0.397
#> Meaning that about 40% of the effect of 'math'
#> on 'science' is mediated by 'read'
#> RID = (Indirect effect / Direct effect)
#> (0.251/0.380) = 0.659
#> That is, the mediated effect is about 0.7 times as
#> large as the direct effect of 'math' on 'science'
#> Upsilon (v) = Variance in Y explained indirectly by X through M
#> v(unadj) = 0.063, v(adj) = 0.061
#>
# Zhao, Lynch & Chen approach only, unstandardized coefficients
rmedsem(mod, indep = "math", med = "read", dep = "science",
approach = "zlc", standardized = FALSE, mcreps = 5000)
#> Significance testing of indirect effect (unstandardized)
#> Model estimated with package 'lavaan'
#> Mediation effect: 'math' -> 'read' -> 'science'
#>
#> Sobel Delta Monte-Carlo
#> Indirect effect 0.265 0.265 0.265
#> Std. Err. 0.052 0.052 0.053
#> z-value 5.073 5.073 5.050
#> p-value 3.91e-07 3.91e-07 4.41e-07
#> CI [0.163, 0.367] [0.163, 0.367] [0.163, 0.373]
#>
#> Zhao, Lynch & Chen's approach to testing mediation
#> Based on p-value estimated using Monte-Carlo
#> STEP 1 - 'math' -> 'science' (X -> Y) with B=0.402 and p<0.001
#> As the Monte-Carlo test above is significant, STEP 1 is
#> significant and their coefficients point in same direction,
#> there is complementary mediation (partial mediation).
#>
#> Effect sizes
#> RIT = (Indirect effect / Total effect)
#> (0.265/0.667) = 0.397
#> Meaning that about 40% of the effect of 'math'
#> on 'science' is mediated by 'read'
#> RID = (Indirect effect / Direct effect)
#> (0.265/0.402) = 0.659
#> That is, the mediated effect is about 0.7 times as
#> large as the direct effect of 'math' on 'science'
#> Upsilon (v) = Variance in Y explained indirectly by X through M
#> v(unadj) = 0.063, v(adj) = 0.061
#>
# \donttest{
## cSEM
if (requireNamespace("cSEM", quietly = TRUE)) {
model <- "
OwnLook =~ smv_attr_face + smv_attr_body + smv_sexy
SelfEst =~ ses_satis + ses_qualities + ses_able_todo
MentWell =~ mwb_optimistic + mwb_useful + mwb_energy
SelfEst ~ OwnLook
MentWell ~ OwnLook + SelfEst
"
mod <- cSEM::csem(rmedsem::mchoice, model)
# small number of bootstrap samples to keep the example fast
rmedsem(mod, indep = "OwnLook", med = "SelfEst", dep = "MentWell",
nbootstrap = 200)
}
#> Significance testing of indirect effect (standardized)
#> Model estimated with package 'cSEM'
#> Mediation effect: 'OwnLook' -> 'SelfEst' -> 'MentWell'
#>
#> Sobel Delta Bootstrap
#> Indirect effect 0.316 0.316 0.316
#> Std. Err. 0.032 0.033 0.034
#> z-value 9.969 9.475 9.370
#> p-value <2e-16 <2e-16 <2e-16
#> CI [0.254, 0.378] [0.250, 0.381] [0.262, 0.391]
#>
#> Baron and Kenny approach to testing mediation
#> STEP 1 - 'OwnLook' -> 'SelfEst' (X -> M) with B=0.578 and p<0.001
#> STEP 2 - 'SelfEst' -> 'MentWell' (M -> Y) with B=0.546 and p<0.001
#> STEP 3 - 'OwnLook' -> 'MentWell' (X -> Y) with B=0.088 and p=0.075
#> As STEP 1, STEP 2 and the Sobel's test above are significant
#> and STEP 3 is not significant the mediation is complete.
#>
#> Zhao, Lynch & Chen's approach to testing mediation
#> Based on p-value estimated using Bootstrap
#> STEP 1 - 'OwnLook' -> 'MentWell' (X -> Y) with B=0.088 and p=0.075
#> As the Bootstrap test above is significant and STEP 1 is not
#> significant there is indirect-only mediation (full mediation).
#>
#> Effect sizes
#> RIT = (Indirect effect / Total effect)
#> (0.316/0.404) = 0.781
#> Meaning that about 78% of the effect of 'OwnLook'
#> on 'MentWell' is mediated by 'SelfEst'
#> RID = (Indirect effect / Direct effect)
#> RID is not reported: direct effect 0.088 is not significant (p = 0.075)
#> Upsilon (v) = Variance in Y explained indirectly by X through M
#> v(unadj) = 0.100, v(adj) = 0.099
#>
## modsem: mediated moderation and moderated mediation
if (requireNamespace("modsem", quietly = TRUE)) {
m <- "
OwnLook =~ smv_attr_face + smv_attr_body + smv_sexy
SelfEst =~ ses_satis + ses_qualities + ses_able_todo
MentWell =~ mwb_optimistic + mwb_useful + mwb_energy
smv =~ smv_kind + smv_caring + smv_understanding +
smv_make_laughh + smv_funny + smv_sociable
SelfEst ~ OwnLook + smv + smv:OwnLook
MentWell ~ OwnLook + SelfEst + smv + smv:OwnLook
"
est <- modsem::modsem(m, data = rmedsem::mchoice, method = "lms")
# mediated moderation
rmedsem(est, indep = "smv:OwnLook", med = "SelfEst", dep = "MentWell")
# moderated mediation
rmedsem(est, indep = "OwnLook", med = "SelfEst", dep = "MentWell",
moderator = "smv")
}
#> Significance testing of indirect effect (standardized)
#> Model estimated with package 'modsem'
#> Mediation effect: 'OwnLook' -> 'SelfEst' -> 'MentWell'
#>
#> Sobel Delta Monte-Carlo
#> Indirect effect 0.253 0.253 0.253
#> Std. Err. 0.029 0.029 0.029
#> z-value 8.847 8.836 8.715
#> p-value <2e-16 <2e-16 <2e-16
#> CI [0.197, 0.309] [0.197, 0.309] [0.199, 0.311]
#>
#> Baron and Kenny approach to testing mediation
#> STEP 1 - 'OwnLook' -> 'SelfEst' (X -> M) with B=0.486 and p<0.001
#> STEP 2 - 'SelfEst' -> 'MentWell' (M -> Y) with B=0.521 and p<0.001
#> STEP 3 - 'OwnLook' -> 'MentWell' (X -> Y) with B=0.011 and p=0.809
#> As STEP 1, STEP 2 and the Sobel's test above are significant
#> and STEP 3 is not significant the mediation is complete.
#>
#> Zhao, Lynch & Chen's approach to testing mediation
#> Based on p-value estimated using Monte-Carlo
#> STEP 1 - 'OwnLook' -> 'MentWell' (X -> Y) with B=0.011 and p=0.809
#> As the Monte-Carlo test above is significant and STEP 1 is not
#> significant there is indirect-only mediation (full mediation).
#>
#> Effect sizes
#> RIT = (Indirect effect / Total effect)
#> (0.253/0.265) = 0.957
#> Meaning that about 96% of the effect of 'OwnLook'
#> on 'MentWell' is mediated by 'SelfEst'
#> RID = (Indirect effect / Direct effect)
#> RID is not reported: direct effect 0.011 is not significant (p = 0.809)
#> Upsilon (v) = Variance in Y explained indirectly by X through M
#> v(unadj) = 0.064, v(adj) = 0.063
#>
#>
#> Direct moderation effects
#> OwnLook -> SelfEst | smv: B = -0.136, se = 0.029, p = 0.000
#> OwnLook -> MentWell | smv: B = -0.008, se = 0.034, p = 0.813
#>
#> Indirect moderation effect
#> OwnLook -> SelfEst -> MentWell | smv: B = -0.071, se = 0.017, p = 0.000
#>
#> Total moderation effect
#> OwnLook -> MentWell | smv: B = -0.079, se = 0.036, p = 0.026
#>
## plssem (PLS-SEM)
if (requireNamespace("plssem", quietly = TRUE)) {
model <- "
OwnLook =~ smv_attr_face + smv_attr_body + smv_sexy
SelfEst =~ ses_satis + ses_qualities + ses_able_todo
MentWell =~ mwb_optimistic + mwb_useful + mwb_energy
SelfEst ~ OwnLook
MentWell ~ OwnLook + SelfEst
"
# small number of bootstrap samples to keep the example fast
fit <- plssem::pls(model, rmedsem::mchoice, bootstrap = TRUE,
boot.R = 200, boot.iseed = 1)
rmedsem(fit, indep = "OwnLook", med = "SelfEst", dep = "MentWell")
}
#> Significance testing of indirect effect (standardized)
#> Model estimated with package 'plssem'
#> Mediation effect: 'OwnLook' -> 'SelfEst' -> 'MentWell'
#>
#> Sobel Delta Bootstrap
#> Indirect effect 0.316 0.316 0.316
#> Std. Err. 0.031 0.032 0.032
#> z-value 10.152 9.915 9.828
#> p-value <2e-16 <2e-16 <2e-16
#> CI [0.255, 0.377] [0.253, 0.378] [0.261, 0.388]
#>
#> Baron and Kenny approach to testing mediation
#> STEP 1 - 'OwnLook' -> 'SelfEst' (X -> M) with B=0.578 and p<0.001
#> STEP 2 - 'SelfEst' -> 'MentWell' (M -> Y) with B=0.546 and p<0.001
#> STEP 3 - 'OwnLook' -> 'MentWell' (X -> Y) with B=0.088 and p=0.031
#> As STEP 1, STEP 2 and STEP 3 as well as the Sobel's test above
#> are significant the mediation is partial.
#>
#> Zhao, Lynch & Chen's approach to testing mediation
#> Based on p-value estimated using Bootstrap
#> STEP 1 - 'OwnLook' -> 'MentWell' (X -> Y) with B=0.088 and p=0.031
#> As the Bootstrap test above is significant, STEP 1 is
#> significant and their coefficients point in same direction,
#> there is complementary mediation (partial mediation).
#>
#> Effect sizes
#> RIT = (Indirect effect / Total effect)
#> (0.316/0.404) = 0.781
#> Meaning that about 78% of the effect of 'OwnLook'
#> on 'MentWell' is mediated by 'SelfEst'
#> RID = (Indirect effect / Direct effect)
#> (0.316/0.088) = 3.570
#> That is, the mediated effect is about 3.6 times as
#> large as the direct effect of 'OwnLook' on 'MentWell'
#> Upsilon (v) = Variance in Y explained indirectly by X through M
#> v(unadj) = 0.100, v(adj) = 0.099
#>
## blavaan
if (requireNamespace("blavaan", quietly = TRUE)) {
# blavaan's fitting functions need the package to be attached
library(blavaan)
# short single chain to keep the example fast; use more chains and
# iterations in practice
bmod <- bsem(mod.txt, data = rmedsem::hsbdemo, n.chains = 1,
burnin = 500, sample = 500, seed = 1,
bcontrol = list(refresh = 0))
rmedsem(bmod, indep = "math", med = "read", dep = "science")
# highest density intervals instead of equal-tailed intervals
if (requireNamespace("HDInterval", quietly = TRUE))
rmedsem(bmod, indep = "math", med = "read", dep = "science", hdi = TRUE)
}
#> Loading required package: Rcpp
#> This is blavaan 0.6-1
#> On multicore systems, we suggest use of future::plan("multicore") or
#> future::plan("multisession") for faster post-MCMC computations.
#> Computing post-estimation metrics (including lvs if requested)...
#> Significance testing of indirect effect (standardized)
#> Model estimated with package 'blavaan'
#> Mediation effect: 'math' -> 'read' -> 'science'
#>
#> Prior (regression coefs): normal(0,10)
#> Bayes
#> Indirect effect 0.246
#> Posterior SD 0.044
#> P(>0) 1.000
#> P(<0) 0.000
#> ER+ ∞
#> ER- 0
#> HDI [0.172, 0.338]
#>
#> Effect sizes
#> RIT = (Indirect effect / Total effect)
#> (0.246/0.629) = 0.391
#> Meaning that about 39% of the effect of 'math'
#> on 'science' is mediated by 'read'
#> RID = (Indirect effect / Direct effect)
#> (0.246/0.383) = 0.643
#> That is, the mediated effect is about 0.6 times as
#> large as the direct effect of 'math' on 'science'
#> Upsilon (v) = Variance in Y explained indirectly by X through M
#> v(unadj) = 0.061, v(adj) = 0.059
#> Posterior mean(v) = 0.063, median(v) = 0.061
#> 95% HDI [0.024, 0.104]
#>
# }