--- title: "User-defined mediation models with GenerateModelCustom" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{User-defined mediation models with GenerateModelCustom} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ## Introduction `GenerateModelCustom()` generates `lavaan` syntax for a user-defined two-condition within-subject mediation model. It is useful when the intended mediator structure cannot be represented by one of the predefined parallel, chained, chained--parallel, or parallel--chained models in `wsMed`. Users specify directed paths among mediators and from mediators to the outcome. For example: ``` r custom_paths <- c( "M1 -> M3", "M3 -> Y", "M2 -> Y" ) ``` Here, `M1`, `M2`, and `M3` denote the mediators, and `Y` denotes the outcome. The user does not specify paths beginning with `X`. The function automatically adds an \(a_i\) path from the within-subject condition to every mediator and the direct effect \(cp\) from the condition to the outcome. ## Mediator numbering Mediator labels are assigned according to the order of the variables supplied to `M_C1` and `M_C2`. For example: | Construct | Condition 1 | Condition 2 | Model label | |:----------|:------------|:------------|:------------| | A | `A1` | `A2` | `M1` | | B | `B1` | `B2` | `M2` | | C | `C1` | `C2` | `M3` | | D | `D1` | `D2` | `Y` | Therefore, `"M1 -> M3"` represents a path from construct A to construct C. Mediator numbering identifies variables; it does not determine path direction. ## Preparing example data The following reproducible example creates three mediator pairs and one outcome pair. It does not depend on an external data file. ``` r set.seed(123) n <- 200 example_custom <- data.frame( A1 = rnorm(n), A2 = rnorm(n, mean = 0.30), B1 = rnorm(n), B2 = rnorm(n, mean = 0.20), C1 = rnorm(n), C2 = rnorm(n, mean = 0.25), D1 = rnorm(n), D2 = rnorm(n, mean = 0.35) ) ``` `PrepareData()` converts the raw condition-specific variables into mediator difference and centered level components and an outcome difference score. ``` r prepared_data <- PrepareData( data = example_custom, M_C1 = c("A1", "B1", "C1"), M_C2 = c("A2", "B2", "C2"), Y_C1 = "D1", Y_C2 = "D2" ) names(prepared_data) #> [1] "Ydiff" "M1diff" "M2diff" "M3diff" "M1avg" "M2avg" "M3avg" ``` For mediator \(M_i\), the two components are \[ M_{i,\mathrm{diff}} = M_{i2} - M_{i1} \] and \[ M_{i,\mathrm{avg}} = \frac{M_{i1} + M_{i2}}{2}, \] where the average component is centered by `PrepareData()`. ## Specifying a custom model Each element of `paths` must describe either a mediator-to-mediator path or a mediator-to-outcome path: ``` r custom_paths <- c( "M1 -> M3", "M3 -> Y", "M2 -> Y" ) ``` Spaces around `->` are optional. For example, `"M1 -> M3"` and `"M1->M3"` are equivalent. The corresponding model syntax is generated as follows: ``` r custom_model <- GenerateModelCustom( prepared_data = prepared_data, paths = custom_paths ) cat(custom_model) #> Ydiff ~ cp*1 + b2*M2diff + d2*M2avg + b3*M3diff + d3*M3avg #> M1diff ~ a1*1 #> M2diff ~ a2*1 #> M3diff ~ a3*1 + b_1_3*M1diff + d_1_3*M1avg #> indirect_1_3 := a1 * b_1_3 * b3 #> indirect_2 := a2 * b2 #> indirect_3 := a3 * b3 #> total_indirect := indirect_1_3 + indirect_2 + indirect_3 #> total_effect := cp + total_indirect ``` For every specified structural edge, the generated regression includes both the difference and level components of the predictor mediator. Thus, `"M1 -> M3"` contributes ```r b_1_3*M1diff + d_1_3*M1avg ``` to the regression equation for `M3diff`. Only specified structural paths are added. Because `"M1 -> Y"` is absent from `custom_paths`, `M1diff` and `M1avg` do not appear directly in the regression equation for `Ydiff`. ## Indirect effects `GenerateModelCustom()` identifies every directed path from a mediator to `Y`. The model above contains three indirect effects: \[ \mathtt{indirect\_1\_3} = \mathtt{a1}\, \mathtt{b\_1\_3}\, \mathtt{b3}, \] \[ \mathtt{indirect\_2} = \mathtt{a2}\, \mathtt{b2}, \] \[ \mathtt{indirect\_3} = \mathtt{a3}\, \mathtt{b3}. \] The last effect exists because the path from the condition to every mediator, including \(M_3\), is added automatically. All identified indirect effects are summed to form `total_indirect`, and the total effect is defined as `cp + total_indirect`. ## Parameter labels The generated model uses the following labels: | Path | Difference component | Level component | |:-----|:---------------------|:----------------| | \(X \rightarrow M_i\) | `ai` | -- | | \(M_i \rightarrow Y\) | `bi` | `di` | | \(M_j \rightarrow M_i\) | `b_j_i` | `d_j_i` | | \(X \rightarrow Y\) | `cp` | -- | For example, the path \(M_1 \rightarrow M_3\) uses `b_1_3` and `d_1_3`, whereas \(M_3 \rightarrow Y\) uses `b3` and `d3`. ## Fitting the complete model with wsMed For an applied analysis, users can pass the same path specification directly to `wsMed()` by setting `form = "UD"`. The following chunk is not evaluated while the vignette is knitted because Monte Carlo confidence intervals can take some time. Remove `eval=FALSE` to run it. ``` r result_custom <- wsMed( data = example_custom, M_C1 = c("A1", "B1", "C1"), M_C2 = c("A2", "B2", "C2"), Y_C1 = "D1", Y_C2 = "D2", form = "UD", paths = custom_paths, Na = "DE", ci_method = "mc", R = 5000, standardized = TRUE, seed = 123 ) print(result_custom) ``` ## Input requirements A valid custom path specification must meet the following requirements: 1. Each path must use a form such as `"M1 -> M2"` or `"M2 -> Y"`. 2. Every referenced mediator must be present in `prepared_data`. 3. Duplicate paths and self-loops such as `"M1 -> M1"` are not allowed. 4. The mediator structure must be acyclic. 5. At least one mediator must have a path ending in `Y`. Paths beginning with `X`, such as `"X -> M1"` or `"X -> Y"`, should not be included because these paths are added automatically. Paths beginning with `Y` are not permitted because `Y` is the final outcome. ## Summary To fit a user-defined model: 1. Supply matched mediator variables through `M_C1` and `M_C2`. 2. Define the structural edges using mediator labels and `Y`. 3. Use `GenerateModelCustom()` to inspect the generated syntax or call `wsMed(form = "UD", paths = ...)` for the complete analysis. This workflow retains the existing difference-and-level parameterization in `wsMed` while allowing users to specify mediation structures beyond the four predefined model forms. ## Standardized moderated custom models The same endpoint scaling applies to a sparse user-defined model. Only paths present in `paths` can be requested in `MP`. For the model above, `b_1_3` and `b3` exist, whereas `b1` does not. ``` r set.seed(321) example_custom$W <- rnorm(nrow(example_custom)) custom_moderated <- wsMed( data = example_custom, M_C1 = c("A1", "B1", "C1"), M_C2 = c("A2", "B2", "C2"), Y_C1 = "D1", Y_C2 = "D2", form = "UD", paths = c("M1 -> M3", "M3 -> Y", "M2 -> Y"), W = "W", W_type = "continuous", MP = c("b_1_3", "b3"), Na = "DE", ci_method = "mc", R = 2000, seed = 321, standardized = TRUE, verbose = FALSE ) head(custom_moderated$moderation_std$beta_coef) #> Path Mediators Level W_value Estimate SE 2.5.%CI.Lo 97.5.%CI.Up Sig #> 1 indirect_effect_1_3 1 3 -1 SD -0.930 -0.00171108 0.00930085 -0.02141640 0.01760392 #> 2 indirect_effect_1_3 1 3 0 SD 0.004 -0.00246412 0.00323804 -0.01037716 0.00255513 #> 3 indirect_effect_1_3 1 3 +1 SD 0.937 -0.00091161 0.00258922 -0.00743724 0.00315255 #> 4 indirect_effect_2 2 -1 SD -0.930 -0.00419233 0.01070311 -0.03017033 0.01513924 #> 5 indirect_effect_2 2 0 SD 0.004 -0.00424159 0.00918899 -0.02724825 0.01246020 #> 6 indirect_effect_2 2 +1 SD 0.937 -0.00429085 0.01089494 -0.03130748 0.01468530 custom_moderated$moderation_std$conditional_overall #> Effect Level W_value Estimate SE 2.5.%CI.Lo 97.5.%CI.Up Sig #> 1 total_indirect -1 SD -0.930 -0.00084796 0.02190236 -0.04624817 0.04603392 #> 3 total_indirect 0 SD 0.004 0.00807649 0.01717070 -0.02427926 0.04448637 #> 5 total_indirect +1 SD 0.937 0.01598798 0.02552867 -0.02705751 0.07551097 #> 2 total_effect -1 SD -0.930 0.22931289 0.09962514 0.03219760 0.42551819 * #> 4 total_effect 0 SD 0.004 0.32274183 0.07074161 0.18614681 0.46708409 * #> 6 total_effect +1 SD 0.937 0.41515782 0.10004355 0.21574178 0.61416485 * ``` The total indirect effect includes every complete path in this model, including paths without a requested interaction. Moderator main effects already fitted in the mediator and outcome regressions enter conditional intercepts even though `a` and `cp` were not requested in `MP`. See [Standardized moderated mediation](StandardizedModeratedMediation.html) for raw-unit probing, categorical coding and uncertainty in the scale factors.