Problems with Constrain expected Means and Variances to be equal across Twin Order
Hi all,
I am trying to fit several bivariate [between my exposure at age 16 and my outcomes at age 21 (accounting for age and sex)] and trivariate [my exposure at age 16 and my outcomes at ages 21 and 26 (also accounting for age and sex)] ACE models. However, I’ve started by fitting univariate saturated and submodels, followed by ACE and submodels, to eventually fit my bivariate models. The saturated models run fine across all, but when I try to fit the constrained models (by twin order and zygosity), I get the following error message:
All fit attempts resulted in errors - check starting values or model specification.
I’ve tried changing the starting values, but it hasn't worked. The ACE models run fine, so I’m not sure why these issues are occurring with the constrained models.
Below is my script. If anyone can spot a potential mistake or suggest why this is happening, I’d really appreciate it. I am using packageVersion("OpenMx"): 2.21.8.
Also, my "twin1" and "twin2" identifiers do not represent birth order, as the numbers are randomly allocated within a twin pair. In this case, is it still reasonable to assess the equality of means if the identifiers don't reflect birth order?
Thanks in advance!
source('https://vipbg.vcu.edu/vipbg/OpenMx2/software/getOpenMx.R')
mxOption(NULL,"Default optimizer","NPSOL")
library(OpenMx)
library(psych); library(polycor)
library(haven)
library(ggplot2)
library(tidyr)
library(dplyr)
library(mets)
library(patchwork)
library(kableExtra)
library(foreign)
library(summarytools)
library(polycor)
library(moments)
library(psych)
library(bestNormalize)
library(lsr)
source("miFunctions.R")
# Create Output
filename <- "two_sat_ace_bdED"
sink(paste(filename,".Ro",sep=""), append=FALSE, split=TRUE)
# ----------------------------------------------------------------------------------------------------------------------
# PREPARE DATA
# Load Data
twinData<-read_dta("twinData.dta")
dim(twinData)
describe(twinData[,1:70], skew=F)
# Select Variables for Analysis
vars <- c('bodydissatisf16', 'eatingdisorder21') # list of variables names
nv <- 2 # number of variables
ntv <- nv*2 # number of total variables
selVars <- paste(vars,c(rep(1,nv),rep(2,nv)),sep="") # This code creates two new variable names by appending 1 and 2 to the original variable name and stores them in the variable selVars.
# Select Data for Analysis
mzData <- subset(twinData, zygos1==1, selVars) # MZ
dzData <- subset(twinData, zygos1==2, selVars) # DZ
# Replace missing values in age16, age211 with values from age212, and vice versa
twinData$age161 <- ifelse(is.na(twinData$age161), twinData$age162, twinData$age161)
twinData$age162 <- ifelse(is.na(twinData$age162), twinData$age161, twinData$age162)
twinData$age211 <- ifelse(is.na(twinData$age211), twinData$age212, twinData$age211)
twinData$age212 <- ifelse(is.na(twinData$age212), twinData$age211, twinData$age212)
# Regress out age and sex for body dissatisfaction
twinData$bodydissatisf161_reg <- resid(lm(data = twinData, bodydissatisf161 ~ age161 + sex1, na.action = na.exclude))
twinData$bodydissatisf162_reg <- resid(lm(data = twinData, bodydissatisf162 ~ age162 + sex2, na.action = na.exclude))
# Regress out age and sex for eating disorders
twinData$eatingdisorder211_reg <- resid(lm(data = twinData, eatingdisorder211 ~ age211 + sex1, na.action = na.exclude))
twinData$eatingdisorder212_reg <- resid(lm(data = twinData, eatingdisorder212 ~ age212 + sex2, na.action = na.exclude))
hist(twinData$eatingdisorder211_reg)
hist(twinData$eatingdisorder211)
hist(twinData$eatingdisorder212_reg)
hist(twinData$eatingdisorder212)
# Assess skewness
transform_variables <- c("bodydissatisf161_reg", "bodydissatisf162_reg", "eatingdisorder211_reg", "eatingdisorder212_reg")
twinData %>%
select(transform_variables) %>%
skewness(., na.rm = T)
# All variables are <1.0 so need to be transformed
hist(twinData$eatingdisorder211_reg)
hist(twinData$eatingdisorder212_reg)
hist(twinData$bodydissatisf161_reg)
hist(twinData$bodydissatisf162_reg)
selVars <- transform_variables
# Select Data for Analysis - Whole sample
mzData <- subset(twinData, zygos1==1, selVars) # MZ
dzData <- subset(twinData, zygos1==2, selVars) # DZ
# Generate Descriptive Statistics
colMeans(mzData,na.rm=TRUE)
colMeans(dzData,na.rm=TRUE)
cov(mzData,use="complete")
cov(dzData,use="complete")
(rMZ<-cor(mzData,use="complete"))
(rDZ<-cor(dzData,use="complete"))
# All variables are <1.0 so do not need to be transformed
#UNCOMMENT in case you think you should still transform as other outcome variables (e.g, smfq will be skewed to ensure comparability)
# Rank transform for normalization
#ed211_norm <- orderNorm(twinData$eatingdisorder211_reg)
#twinData$eatingdisorder211_reg_norm <- predict(ed211_norm)
#ed212_norm <- orderNorm(twinData$eatingdisorder212_reg)
#twinData$eatingdisorder212_reg_norm <- predict(ed212_norm)
# Set Starting Values
svMe <- c(-0.02, -0.02) # start value for means
svVa <- c(3.14, 93.42) # start value for variances
lbVa <- .0001 # lower bound for variances
# Create Labels
labMeMZ <- labVars("meanMZ",selVars)
labMeDZ <- labVars("meanDZ",selVars)
labMeZ <- labVars("meanZ",selVars)
labCvMZ <- labLower("covMZ",ntv)
labCvDZ <- labLower("covDZ",ntv)
labCvZ <- labLower("covZ",ntv)
labVaMZ <- labDiag("covMZ",ntv)
labVaDZ <- labDiag("covDZ",ntv)
labVaZ <- labDiag("covZ",ntv)
# ----------------------------------------------------------------------------------------------------------------------
# PREPARE MODEL
# Create Algebra for expected Mean Matrices
meanMZ <- mxMatrix( type="Full", nrow=1, ncol=ntv, free=TRUE, values=svMe, labels=labMeMZ, name="meanMZ" )
meanDZ <- mxMatrix( type="Full", nrow=1, ncol=ntv, free=TRUE, values=svMe, labels=labMeDZ, name="meanDZ" )
# Create Algebra for expected Variance/Covariance Matrices
covMZ <- mxMatrix( type="Symm", nrow=ntv, ncol=ntv, free=TRUE, values=valDiag(svVa,ntv), lbound=valDiag(lbVa,ntv),
labels=labCvMZ, name="covMZ" )
covDZ <- mxMatrix( type="Symm", nrow=ntv, ncol=ntv, free=TRUE, values=valDiag(svVa,ntv), lbound=valDiag(lbVa,ntv),
labels=labCvDZ, name="covDZ" )
# Create Data Objects for Multiple Groups
dataMZ <- mxData( observed=mzData, type="raw" )
dataDZ <- mxData( observed=dzData, type="raw" )
# Create Expectation Objects for Multiple Groups
expMZ <- mxExpectationNormal( covariance="covMZ", means="meanMZ", dimnames=selVars )
expDZ <- mxExpectationNormal( covariance="covDZ", means="meanDZ", dimnames=selVars )
funML <- mxFitFunctionML()
# Create Model Objects for Multiple Groups
modelMZ <- mxModel( meanMZ, covMZ, dataMZ, expMZ, funML, name="MZ" )
modelDZ <- mxModel( meanDZ, covDZ, dataDZ, expDZ, funML, name="DZ" )
multi <- mxFitFunctionMultigroup( c("MZ","DZ") )
# Create Confidence Interval Objects
ciCov <- mxCI( c('MZ.covMZ','DZ.covDZ') )
ciMean <- mxCI( c('MZ.meanMZ','DZ.meanDZ') )
# Build Saturated Model with Confidence Intervals
modelSAT <- mxModel( "twoSATc", modelMZ, modelDZ, multi, ciCov, ciMean )
# ----------------------------------------------------------------------------------------------------------------------
# RUN MODEL
# Run Saturated Model
fitSAT <- mxTryHard( modelSAT, intervals=F )
sumSAT <- summary( fitSAT )
# Print Goodness-of-fit Statistics & Parameter Estimates
fitGofs(fitSAT)
fitEsts(fitSAT)
mxGetExpected( fitSAT, ("means"))
mxGetExpected( fitSAT, ("covariance"))
# Chagne starting values using expected means and covariances from saturated models
# Set Starting Values
svMe <- c(-0.02, -0.01) # start value for means
svVa <- c(3.08, 91.6) # start value for variances
lbVa <- .0001 # lower bound for variances
# ----------------------------------------------------------------------------------------------------------------------
# RUN SUBMODELS
# Constrain expected Means to be equal across Twin Order
modelEMO <- mxModel( fitSAT, name="twoEMOc" )
for (i in 1:nv) {
modelEMO <- omxSetParameters( modelEMO, label=c(labMeMZ[nv+i],labMeMZ[i]), free=TRUE, values=svMe[i], newlabels=labMeMZ[i] )
modelEMO <- omxSetParameters( modelEMO, label=c(labMeDZ[nv+i],labMeDZ[i]), free=TRUE, values=svMe[i], newlabels=labMeDZ[i] ) }
fitEMO <- mxTryHard( modelEMO, intervals=F )
fitGofs(fitEMO); fitEsts(fitEMO)
# Constrain expected Means and Variances to be equal across Twin Order
modelEMVO <- mxModel( fitEMO, name="twoEMVOc" )
for (i in 1:nv) {
modelEMVO <- omxSetParameters( modelEMVO, label=c(labVaMZ[nv+i],labVaMZ[i]), free=TRUE, values=svVa[i], newlabels=labVaMZ[i] )
modelEMVO <- omxSetParameters( modelEMVO, label=c(labVaDZ[nv+i],labVaDZ[i]), free=TRUE, values=svVa[i], newlabels=labVaDZ[i] ) }
fitEMVO <- mxTryHard( modelEMVO, intervals=F)
fitGofs(fitEMVO); fitEsts(fitEMVO)
# Constrain expected Means and Variances to be equal across Twin Order and Zygosity
modelEMVZ <- mxModel( fitEMVO, name="twoEMVZc" )
for (i in 1:nv) {
modelEMVZ <- omxSetParameters( modelEMVZ, label=c(labMeMZ[i],labMeDZ[i]), free=TRUE, values=svMe[i], newlabels=labMeZ[i] )
modelEMVZ <- omxSetParameters( modelEMVZ, label=c(labVaMZ[i],labVaDZ[i]), free=TRUE, values=svVa[i], newlabels=labVaZ[i] ) }
fitEMVZ <- mxTryHard( modelEMVZ, intervals=F )
fitGofs(fitEMVZ); fitEsts(fitEMVZ)
# Print Comparative Fit Statistics
mxCompare( fitSAT, subs <- list(fitEMO, fitEMVO, fitEMVZ) )
#----------------------------------------------------------------------------------------------------
# Start with Cholesky, path based ACE models and then as sensitivity analysis, fit the variance based
# Set Starting Values
svMe <- c(-0.02, -0.01) # start value for means
svPa <- 6.88 # start value for path coefficient (I have taken the square root of the averaged variances)
svPe <- .7 # start value for path coefficient for e
lbPa <- .0001 # lower bound for path coefficient
lbPaD <- valDiagLU(lbPa,-10,NA,nv) # lower bound for diagonal, lower & upper elements of covariance matrix
# ----------------------------------------------------------------------------------------------------------------------
# PREPARE MODEL
# ACE Model
# Create Algebra for expected Mean Matrices
meanG <- mxMatrix( type="Full", nrow=1, ncol=ntv, free=TRUE, values=svMe, labels=labVars("mean",vars), name="meanG" )
# Create Matrices for Path Coefficients
pathA <- mxMatrix( type="Lower", nrow=nv, ncol=nv, free=TRUE, values=valDiag(svPa,nv), labels=labLower("a",nv), lbound=lbPaD,
name="a" )
pathC <- mxMatrix( type="Lower", nrow=nv, ncol=nv, free=TRUE, values=valDiag(svPa,nv), labels=labLower("c",nv), lbound=lbPaD,
name="c" )
pathE <- mxMatrix( type="Lower", nrow=nv, ncol=nv, free=TRUE, values=valDiag(svPe,nv), labels=labLower("e",nv), lbound=lbPaD,
name="e" )
# Create Algebra for Variance Comptwonts
covA <- mxAlgebra( expression=a %*% t(a), name="A" )
covC <- mxAlgebra( expression=c %*% t(c), name="C" )
covE <- mxAlgebra( expression=e %*% t(e), name="E" )
# Create Algebra for expected Variance/Covariance Matrices in MZ & DZ twins
covP <- mxAlgebra( expression= A+C+E, name="V" )
covMZ <- mxAlgebra( expression= A+C, name="cMZ" )
covDZ <- mxAlgebra( expression= 0.5%x%A+ C, name="cDZ" )
expCovMZ <- mxAlgebra( expression= rbind( cbind(V, cMZ), cbind(t(cMZ), V)), name="expCovMZ" )
expCovDZ <- mxAlgebra( expression= rbind( cbind(V, cDZ), cbind(t(cDZ), V)), name="expCovDZ" )
# Create Data Objects for Multiple Groups
dataMZ <- mxData( observed=mzData, type="raw" )
dataDZ <- mxData( observed=dzData, type="raw" )
# Create Expectation Objects for Multiple Groups
expMZ <- mxExpectationNormal( covariance="expCovMZ", means="meanG", dimnames=selVars )
expDZ <- mxExpectationNormal( covariance="expCovDZ", means="meanG", dimnames=selVars )
funML <- mxFitFunctionML()
# Create Model Objects for Multiple Groups
pars <- list( meanG, pathA, pathC, pathE, covA, covC, covE, covP )
modelMZ <- mxModel( pars, covMZ, expCovMZ, dataMZ, expMZ, funML, name="MZ" )
modelDZ <- mxModel( pars, covDZ, expCovDZ, dataDZ, expDZ, funML, name="DZ" )
multi <- mxFitFunctionMultigroup( c("MZ","DZ") )
# Create Algebra for Standardization
matI <- mxMatrix( type="Iden", nrow=nv, ncol=nv, name="I" )
invSD <- mxAlgebra( expression=solve(sqrt(I*V)), name="iSD" )
# Calculate genetic and environmental correlations
corA <- mxAlgebra( expression=solve(sqrt(I*A))%&%A, name ="rA" ) #cov2cor()
corC <- mxAlgebra( expression=solve(sqrt(I*C))%&%C, name ="rC" )
corE <- mxAlgebra( expression=solve(sqrt(I*E))%&%E, name ="rE" )
# Create Algebra for Variance Components
rowUS <- rep('US',nv)
colUS <- rep(c('A','C','E','SA','SC','SE'),each=nv)
estUS <- mxAlgebra( expression=cbind(A,C,E,A/V,C/V,E/V), name="US", dimnames=list(rowUS,colUS) )
# Create Confidence Interval Objects
odd <- seq(1+3*nv,2*3*nv,nv)
even <- seq(2+3*nv,2*3*nv,nv)
ciACE <- mxCI( c("US[1,odd]","US[2,odd]","US[2,even]") )
# Build Model with Confidence Intervals
calc <- list( matI, invSD, corA, corC, corE, estUS, ciACE )
modelACE <- mxModel( "twoACEc", pars, modelMZ, modelDZ, multi, calc )
# ----------------------------------------------------------------------------------------------------------------------
# RUN MODEL
# Run ACE Model
fitACE <- mxTryHard( modelACE, intervals=T )
sumACE <- summary( fitACE )
# Compare with Saturated Model
#mxCompare( fitSAT, fitACE )
# Print Goodness-of-fit Statistics & Parameter Estimates
fitGofs(fitACE)
fitEstCis(fitACE)
# ----------------------------------------------------------------------------------------------------------------------
# RUN SUBMODELS
# Run AE model
modelAE <- mxModel( fitACE, name="twoAEc" )
modelAE <- omxSetParameters( modelAE, labels=labLower("c",nv), free=FALSE, values=0 )
fitAE <- mxTryHard( modelAE, intervals=T )
fitGofs(fitAE); fitEstCis(fitAE)
# Run CE model
modelCE <- mxModel( fitACE, name="twoCEc" )
modelCE <- omxSetParameters( modelCE, labels=labLower("a",nv), free=FALSE, values=0 )
fitCE <- mxTryHard( modelCE, intervals=T )
fitGofs(fitCE); fitEstCis(fitCE)
# Run E model
modelE <- mxModel( fitAE, name="twoEc" )
modelE <- omxSetParameters( modelE, labels=labLower("a",nv), free=FALSE, values=0 )
fitE <- mxTryHard( modelE, intervals=T )
fitGofs(fitE); fitEstCis(fitE)
# Print Comparative Fit Statistics
Compare_ACE_bd_ed<-mxCompare( fitACE, nested <- list(fitAE, fitCE, fitE) )
write.csv(Compare_ACE_bd_ed, "Compare_ACE_bd_ed.csv", row.names = FALSE)
results_ACE_bd_ed<-round(rbind(fitACE$US$result,fitAE$US$result,fitCE$US$result,fitE$US$result),4)
write.csv(results_ACE_bd_ed, "results_ACE_bd_ed.csv", row.names = FALSE)
# ----------------------------------------------------------------------------------------------------------------------
# Fit the ADE Cholesky model + its submodels
# ----------------------------------------------------------------------------------------------------------------------
# PREPARE MODEL
# ACE Model
# Create Algebra for expected Mean Matrices
meanG <- mxMatrix( type="Full", nrow=1, ncol=ntv, free=TRUE, values=svMe, labels=labVars("mean",vars), name="meanG" )
# Create Matrices for Path Coefficients
pathA <- mxMatrix( type="Lower", nrow=nv, ncol=nv, free=TRUE, values=valDiag(svPa,nv), labels=labLower("a",nv), lbound=lbPaD,
name="a" )
pathD <- mxMatrix( type="Lower", nrow=nv, ncol=nv, free=TRUE, values=valDiag(svPa,nv), labels=labLower("d",nv), lbound=lbPaD,
name="d" )
pathE <- mxMatrix( type="Lower", nrow=nv, ncol=nv, free=TRUE, values=valDiag(svPe,nv), labels=labLower("e",nv), lbound=lbPaD,
name="e" )
# Create Algebra for Variance Comptwonts
covA <- mxAlgebra( expression=a %*% t(a), name="A" )
covD <- mxAlgebra( expression=d %*% t(d), name="D" )
covE <- mxAlgebra( expression=e %*% t(e), name="E" )
# Create Algebra for expected Variance/Covariance Matrices in MZ & DZ twins
covP <- mxAlgebra( expression= A+D+E, name="V" )
covMZ <- mxAlgebra( expression= A+D, name="cMZ" )
covDZ <- mxAlgebra( expression= 0.5%x%A+ 0.25%x%D, name="cDZ" )
expCovMZ <- mxAlgebra( expression= rbind( cbind(V, cMZ), cbind(t(cMZ), V)), name="expCovMZ" )
expCovDZ <- mxAlgebra( expression= rbind( cbind(V, cDZ), cbind(t(cDZ), V)), name="expCovDZ" )
# Create Data Objects for Multiple Groups
dataMZ <- mxData( observed=mzData, type="raw" )
dataDZ <- mxData( observed=dzData, type="raw" )
# Create Expectation Objects for Multiple Groups
expMZ <- mxExpectationNormal( covariance="expCovMZ", means="meanG", dimnames=selVars )
expDZ <- mxExpectationNormal( covariance="expCovDZ", means="meanG", dimnames=selVars )
funML <- mxFitFunctionML()
# Create Model Objects for Multiple Groups
pars <- list(meanG, pathA, pathD, pathE, covA, covD, covE, covP )
modelMZ <- mxModel( pars, covMZ, expCovMZ, dataMZ, expMZ, funML, name="MZ" )
modelDZ <- mxModel( pars, covDZ, expCovDZ, dataDZ, expDZ, funML, name="DZ" )
multi <- mxFitFunctionMultigroup( c("MZ","DZ") )
# Create Algebra for Standardization
matI <- mxMatrix( type="Iden", nrow=nv, ncol=nv, name="I" )
invSD <- mxAlgebra( expression=solve(sqrt(I*V)), name="iSD" )
# Calculate genetic and environmental correlations
corA <- mxAlgebra( expression=solve(sqrt(I*A))%&%A, name ="rA" ) #cov2cor()
corD <- mxAlgebra( expression=solve(sqrt(I*D))%&%D, name ="rD" )
corE <- mxAlgebra( expression=solve(sqrt(I*E))%&%E, name ="rE" )
# Create Algebra for Variance Components
rowUS <- rep('US',nv)
colUS <- rep(c('A','D','E','SA','SD','SE'),each=nv)
estUS <- mxAlgebra( expression=cbind(A,D,E,A/V,D/V,E/V), name="US", dimnames=list(rowUS,colUS) )
# Create Confidence Interval Objects
odd <- seq(1+3*nv,2*3*nv,nv)
even <- seq(2+3*nv,2*3*nv,nv)
ciADE <- mxCI( c("US[1,odd]","US[2,odd]","US[2,even]") )
# Build Model with Confidence Intervals
calc <- list( matI, invSD, corA, corD, corE, estUS, ciADE )
modelADE <- mxModel( "twoADEc", pars, modelMZ, modelDZ, multi, calc )
# ----------------------------------------------------------------------------------------------------------------------
# RUN MODEL
# Run ADE Model
fitADE <- mxTryHard( modelADE, intervals=T )
sumADE <- summary( fitADE )
# Compare with Saturated Model
#mxCompare( fitSAT, fitADE )
# Print Goodness-of-fit Statistics & Parameter Estimates
fitGofs(fitADE)
fitEstCis(fitADE)
# ----------------------------------------------------------------------------------------------------------------------
# RUN SUBMODELS
# Run AE model
modelAE <- mxModel( fitADE, name="twoAEc" )
modelAE <- omxSetParameters( modelAE, labels=labLower("d",nv), free=FALSE, values=0 )
fitAE <- mxTryHard( modelAE, intervals=T )
fitGofs(fitAE); fitEstCis(fitAE)
# Run E model
modelE <- mxModel( fitAE, name="twoEc" )
modelE <- omxSetParameters( modelE, labels=labLower("a",nv), free=FALSE, values=0 )
fitE <- mxTryHard( modelE, intervals=T )
fitGofs(fitE); fitEstCis(fitE)
# Print Comparative Fit Statistics
Compare_ADE_bd_ed<-mxCompare( fitADE, nested <- list(fitAE, fitE) )
write.csv(Compare_ADE_bd_ed, "Compare_ADE_bd_ed.csv", row.names = FALSE)
ADE_results_bd_ed<-round(rbind(fitADE$US$result,fitAE$US$result,fitE$US$result),4)
write.csv(ADE_results_bd_ed, "ADE_results_bd_ed.csv", row.names = FALSE)
#----------------------------------------------------------------------------------------------------------------
# As sensitivity analysis fir the variance based ACE model
# PREPARE MODEL
# Create Algebra for expected Mean Matrices
meanG <- mxMatrix( type="Full", nrow=1, ncol=ntv, free=TRUE, values=svMe, labels=labVars("mean",vars), name="meanG" )
# Create Matrices for Variance Components
covA <- mxMatrix( type="Symm", nrow=nv, ncol=nv, free=TRUE, values=valDiag(svPa,nv), label=labLower("VA",nv), name="VA" )
covC <- mxMatrix( type="Symm", nrow=nv, ncol=nv, free=TRUE, values=valDiag(svPa,nv), label=labLower("VC",nv), name="VC" )
covE <- mxMatrix( type="Symm", nrow=nv, ncol=nv, free=TRUE, values=valDiag(svPa,nv), label=labLower("VE",nv), name="VE" )
# Create Algebra for expected Variance/Covariance Matrices in MZ & DZ twins
covP <- mxAlgebra( expression= VA+VC+VE, name="V" )
covMZ <- mxAlgebra( expression= VA+VC, name="cMZ" )
covDZ <- mxAlgebra( expression= 0.5%x%VA+ VC, name="cDZ" )
expCovMZ <- mxAlgebra( expression= rbind( cbind(V, cMZ), cbind(t(cMZ), V)), name="expCovMZ" )
expCovDZ <- mxAlgebra( expression= rbind( cbind(V, cDZ), cbind(t(cDZ), V)), name="expCovDZ" )
# Create Data Objects for Multiple Groups
dataMZ <- mxData( observed=mzData, type="raw" )
dataDZ <- mxData( observed=dzData, type="raw" )
# Create Expectation Objects for Multiple Groups
expMZ <- mxExpectationNormal( covariance="expCovMZ", means="meanG", dimnames=selVars )
expDZ <- mxExpectationNormal( covariance="expCovDZ", means="meanG", dimnames=selVars )
funML <- mxFitFunctionML()
# Create Model Objects for Multiple Groups
pars <- list( meanG, covA, covC, covE, covP )
modelMZ <- mxModel( pars, covMZ, expCovMZ, dataMZ, expMZ, funML, name="MZ" )
modelDZ <- mxModel( pars, covDZ, expCovDZ, dataDZ, expDZ, funML, name="DZ" )
multi <- mxFitFunctionMultigroup( c("MZ","DZ") )
# Create Algebra for Standardization
matI <- mxMatrix( type="Iden", nrow=nv, ncol=nv, name="I" )
invSD <- mxAlgebra( expression=solve(sqrt(I*V)), name="iSD" )
# Calculate genetic and environmental correlations
corA <- mxAlgebra( expression=solve(sqrt(I*VA))%&%VA, name ="rA" ) #cov2cor()
corC <- mxAlgebra( expression=solve(sqrt(I*VC))%&%VC, name ="rC" )
corE <- mxAlgebra( expression=solve(sqrt(I*VE))%&%VE, name ="rE" )
# Create Algebra for Unstandardized and Standardized Variance Components
rowUS <- rep('US',nv)
colUS <- rep(c('VA','VC','VE','SA','SC','SE'),each=nv)
estUS <- mxAlgebra( expression=cbind(VA,VC,VE,VA/V,VC/V,VE/V), name="US", dimnames=list(rowUS,colUS) )
# Create Confidence Interval Objects
odd <- seq(1+3*nv,2*3*nv,nv)
even <- seq(2+3*nv,2*3*nv,nv)
ciACE <- mxCI( c("US[1,odd]","US[2,odd]","US[2,even]") )
# Build Model with Confidence Intervals
calc <- list( matI, invSD, corA, corC, corE, estUS, ciACE )
modelACE <- mxModel( "twoACEvc", pars, modelMZ, modelDZ, multi, calc )
# ----------------------------------------------------------------------------------------------------------------------
# RUN MODEL
# Run ACE Model
fitACE <- mxTryHard( modelACE, intervals=T )
sumACE <- summary( fitACE )
# Compare with Saturated Model
mxCompare( fitSAT, fitACE )
# Print Goodness-of-fit Statistics & Parameter Estimates
fitGofs(fitACE)
fitEstCis(fitACE)
# ----------------------------------------------------------------------------------------------------------------------
# RUN SUBMODELS
# Run AE model
modelAE <- mxModel( fitACE, name="twoAEvc" )
modelAE <- omxSetParameters( modelAE, labels=labLower("VC",nv), free=FALSE, values=0 )
fitAE <- mxTryHard( modelAE, intervals=T )
fitGofs(fitAE); fitEstCis(fitAE)
# Run CE model
modelCE <- mxModel( fitACE, name="twoCEvc" )
modelCE <- omxSetParameters( modelCE, labels=labLower("VA",nv), free=FALSE, values=0 )
modelCE <- omxSetParameters( modelCE, labels=labLower("VC",nv), free=TRUE, values=.6 )
fitCE <- mxTryHard( modelCE, intervals=T )
fitGofs(fitCE); fitEstCis(fitCE)
# Run E model
modelE <- mxModel( fitAE, name="twoEvc" )
modelE <- omxSetParameters( modelE, labels=labLower("VA",nv), free=FALSE, values=0 )
fitE <- mxTryHard( modelE, intervals=T )
fitGofs(fitE); fitEstCis(fitE)
# Print Comparative Fit Statistics
mxCompare( fitACE, nested <- list(fitAE, fitCE, fitE) )
round(rbind(fitACE$US$result,fitAE$US$result,fitCE$US$result,fitE$US$result),4)
Inspect the expected covariance matrices and expected means
Hi
I cannot directly inspect your issue without access to the data. However, I can tell you what I would do to diagnose the issue. Two things might be off, the expected covariances and the expected means. Assuming that it's this section that has the error:
Supposing modelEMO fails, I would then look at the model-implied statistics like this:
expcovs <- mxGetExpected(modelEMO, 'covariance')
#get eigenvalues and inspect to verify positive definiteness. Any negative eigenvalues shows a problem with the covariances. Also, the diagonals of the matrix should approximate or be a bit larger than the observed variances.
eigen(expcovs$MZ)
#get model-implied means
expmeans <- mxGetExpected(modelEMO, 'means')
#inspect means and make sure they are within 1sd or so of the true mean. The sd in question is the square root of the diagonal element of the model-implied covariance corresponding to that variable (they are in the same order). Change the values for the means if not roughly same as observed.
Hope this helps! Let us know how you get on.
Log in or register to post comments
In reply to Inspect the expected covariance matrices and expected means by AdminNeale
Hi, Thank you so much for…
Hi,
Thank you so much for our response. So my modelEMO runs okay, it is when I constrain the variances (EMVO and EMVZ) that the problems occurr...
I have tried to run your diagnostics and indeed I get negative values when running the eigen(expcovs$MZ). Do you know what could be causing this? The expected means and covariances are indeed similar though to the real ones.
These are the actual means (regressed on age and sex) and the actual covariances. I have also set starting values that approximate the real means and covariances.
For some reason, see highlighted in bold. It seems that the expected covariances have been flipped for trait 1 and trait 2, where the covariance for body dissatisfaction twin1 and twin 2 that should be around 3 is actually around 90 which is the expected covariance for eating disorder.
Have I done something when setting the starting values or the model that has forced this error?
Thanks again for your help with this - really appreciated!
Log in or register to post comments
In reply to Hi, Thank you so much for… by Ilaria
One thing I find very…
One thing I find very helpful dealing with starting value problems is to avoid large covariances between variables. If the correlation is 1 or more, the likelihood is undefined and optimization can't find its way 'down'. So I would dial down the starting values for A and C components, and increase the E components to compensate. Making E's off-diagonal elements zero can also help. But still something else is up...
Aha! I think your problem is that the variables are in the wrong order. The order that model is set up to generate is T1V1 T1V2 T2V1 T2V2. Your observed variables are instead T1V1 T2V1 T1V2 T2V2. So, if you reorganize bodydissatisf161_reg bodydissatisf162_reg eatingdisorder211_reg eatingdisorder212_reg to bodydissatisf161_reg eatingdisorder211_reg bodydissatisf162_reg eatingdisorder212_reg All should be well. Good luck and please let us know if this works or not.
Log in or register to post comments
Hi, Does anyone have any…
Hi,
Does anyone have any idea what could be going wrong? I am setting the wrong starting values? I did not get this problem in other models whether the models are the same and the data too.
Thanks for your help for this - much appreciated!
Log in or register to post comments
Hi - does anyone know what…
Hi - does anyone know what is not working? I have tried to modify the starting values but the EMVO model (let's say to 4 and 7 respectively) but this is what happens when I try to fit the EMVO model (see below).
It just seems like it is getting forced into the variance of both variable 1 and variable 2, whereas what I thought this code should have been doing (see above) is to constrain the variances to be equal across twins and zygosity but within variable. So, in this example it should have estimated something around 4 for the first variable and something around 7 (which now is a totally unrealistic value as the variance is more around 80) for the second, but they are distributed for twin 1 and 2 instead seems like.
Does it just not make sense running such model when the variances of the two variables are so different?
Thanks for your help!
Log in or register to post comments