simsem / semTools

Useful tools for structural equation modeling
75 stars 36 forks source link

Error in fitMeasures after run.mi #134

Closed Sara-SEM closed 1 month ago

Sara-SEM commented 9 months ago

Hello everyone,

I am runnning a SEM model based on imputed data. The code (see below) worked without any problems till approx. September 2023 (R version 4.2). Now I switched to the latest R version (4.3.0), lavaan (version: 0.6-11.1676), semTools (version: 0.5-6 ) and get this error:

Error in fitMeasures(object, fit.measures = indices, output = "text", : could not find symbol "fm.args" in the environment of the generic function

Sadly I can´t run my syntax anymore with the current install and can´t replicate my research.

I would be very grateful for any help and hope I posted the necessary information Sara

Installed: install.packages("devtools") install.packages("lavaan", repos = "http://www.da.ugent.be", type = "source") install.packages("mice") install.packages("semTools")

CODE:


MyData <- read.spss("Data", to.data.frame = TRUE,
                    # if you plan to treat Likert items as ordinal or numeric:
                    use.value.labels = FALSE)

#####imputation
dataimp1 <- mice(MyData, m=25, seed=12345, max =10)
mice.imp1 <- NULL
m=25
for(i in 1:m) {
mice.imp1[[i]] <- complete(dataimp1,action=i, include=FALSE)}

####SEM rumMI
Model <- ' value =~ X1 + X2 + X3 + X4 + X5 
cost =~ X6 + X7 
information =~ X8 + X9 +X10
value ~~ costs
participation ~ value + cost + information + gender + education
information ~ value + cost + gender + education
'
FitModel <- runMI(Model, 
                 data=mice.imp1, ordered=c ("participation”, “gender”), estimator = "DWLS",
                 fun="sem", std.lv = T)
summary (FitModel, fit.measures = TRUE, standardized =T, rsquare=T, ci =T )`
TDJorgensen commented 9 months ago

I switched to the latest R version (4.3.0), lavaan (version: 0.6-11.1676), semTools (version: 0.5-6 )

These are not the latest software. R is currently 4.3.2, although I don't think that will make any difference. The latest lavaan on CRAN is 0.6-17, and the latest development version of semTools has resolved the issue of the new fm.args= argument for lavaan's summary() method:

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

If the problem persists, I would need the data to reproduce your example, and the R script you provided would need normal quotation marks instead of the "fancy"/curly quotes around some of the intended character strings (see the ones around "gender" and the one at the end of "participation"). Also, gender is an exogenous predictor, so it should not be placed in the ordered= argument; instead, use dummy codes in your data set to represent exogenous categorical variables: https://lavaan.ugent.be/tutorial/cat.html

Sara-SEM commented 9 months ago

Thank you so much for your immediate help. I still get an error along the way! Unfortunately, I´m not allowed to share the data because of the data contract.

Here is what I did:

First, I installed the latest versions of R (4.3.2), lavaan (6-17) and semTools (0.5-6.933).

Second, I ran the SEM with imputed data again and got the error below.

Model <- ' value =~ X1 + X2 + X3 + X4 + X5 cost =~ X6 + X7 information =~ X8 + X9 +X10 value ~~ costs participation ~ value + cost + information + gender + education information ~ value + cost + gender + education'

Note: gender and participation are coded dummy variables (0/1)

FitModel <- runMI(Model, data=mice.imp1, ordered=c ("participation", estimator = "DWLS", fun="sem", std.lv = T) summary (FitModel, fit.measures = TRUE, standardized =T, rsquare=T, ci =T )

Error in lav_standardize_all(object, est = est, GLIST = GLIST, partable = partable, : no slot of the name "implied" for this object of the class "lavaan.mi"

TDJorgensen commented 9 months ago

no slot of the name "implied" for this object of the class "lavaan.mi"

I doubt I can track down this error without data to reproduce it. Does the error persist if you have the development version of lavaan installed?

remotes::install_github("yrosseel/lavaan")
Sara-SEM commented 9 months ago

Thank you! I installed "yrosseel/lavaan"! Interestingly, the error only persists when I run the model with the additional exogenous variables (gender + education). This code didn’t work (gender + education included): Model_B <- ' value =~ X1 + X2 + X3 + X4 + X5 cost =~ X6 + X7 information =~ X8 + X9 +X10 value ~~ costs participation ~ value + cost + information + gender + education information ~ value + cost + gender + education'

Note. gender and participation are coded as dummies; education (level) is coded numeric

FitModel_B <- runMI(Model_B, data=mice.imp1, ordered=c ("participation", estimator = "DWLS", fun="sem", std.lv = T) summary (FitModel_B, fit.measures = TRUE, standardized =T, rsquare=T, ci =T )

Error in lav_standardize_all(object, est = est, GLIST = GLIST, partable = partable, : no slot of the name "implied" for this object of the class "lavaan.mi"

This code works (gender + education excluded): Model_A <- ' value =~ X1 + X2 + X3 + X4 + X5 cost =~ X6 + X7 information =~ X8 + X9 +X10 value ~~ costs participation ~ value + cost + information information ~ value + cost '

FitModel_A <- runMI(Model_A, data=mice.imp1, ordered=c ("participation", estimator = "DWLS", fun="sem", std.lv = T) summary (FitModel_A, fit.measures = TRUE, standardized =T, rsquare=T, ci =T )

TDJorgensen commented 9 months ago

Try

sem.mi(Model_A, data = mice.imp1, ordered = "participation",
       std.lv = TRUE, conditional.x = FALSE)
Sara-SEM commented 9 months ago

Thank you for your advice. I ran this code and got an error:r

error in lav_data_full(data = data, group = group, cluster = cluster, : lavaan ERROR: unordered factor(s) detected; make them numeric or ordered: gender

I have categorised gender as a factor before imputation (see the code below)

code

MyData <- read.spss("Data.sav", to.data.frame = TRUE,

if you plan to treat Likert items as ordinal or numeric:

                use.value.labels = FALSE)

as factors

MyData$participation<- as.factor(MyData$participation) MyData$gender <- as.factor(MyData$gender)

imputation

dataimp1 <- mice(MyData, m=25, seed=12345, max =10) mice.imp1 <- NULL m=25 for(i in 1:m) { mice.imp1[[i]] <- complete(dataimp1,action=i, include=FALSE)}

sem

Model_B <- ' value =~ X1 + X2 + X3 + X4 + X5 cost =~ X6 + X7 information =~ X8 + X9 +X10 value ~~ costs participation ~ value + cost + information + gender + education information ~ value + cost + gender + education '

sem.mi(Model_B, data = mice.imp1, ordered = "participation", std.lv = TRUE, conditional.x = FALSE)

error in lav_data_full(data = data, group = group, cluster = cluster, : lavaan ERROR: unordered factor(s) detected; make them numeric or ordered: gender

TDJorgensen commented 9 months ago

error in lav_data_full(data = data, group = group, cluster = cluster, : lavaan ERROR: unordered factor(s) detected; make them numeric or ordered: gender

I have categorised gender as a factor before imputation

Well that's obviously a problem. Just do what the error message recommends. I don't know how your factor is coded, but if the labels are "male" and "female", then this could work (for example):

for (i in 1:m) {
  mice.imp1[[i]] <- complete(dataimp1,action=i, include=FALSE)
  mice.imp1[[i]]$male <- ifelse(mice.imp1[[i]]$gender == "male", 1, 0)
}

Then just use the dummy code male in your syntax.

Sara-SEM commented 9 months ago

Thank you. I tried this and received 12 warnings (see below)

code

MyData <- read.spss("Data.sav", to.data.frame = TRUE,

if you plan to treat Likert items as ordinal or numeric:

                use.value.labels = FALSE)

as factors

MyData$participation<- as.factor(MyData$participation) MyData$gender <- as.factor(MyData$gender)

value labels

MyData$gender <- factor(MyData$gender, levels = c(0,1), labels = c("female", "male"))

imputation

dataimp1 <- mice(MyData, m=25, seed=12345, max =10) mice.imp1 <- NULL m=25 for(i in 1:m) { mice.imp1[[i]] <- complete(dataimp1,action=i, include=FALSE)}

add male

for (i in 1:m) { mice.imp1[[i]] <- complete(dataimp1,action=i, include=FALSE) mice.imp1[[i]]$male <- ifelse(mice.imp1[[i]]$gender == "male", 1, 0) } Note. male is now categorized as numeric (double) in mice.imp1

sem

Model_B <- ' value =~ X1 + X2 + X3 + X4 + X5 cost =~ X6 + X7 information =~ X8 + X9 +X10 value ~~ costs participation ~ value + cost + information + male + education information ~ value + cost + male + education '

fit <- sem.mi(Model_B, data = mice.imp1, ordered = "participation", std.lv = TRUE, conditional.x = FALSE)

There were 12 warnings (display with warnings())

summary (fit, fit.measures = TRUE, standardized =T, rsquare=T, ci =T)

error in .local(object, ...) : No imputations meet "omit.imps" criteria.

summary(warnings(fit))

Summary of (a total of 12) warnings: 6x : In lav_model_vcov(lavmodel = lavmodel, lavsamplestats = lavsamplestats, ... : lavaan WARNING: Could not compute standard errors! The information matrix could not be inverted. This may be a symptom that the model is not identified. 6x : In lav_test_satorra_bentler(lavobject = NULL, lavsamplestats = lavsamplestats, ... : lavaan WARNING: could not invert information matrix needed for robust test statistic

Sara-SEM commented 7 months ago

Sorry to ask again. Is there any other way to include dummies (gender) as exogenous factors in the SEM model above?

TDJorgensen commented 7 months ago

Yes, you can, but the warning messages say

No imputations meet "omit.imps" criteria

because

Could not compute standard errors

When you just print fit on the console, it should tell you how for many imputations the model converged on a solution. The 2 default omit.imps= criteria in any class?lavaan.mi method are:

Since there are no _SE_s available, you could remove the second criterion by setting summary(fit, ..., omit.imps = "no.conv"), but if _SE_s can't be computed, I'm not sure how trustworthy the point estimates are.

You can investigate further by fitting your model to a single imputed data set, one at a time to at least one of the imputations. Then you'll see more of lavaan's warnings to help diagnose/resolve the issue.

One idea would be to equate the loadings of the 2-indicator factor:

cost =~ L*X6 + L*X7

without which your model might not be empirically identified (depending on N and how strongly correlated cost is with the other factors).