Attachment | Size |
---|---|
lavaan-model.png [6] | 806.51 KB |
As written in this thread [7], I have repeated problems with a non-convex Hessian while working my way step-wise towards a 3-level SEM with latent variables and their respective measurement items in a paper in organizational psychology.
While I'm looking for general guidelines to deal with non-cenvex Hessians and status code 5-issues in that thread, it's probably good to look at my models to find issues here.
My goal is to build a model with two variables measured on the 1st "individual" level (X, Y), two variables measured on the 2nd "team" level (V, W) and a 3rd "district" level to control for shared variance between teams. All X, Y, V, W will be related through regressions on the 2nd level. I compare my models with lavaan as far as feasible (lavaan isn't able to do 3lvl MSEMs).
I get the single-level regressions and 2lvl-measurement models to agree. Yet, when trying to build a 2lvl-factor model regressing Y on X, I already run into problems.
I have attached a sketch of the lavaan model as I understand it. Here is the code, is something about my model already wrong? If not, where can I start trouble shooting?
I'm grateful for your support. I hope I've just made a simple mistake somewhere and hope it's not too stupid.
require(OpenMx) dataL1 <- data dataL2 <- data[!duplicated(data$team),] mxDataL1 <- mxData(observed=dataL1, type="raw") mxDataL2 <- mxData(observed=dataL2, type="raw", primaryKey = "team") xItems <- paste0("x",1:nx) yItems <- paste0("y",1:ny) ## Defining various Paths # Paths X lvl 1 pathXItemsVar <- mxPath(from=xItems, arrows=2, free=TRUE, values = diag(var(data[xItems], na.rm=TRUE)), labels=paste0("e_x",1:nx)) # residual variances pathXItemsMeans <- mxPath(from = "one", to = xItems, free=TRUE, values=1, labels=paste0("m_x",1:nx)) # means items pathXItemsMeans0 <- mxPath(from = "one", to = xItems, free = FALSE, values=0, labels=paste0("m_x",1:nx)) # manifest means, constrained to 0 pathXLoadings <- mxPath(from="x", to=xItems, free=c(FALSE,rep(TRUE,nx-1)), values=1, labels=paste0("fl_x",1:nx)) # factor loadings, fixing first factor to 1 pathXLatentVar <- mxPath(from="x", arrows=2, free=TRUE, values=1, labels="var_x") # latent variance # Paths Y lvl 1 pathYItemsVar <- mxPath(from=yItems, arrows=2, free=TRUE, values = diag(var(data[yItems], na.rm=TRUE)), labels=paste0("e_y",1:ny)) # residual variances pathYItemsMeans <- mxPath(from = "one", to = yItems, free=TRUE, values=1, labels=paste0("m_y",1:ny)) # means items pathYItemsMeans0 <- mxPath(from = "one", to = yItems, free = FALSE, values=0, labels=paste0("m_y",1:ny)) # manifest means, constrained to 0 pathYLoadings <- mxPath(from="y", to=yItems, free=c(FALSE,rep(TRUE,ny-1)), values=1, labels=paste0("fl_y",1:ny)) # factor loadings, fixing first factor to 1 pathYLatentVar <- mxPath(from="y", arrows=2, free=TRUE, values = 1, labels="var_y") # latent variance # Paths X lvl 2 pathXItemsVarL2 <- mxPath(from=xItems, arrows=2, free=TRUE, values = diag(var(data[xItems], na.rm=TRUE)), labels=paste0("e_l2x",1:nx)) # (latent) items variance pathXItemsMeansL2 <- mxPath(from = "one", to = xItems, free=TRUE, values=1, labels=paste0("m_l2x",1:nx)) # (latent) items means pathXLoadingsL2 <- mxPath(from = "xTeam", to = xItems,free = c(FALSE,rep(TRUE,nx-1)), values = 1, labels = paste0("fl_x",1:nx)) # latent Team factor, loadings constrained to same as on within level, first fixed to 1 pathXLatentVarL2 <- mxPath(from = "xTeam", arrows = 2, values = .25, free = TRUE, labels = "xTeam_var") # latent team factor, variance # Paths Y lvl 2 pathYItemsVarL2 <- mxPath(from=yItems, arrows=2, free=TRUE, values = diag(var(data[yItems], na.rm=TRUE)), labels=paste0("e_l2y",1:ny)) # (latent) items variance pathYItemsMeansL2 <- mxPath(from = "one", to = yItems, free=TRUE, values=1, labels=paste0("m_l2y",1:ny)) # (latent) items means pathYLoadingsL2 <- mxPath(from = "yTeam", to = yItems,free = c(FALSE,rep(TRUE,ny-1)), values = 1, labels = paste0("fl_y",1:ny)) # latent Team factor, loadings constrained to same as on within level, first fixed to 1 pathYLatentVarL2 <- mxPath(from = "yTeam", arrows = 2, values = .25, free = TRUE, labels = "yTeam_var") # latent team factor, variance # Regression pathRegXY <- mxPath(from = "x", to = "y", arrows = 1, free = TRUE, value = 1, labels = "x_to_y_within") pathRegXYTeam <- mxPath(from = "xTeam", to = "yTeam", arrows = 1, free = TRUE, value = 1, labels = "x_to_y_between") ## Lavaan model require(lavaan) lmodelXYL12 <- ' level: 1 xw =~ a1 * x1 + a2 * x2 + a3 * x3 + a4 * x4 + a5 * x5 + a6 * x6 + a7 * x7 + a8 * x8 + a9 * x9 + a10 * x10 + a11 * x11 + a12 * x12 + a13 * x13 + a14 * x14 yw =~ b1 * y1 + b2 * y2 + b3 * y3 + b4 * y4 + b5 * y5 + b6 * y6 + b7 * y7 + b8 * y8 + b9 * y9 + b10 * y10 + b11 * y11 + b12 * y12 yw ~ xw level: 2 xb =~ a1 * x1 + a2 * x2 + a3 * x3 + a4 * x4 + a5 * x5 + a6 * x6 + a7 * x7 + a8 * x8 + a9 * x9 + a10 * x10 + a11 * x11 + a12 * x12 + a13 * x13 + a14 * x14 yb =~ b1 * y1 + b2 * y2 + b3 * y3 + b4 * y4 + b5 * y5 + b6 * y6 + b7 * y7 + b8 * y8 + b9 * y9 + b10 * y10 + b11 * y11 + b12 * y12 yb ~ xb ' lfitXYL12 <- sem(model = lmodelXYL12, data = dataL1, cluster = "team") summary(lfitXYL12) # the factor loadings and other measures are the same as with OpenMx ## OpenMx Models pathRegXY <- mxPath(from = "x", to = "y", arrows = 1, free = TRUE, value = 1, labels = "x_to_y") pathRegXYTeam <- mxPath(from = "xTeam", to = "yTeam", arrows = 1, free = TRUE, value = 1, labels = "x_to_y") modelXYLatentL2 <- mxModel( model = "between", type = "RAM", manifestVars = c(), latentVars = c("xTeam","yTeam",xItems,yItems), mxDataL2, pathXItemsMeansL2, pathXItemsVarL2, pathYItemsMeansL2, pathYItemsVarL2, pathXLatentVarL2, pathXLoadingsL2, pathYLatentVarL2, pathYLoadingsL2, pathRegXYTeam, mxCI(c("x_to_y_between")) ) modelXYLatentL12 <- mxModel( model = "within", type = "RAM", modelXYLatentL2, manifestVars = c(xItems,yItems), latentVars = c("x","y"), mxDataL1, mxPath(from = paste0("between.",xItems), to = xItems, values=1, free=FALSE, joinKey="team"), #linking (latent) between lvl Items to manifest vars mxPath(from = paste0("between.",yItems), to = yItems, values=1, free=FALSE, joinKey="team"), #linking (latent) between lvl Items to manifest vars pathXItemsMeans0, pathXItemsVar, pathYItemsMeans0, pathYItemsVar, pathXLatentVar, pathXLoadings, pathYLatentVar, pathYLoadings, pathRegXY, mxCI(c("x_to_y_within")) ) fitXYLatentL12 <- mxRun(modelXYLatentL12, intervals = TRUE) summary(fitXYLatentL12)