Error when using emmeans() on a lavaan() object

231 views
Skip to first unread message

Fabio

unread,
Nov 22, 2023, 8:39:51 AM11/22/23
to lavaan
Hi everyone, 

I am running a path analysis in lavaan that looks like this:

model <- ''
 DV ~ 
 Covariate1 + Covariate2 + Covariate3 + 
 Predictor0 + Predictor1 + Predictor2 + Predictor3 + Predictor4 +  
 Predictor1:Predictor3 + Predictor1:Predictor4 +
 Predictor2:Predictor3 + Predictor2:Predictor4 +
 Predictor1:Covariate1 + Predictor2:Covariate1 +
 Predictor3:Covariate1 + Predictor4:Covariate1 +
 Predictor1 ~~ Covariate4
 Predictor2 ~~ Covariate4
 Predictor3 ~~ Covariate4
 Predictor4 ~~ Covariate4
'''
model_fit <- sem(model, data = d, missing = "fiml", estimator = "MLR")


The model runs without problems. However, when I try to estimate marginal effects for the Predictor1×Covariate1 interaction using emmeans, I get an error:

Covariate1_range <- range(d$Covariate1)
Predictor1_range <- range(d$Predictor1)

model_fit_marg <- emmeans(
  model_fit,
  ~ Predictor1 | Covariate1,
  at = list(
    Covariate1 = Covariate1_range,
    Predictor1 = Predictor1_range
  ),
  data = d,
  lavaan.DV = "DV" )

Error in names(temp_bhat) <- c(par_names, colnames(emmb$V)[!colnames(emmb$V) %in% : 'names' attribute [21] must be the same length as the vector [17]


Note that Covariate1 is num [1:2] 0 1.

Hope that someone can help me!

Simon Harmel

unread,
Nov 22, 2023, 9:02:25 AM11/22/23
to lav...@googlegroups.com
Are you sure that emmeans supports lavaan models?

--
You received this message because you are subscribed to the Google Groups "lavaan" group.
To unsubscribe from this group and stop receiving emails from it, send an email to lavaan+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/lavaan/828321cc-eda7-4c33-bcbf-6c9252d78693n%40googlegroups.com.

Fabio

unread,
Nov 22, 2023, 9:07:27 AM11/22/23
to lavaan
Yes, I have used it multiple times with no issues (also, the emmeans() function has a lavaan.DV argument).

I haven't experienced anything like this before, which makes me think that it may have something to do with my model specification, but I can't figure out what...

J Pap

unread,
Nov 22, 2023, 7:11:29 PM11/22/23
to lavaan
Hi!

I show this conversation and I wanted to ask a question that you might have some experience on. 
In my analysis I am using margins and prediction package in R to estimate marginal effects and make some point estimates from a polynomial regression

z = x + y + x2 + xy + y2

Reg <- lm(Predicted ~  Xa + Ya + I(Xa^2) + Xa*Ya, data=dat)
library("margins")
library("prediction")
Margins1 <- margins(Reg, at = list(Xa = 5, Ya= 5), vce = "simulation",iterations = 1000)
Point1<-prediction(Reg, at = list(Xa = 5, Ya = 5),type = "response")
summary(Margins1)
summary(Point1)

However, I would like to try using a measurement model instead of just an average. Thus, I am thinking of using a SEM
reg <- '
   #measurement
   Predicted =~Z1 + Z2 + Z3
   Xa=~X1+ X2
   Ya=~Y1+ Y2
   #path
   Predicted ~  Xa + Ya + I(Xa^2) + Xa*Ya
  '
Reg_fit<- sem(reg, data = dat, estimator = "MLR")

Do you know how I can replicate the margins and prediction in the SEM - lavaan environment? Thank you very much for your help.

Best,
J

Simon Harmel

unread,
Nov 22, 2023, 9:52:50 PM11/22/23
to lav...@googlegroups.com
For clarity,  `lavaan.DV=` is NOT an argument from emeans() really, it is from `semTools::emm_basis.lavaan` which has written extensions (`semTools::emm_basis.lavaan` and  semTools::recover_data.lavaan) for lavaan to connect with the emmeans() package. All of this means that it's possible that you should address your question to the author of the `semTools` not emmeans().

Just a quick check, though, is your Covariate1 a binary variable that takes only 0 or 1? If yes, then by default emmeans takes such a binary variable to be a factor not a numeric/continuous variable and likely you don't need to use it in `at=`. see the last example here: https://search.r-project.org/CRAN/refmans/semTools/html/lavaan2emmeans.html


Terrence Jorgensen

unread,
Nov 23, 2023, 4:28:26 AM11/23/23
to lavaan
`lavaan.DV=` is NOT an argument from emeans() really, it is from `semTools::emm_basis.lavaan` which has written extensions (`semTools::emm_basis.lavaan` and  semTools::recover_data.lavaan) for lavaan to connect with the emmeans() package

Indeed, thanks for pointing out the necessity to load the semTools library.  Also, some issues with missing data and with groups of equal size have been resolved in the development version, so make sure you have the latest installed:

remotes::install_github("simsem/semTools/semTools")

If the problem persists, a full reprex (i.e., with some data) would help me track down the issue.

Terrence D. Jorgensen
Assistant Professor, Methods and Statistics
Research Institute for Child Development and Education, the University of Amsterdam

Fabio

unread,
Nov 23, 2023, 5:13:10 AM11/23/23
to lavaan
Thank you both. We are at the very edge of my technical skills here, so pardon my obtuseness.

Covariate1 does indeed only take 0 or 1. However, removing the 'at = ' doesn't help much.

Installing the development version of semTools works in the sense that I now get a different error:

Error in X[ii, ii, drop = FALSE] %*% y[ii] : non-conformable arguments

This error is independent of which data I use.

All the best,
F.

Terrence Jorgensen

unread,
Nov 24, 2023, 5:18:32 AM11/24/23
to lavaan
An error message is not a reproducible example.  I am able to run all the ?lavaan2emmeans help-page examples.  If you can provide an example that I can reproduce your error, I might be able to investigate.

e.s.tw...@gmail.com

unread,
May 22, 2024, 9:46:43 AM5/22/24
to lavaan
Hi all, 

I run into exactly the same error and I can't figure out what I am doing wrong. I created a snapshot of the data so that my error can be reproduced:

library(lavaan)
library(semTools)

data <- data.frame ( bls_math_err_8 = c(24, 6, 24, 22, NA, 16, 15, 15, 14, 9, 22, 15, 11, 17, 19, NA, 7, 13, NA, 19),
                     bls_read_word_err_8 = c(NA, 2, 3, 18, 48, 4, 16, NA, 11, 8, 0, 2, 48, 2, 1, 24, 15, 16, 7, 5),
                     bls_read_cont_err_8 = c(12, NA, 0, 156, 156, 10, NA, 27, 12, 6, 5, 0, 156, 10, 4, 112, 24, 20, 15, 11),
                     bls_pseudo_err_8 = c(13, 4, 14, 31, 8, NA, 14, 11, 12, 9, 8, NA, 31, 8, 6, 29, 17, 22, 14, 7),
                     GA = c(31, 32, 30, 30, 30, 35, 28, 33, 27, 30, 35, 26, 28, 30, 26, 32, NA, 31, 30, 33),
                     cntxt_adv_trans = c(-0.66, -0.66, -0.35, -0.66, 0.13, 1.33, -2.04, -0.09, -0.09, -0.35, -2.04, -1.07, -0.35, -2.04, 1.04, 1.60, NA, 0.34, 0.88, 2.64),
                     sex = c(1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1),
                     Group_Home_05 = c(NA, 1, 1, 1, NA, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0) )

model1 <- 'acad  =~ bls_math_err_8 + bls_read_word_err_8 + bls_read_cont_err_8 + bls_pseudo_err_8
           acad ~ GA + cntxt_adv_trans + GA:cntxt_adv_trans + sex + Group_Home_05 + Group_Home_05:GA
           GA ~~ cntxt_adv_trans + 0*GA:cntxt_adv_trans + 0*sex + 0*Group_Home_05
           cntxt_adv_trans ~~ 0*GA:cntxt_adv_trans + 0*sex + 0*Group_Home_05'
fit <- sem(model1, data=data, missing="fiml.x", fixed.x=FALSE)
(mylist <- list(GA=seq(23,42, by=1), Group_Home_05=1:0))
em.acad <- emmeans(fit, specs = ~ GA | Group_Home_05,
                   at = mylist,
                   # because SEMs can have multiple DVs:
                   lavaan.DV = "acad")
emmip(em.acad, Group_Home_05 ~ GA, at=mylist, CIs=TRUE)
em2 <- emmip(em.acad, Group_Home_05 ~ GA, at=mylist, CIs=TRUE, plotit=FALSE)

I get the following error when running emmeans() :
Error in names(temp_bhat) <- c(par_names, colnames(emmb$V)[!colnames(emmb$V) %in% : 'names' attribute [8] must be the same length as the vector [7]

Note: sem() also gives a warning about large variance for this small subset of the data, but I do not get this warning when running the code on my full database, so this is likely unrelated to the error above.

Any help would be greatly appreciated!

Best wishes,
Sabrina

Op vrijdag 24 november 2023 om 10:18:32 UTC schreef Terrence Jorgensen:

e.s.tw...@gmail.com

unread,
May 23, 2024, 6:58:06 AM5/23/24
to lavaan
I solved the issue, so I thought I post the solution:

I was easy in the end: the error disappeared after adding nuisance = c("GA:cntxt_adv_trans", "sex") to emmeans().
 
Another mistake I made was that I had not included cntxt_adv_trans in my list. This variable is not part of the interaction that I wanted to plot, but it should also not be specified as nuisance because my model estimates GA ~~ cntxt_adv_trans.

Corrected code in case it is helpful to anyone:
model1 <- 'acad =~ math_err_r + read_w_err_r + read_c_err_r + pseudo_err_r
           acad ~ GA + cntxt_adv_trans + GA:cntxt_adv_trans + sex + Group_Home_05 + GA:Group_Home_05

           GA ~~ cntxt_adv_trans + 0*GA:cntxt_adv_trans + 0*sex + 0*Group_Home_05
           cntxt_adv_trans ~~ 0*GA:cntxt_adv_trans + 0*sex + 0*Group_Home_05'
fit1 <- sem(model1, data=data, missing="fiml.x", fixed.x = FALSE)
(mylist <- list(GA=seq(23,42, by=1), Group_Home_05=1:0, cntxt_adv_trans=c(cntxt_low, cntxt_high)))
em.acad <- emmeans(fit1, specs = ~ GA | Group_Home_05, nuisance = c("GA:cntxt_adv_trans", "sex"),

at = mylist,
# because SEMs can have multiple DVs:
lavaan.DV = "acad")
emmip(em.acad, Group_Home_05 ~ GA, at=mylist, CIs=TRUE)
em2 <- emmip(em.acad, Group_Home_05 ~ GA, at=mylist, CIs=TRUE, plotit=FALSE)


Op woensdag 22 mei 2024 om 14:46:43 UTC+1 schreef e.s.tw...@gmail.com:
Reply all
Reply to author
Forward
0 new messages