Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

robust fit indices for ordinal data with equality constraints #386

Open
TDJorgensen opened this issue Oct 2, 2024 · 2 comments
Open

robust fit indices for ordinal data with equality constraints #386

TDJorgensen opened this issue Oct 2, 2024 · 2 comments

Comments

@TDJorgensen
Copy link
Contributor

TDJorgensen commented Oct 2, 2024

Not sure the full scope of the problem, but noting it here to investigate at some point. Reported on CrossValidated, but here is a reprex:

library(semTools)
data(datCat)

mod.cat <- ' FU1 =~ u1 + u2 + u3 + u4
             FU2 =~ u5 + u6 + u7 + u8 '

fit1 <- cfa(mod.cat, data = datCat, group = "g", std.lv = TRUE)
fit0 <- cfa(mod.cat, data = datCat, group = "g", std.lv = TRUE,
            group.equal = c("thresholds","loadings","intercepts"))
fitMeasures(fit1, output = "pretty") # robust fit indices look good
fitMeasures(fit0, output = "pretty") # here they are NA

But the model-implied matrices are positive definite:

sapply(lavInspect(fit0, "cor.ov"), det)

So I don't see why the ML fit function would fail with the DWLS estimates.

Weirdly, this seems to happen only when thresholds are among the constrained parameters (whether constrained in syntax with labels, or using group.equal=). When only the loadings are constrained (which is invalid because scales aren't linked without threshold constraints), the robust indices are provided:

fitL <- cfa(mod.cat, data = datCat, group = "g", group.equal = c("loadings"))
fitMeasures(fitL, output = "pretty")

This is the same behavior reported on CrossValidated using other data.

@yrosseel
Copy link
Owner

I believe this is now fixed in the github version.

The problem was that the (intercepts and) thresholds are removed in the 'continuous' version of the model (using estimator catML), but the equality constraints were still present in the parameter table. This produced an error (silently), resulting in NAs.

While looking into this, I was somewhat surprised to see that in the fit0 model (with equal loadings/thresholds), df=66 for the user model, but df=56 for the baseline model. Some fit indices (like RFI) give NA in this case. (Perhaps all incremental fit indices should?). Something just doesn't feel right.

@TDJorgensen
Copy link
Contributor Author

I believe this is now fixed in the github version

Thanks! The reprex above works now. I posted a response on CrossValidated. Maybe that OP will respond positively, too.

I was somewhat surprised to see that in the fit0 model (with equal loadings/thresholds), df=66 for the user model, but df=56 for the baseline model

Indeed, this is because lavaan's default baseline model freely estimates thresholds. Thus, it is not actually nested in a model with equality-constrained thresholds, so it should not be used to calculate incremental fit indices (regardless of whether the value comes out NA, or whether the df are lower in the baseline model). This is the same issue with continuous variables, when scalar-invariance constraints are imposed: a baseline model with free intercepts is not nested under a scalar-invariance model with equality-constrained intercepts.

Widaman, K. F., & Thompson, J. S. (2003). On specifying the null model for incremental fit indices in structural equation modeling. Psychological Methods, 8(1), 16–37. https://doi.org/10.1037/1082-989X.8.1.16

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants