"x:w ~ z" in the model syntax?

67 views
Skip to first unread message

Shu Fai Cheung (張樹輝)

unread,
Aug 12, 2025, 11:10:22 AMAug 12
to lavaan
Hi All,

Suppose a mediation model with the b-path moderated is fitted:

library(lavaan)
#> This is lavaan 0.6-19
#> lavaan is FREE software! Please report any bugs.

mod <-
"
x2 ~ x1
x3 ~ x2 + x4 + x2:x4 + x1
"

dat <- HolzingerSwineford1939[, paste0("x", 1:9)]

fit1 <- sem(mod,
            dat,
            fixed.x = FALSE)
fit1
#> lavaan 0.6-19 ended normally after 10 iterations
#>
#>   Estimator                                         ML
#>   Optimization method                           NLMINB
#>   Number of model parameters                        11
#>
#>   Number of observations                           301
#>
#> Model Test User Model:
#>                                                      
#>   Test statistic                              1090.398
#>   Degrees of freedom                                 4
#>   P-value (Chi-square)                           0.000
fit2 <- sem(mod,
            dat + 2,
            fixed.x = FALSE)
fit2
#> lavaan 0.6-19 ended normally after 11 iterations
#>
#>   Estimator                                         ML
#>   Optimization method                           NLMINB
#>   Number of model parameters                        11
#>
#>   Number of observations                           301
#>
#> Model Test User Model:
#>                                                      
#>   Test statistic                              1289.517
#>   Degrees of freedom                                 4
#>   P-value (Chi-square)                           0.000

This model syntax does not work because the model is not invariant to linear transformation of the variables. This is a known issue, and we need to free the covariance between the interaction term interaction x2:x4 and the error term of x2, the mediator, among some other covariances fixed by lavaan to zero.

The following syntax will work. Other covariances need to be specified manually because we manually free the covariance between the interaction term and an error term:

modb <-
"
x2 ~ x1
x3 ~ x2 + x4 + x2:x4 + x1
x1 ~~ x4 + x2:x4
x4 ~~ x2 + x2:x4
x2 ~~ x2:x4
"

fitb1 <- sem(modb,
             dat,
             fixed.x = FALSE)
fitb1
#> lavaan 0.6-19 ended normally after 75 iterations
#>
#>   Estimator                                         ML
#>   Optimization method                           NLMINB
#>   Number of model parameters                        15
#>
#>   Number of observations                           301
#>
#> Model Test User Model:
#>                                                      
#>   Test statistic                                 0.000
#>   Degrees of freedom                                 0

The model is a saturated model, as it should be.

However, an error will be raised if the interaction term "x2:x4" appears on the left-hand side, "x2:x4 ~~ x2" in the following example:

modc <-
"
x2 ~ x1
x3 ~ x2 + x4 + x2:x4 + x1
x1 ~~ x4 + x2:x4
x4 ~~ x2 + x2:x4
x2:x4 ~~ x2
"

fitc1 <- sem(modc,
             dat,
             fixed.x = FALSE)
#> Error: lavaan->ldw_parse_model_string():  
#>    Invalid block identifier. The correct syntax is: "LHS: RHS", where LHS is
#>    a block identifier (eg group or level), and RHS is the group/level/block
#>    number or label. at line 5, pos 1
#> x2:x4 ~~ x2
#> ^

For this particular model, the problem can be solved by not placing the interaction term on the left-hand side.

However, is there any workaround or unofficial "trick" to specify an interaction term on the left-hand side without resulting in this error?

I have this question because what I want to fit is a more complicated model with more than one interaction term, and I will need to free a covariance like "x2:x4 ~~ x3:x5".

This error can be avoided by forming the interaction terms in the data directly, e.g., x2_x4 <- x2 * x4 and x3_x5 <- x3 * x5, and not using ":". However, for some reason, I would like to use ":", if this is possible.

-- Shu Fai

Shu Fai Cheung (張樹輝)

unread,
Aug 12, 2025, 8:37:27 PMAug 12
to lavaan
Oh, I found a typo in my title. I meant "x:w ~~ z", a covariance, not a regression coefficient. Sorry for the confusion caused.

Regards,
Shu Fai

Terrence Jorgensen

unread,
Aug 14, 2025, 4:58:50 AMAug 14
to lavaan
an error will be raised if the interaction term "x2:x4" appears on the left-hand side

Indeed, I think without a preceding operator, the parser interprets any label-like text followed by a colon as introducing a block, which then runs into problems when another operator is found before the end of the line.  I noticed this when working offline to answer this question, but I forgot to post the issue on GitHub.  Would you have time to open an issue here, using your example?


FYI, although you can avoid this issue in your example (using "x2 ~~ x2:x4"), the issue becomes unavoidable when you need to free correlations between products with multiple moderators.  So if x2's effect were moderated not only by x4 but also x5, you would want to estimate the "x2:x4 ~~ x2:x5" correlation, but that specification can't work in either LHS-RHS order.  Currently, it requires the user to manually calculate product terms to include in the model.  Manually calculating product variables is also necessary with higher-order interactions (i.e., the parser will not interpret multiple colons that way).  

Terrence D. Jorgensen    (he, him, his)
Assistant Professor, Methods and Statistics
Research Institute for Child Development and Education, the University of Amsterdam
http://www.uva.nl/profile/t.d.jorgensen


Shu Fai Cheung (張樹輝)

unread,
Aug 15, 2025, 8:12:37 AMAug 15
to lavaan
Thanks for your suggestion. I opened an issue based on my original post:

https://github.com/yrosseel/lavaan/issues/434

I am not familiar with the (new) lavaan parser functions, but I am trying to suggest a fix that, hopefully, can allow for  "x2:x4 ~~ x2:x5"  and  "x2:x4 ~~ x2" without changing lavaan syntax rules. I will share that on GitHub. 

-- Shu Fai
Reply all
Reply to author
Forward
0 new messages