--- title: "Plotting mediation effects and contrasts" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Plotting mediation effects and contrasts} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- The four plotting functions return editable `ggplot` objects and retain the plotted estimates and interval limits in `p$data`. Set `standardized = TRUE` to use the standardized results already requested during fitting. With `ci_method = "both"`, use `engine = "mc"` or `engine = "boot"` consistently. For a single engine, the stored engine is used automatically. ## Reproducible two-condition data ``` r set.seed(918) n <- 350 w <- rnorm(n, 3, 2) avg1 <- rnorm(n); avg2 <- rnorm(n) dm1 <- 2 + .8*w + rnorm(n) dm2 <- 1 + .4*w + .3*dm1 + rnorm(n) dy <- .5 + .6*w + .5*dm1 + .7*dm2 + .2*dm1*w + .3*avg1 + rnorm(n) y1 <- rnorm(n) dat <- data.frame(M11=avg1-dm1/2, M12=avg1+dm1/2, M21=avg2-dm2/2, M22=avg2+dm2/2, Y1=y1, Y2=y1+dy, W=w) dat$Group <- cut(w, c(-Inf,2,4,Inf), labels=c("A","B","C")) fit_args <- list(data=dat, M_C1=c("M11","M21"), M_C2=c("M12","M22"), Y_C1="Y1", Y_C2="Y2", form="P", Na="DE", ci_method="mc", R=2000, seed=2026, standardized=TRUE, verbose=FALSE) plain <- do.call(wsMed, fit_args) continuous <- do.call(wsMed, c(fit_args, list(W="W", W_type="continuous", MP=c("b1","d1")))) categorical <- do.call(wsMed, c(fit_args, list(W="Group", W_type="categorical", MP=c("b1","d1")))) ``` These separate fits illustrate each plotting interface; changing W from continuous to grouped changes the fitted model and is not a transformation of the original conditional estimates. ## Forest plots `plot_effects()` displays complete indirect effects, their total, the direct effect (`cp`) and the total effect. Choose rows and their display order with `paths`; use a named `labels` vector for readable descriptions. ``` r forest <- plot_effects(plain, standardized=TRUE, paths=c("indirect_1", "indirect_2", "total_indirect", "cp", "total_effect"), labels=c(indirect_1="Via M1", indirect_2="Via M2", total_indirect="Total indirect", cp="Direct", total_effect="Total")) forest ``` ![plot of chunk forest](figure/PlottingEffects-forest-1.png) With a moderator, this forest shows effects at the model reference value (centered continuous W = 0, or the reference category). It does not average conditional effects across W. To display different W levels, use the next plot. ## Conditional effects by group or selected level ``` r group_plot <- plot_conditional_effects(categorical, standardized=TRUE, paths=c("indirect_1","indirect_2"), labels=c(indirect_1="Via M1",indirect_2="Via M2"), ncol=2) group_plot ``` ![plot of chunk categorical-effects](figure/PlottingEffects-categorical-effects-1.png) Each point and interval belongs to a fitted group. There are no interpolating lines between categories. `levels` can select and reorder group labels. Choose `type = "paths"` for available path coefficients or `type = "overall"` for total indirect and total effects. All panels share their effect axis. The same function can display the stored reference levels of a continuous W: ``` r plot_conditional_effects(continuous, paths="indirect_effect_1", levels=c("-1 SD","0 SD","+1 SD"), standardized=TRUE, labels=c(indirect_effect_1="Via M1")) ``` ![plot of chunk continuous-levels](figure/PlottingEffects-continuous-levels-1.png) The axis includes raw W values. `indirect_1` and `indirect_effect_1` are accepted as aliases when selecting an available indirect effect; the underlying result tables keep their existing identifiers. ## Differences need their own intervals One effect having an interval that excludes zero and another having an interval that includes zero does not establish a difference between them. `plot_contrasts()` displays the difference and its own interval instead. ``` r contrast_plot <- plot_contrasts(categorical, standardized=TRUE, paths=c("indirect_1","indirect_2"), labels=c(indirect_1="Via M1",indirect_2="Via M2"), ncol=2) contrast_plot ``` ![plot of chunk categorical-contrasts](figure/PlottingEffects-categorical-contrasts-1.png) For example, `B - A` means the conditional effect in B minus that in A. With a continuous moderator, the same function compares stored low, mean and high moderator levels. `contrasts` selects exact labels from the result table (also visible in `contrast_plot$data$Contrast`). Conditional contrasts use the already-computed joint-draw contrast intervals, not differences between endpoints of separate intervals. Without a moderator, the plot compares indirect paths with one another: ``` r plot_contrasts(plain, standardized=TRUE) ``` ![plot of chunk path-contrasts](figure/PlottingEffects-path-contrasts-1.png) Here the helper uses stored joint draws and fitted/pooled point estimates. Standardized contrasts are computed with each draw's own endpoint scales before forming percentile intervals. No model is refitted. A moderator fit currently supports contrasts within each effect across groups/levels, not arbitrary contrasts between different indirect paths at a fixed W. For continuous moderators, `type = "overall"` is unavailable unless an overall contrast table is present; specific indirect and path contrasts remain available. ## Conditional curves and their highlighted ranges ``` r plot_moderation_curve(continuous, "total_indirect", standardized=TRUE) ``` ![plot of chunk curve](figure/PlottingEffects-curve-1.png) The band uses the fitted confidence level. Shading denotes stored grid values whose pointwise interval excludes zero. Labels give raw W bounds, not sample percentiles. Boundaries are grid approximations; they are not exact Johnson--Neyman boundaries or simultaneous confidence regions. An adjacent change from a negative to a positive interval breaks a highlighted range. ## Inspect and export ``` r forest$data[, c("Path","Estimate","CI.LL","CI.UL")] #> Path Estimate CI.LL CI.UL #> 16 indirect_1 1.8547450 1.7256431 1.9948219 #> 17 indirect_2 1.0906147 0.9887227 1.1976153 #> 18 total_indirect 2.9453597 2.7781650 3.1264568 #> 1 cp -0.7473749 -0.8593807 -0.6275049 #> 19 total_effect 2.1979847 2.0356903 2.3746074 attr(forest, "wsmed_plot") #> $engine #> [1] "mc" #> #> $standardized #> [1] TRUE #> #> $level #> [1] 0.95 ``` ``` r ggplot2::ggsave("mediation-effects.pdf", forest, width=8, height=5) ggplot2::ggsave("group-effects.png", group_plot, width=8, height=5, dpi=300) ``` All conditional intervals are percentile intervals; bootstrap parameter forest plots use the stored bootstrap interval type. The common marginal scale, fixed raw W probes and joint uncertainty are described in [Standardized moderated mediation](StandardizedModeratedMediation.html).