# # Copyright 2007-2010 The OpenMx Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ----------------------------------------------------------------------- # Program: LatentGrowthModel_MatrixRaw.R # Author: Ryne Estabrook # Date: 08 01 2009 # # Latent Growth model to estimate means and (co)variances of slope and intercept # Matrix style model input - Raw data input # # Revision History # Hermine Maes -- 10 08 2009 updated & reformatted # ----------------------------------------------------------------------- require(OpenMx) #Prepare Data # ----------------------------------------------------------------------- data(myLongitudinalData) #Create an MxModel object # ----------------------------------------------------------------------- #PHIL: matrix model that uses raw data, works just fine growthCurveModel <- mxModel("Linear Growth Curve Model Matrix Specification", mxData( observed=myLongitudinalData, type="raw" ), mxMatrix( type="Full", nrow=7, ncol=7, free=F, values=c(0,0,0,0,0,1,0, 0,0,0,0,0,1,1, 0,0,0,0,0,1,2, 0,0,0,0,0,1,3, 0,0,0,0,0,1,4, 0,0,0,0,0,0,0, 0,0,0,0,0,0,0), byrow=TRUE, name="A" ), mxMatrix( type="Symm", nrow=7, ncol=7, free=c(T, F, F, F, F, F, F, F, T, F, F, F, F, F, F, F, T, F, F, F, F, F, F, F, T, F, F, F, F, F, F, F, T, F, F, F, F, F, F, F, T, T, F, F, F, F, F, T, T), values=c(0,0,0,0,0, 0, 0, 0,0,0,0,0, 0, 0, 0,0,0,0,0, 0, 0, 0,0,0,0,0, 0, 0, 0,0,0,0,0, 0, 0, 0,0,0,0,0, 1,0.5, 0,0,0,0,0,0.5, 1), labels=c("residual", NA, NA, NA, NA, NA, NA, NA, "residual", NA, NA, NA, NA, NA, NA, NA, "residual", NA, NA, NA, NA, NA, NA, NA, "residual", NA, NA, NA, NA, NA, NA, NA, "residual", NA, NA, NA, NA, NA, NA, NA, "vari", "cov", NA, NA, NA, NA, NA, "cov", "vars"), byrow= TRUE, name="S" ), mxMatrix( type="Full", nrow=5, ncol=7, free=F, values=c(1,0,0,0,0,0,0, 0,1,0,0,0,0,0, 0,0,1,0,0,0,0, 0,0,0,1,0,0,0, 0,0,0,0,1,0,0), byrow=T, dimnames=list(NULL, c(names(myLongitudinalData), "intercept", "slope")), name="F" ), mxMatrix( type="Full", nrow=1, ncol=7, values=c(0,0,0,0,0,1,1), free=c(F,F,F,F,F,T,T), labels=c(NA,NA,NA,NA,NA,"meani","means"), name="M" ), mxRAMObjective("A","S","F","M") ) growthCurveFit<-mxRun(growthCurveModel, suppressWarnings=TRUE) summary(growthCurveFit) growthCurveFit@output$estimate #------------------------------------------------------------------- ####PHIL: This next run block fails, even after tinkering with the failing messages by #### manually adding dimnames and other things require(OpenMx) #Prepare Data # ----------------------------------------------------------------------- data(myLongitudinalData) covMat<-cov(myLongitudinalData) means<-colMeans(myLongitudinalData) N<-nrow(myLongitudinalData) #Create an MxModel object # ----------------------------------------------------------------------- #PHIL: Specify input as a covariance, means, and sample size growthCurveModel <- mxModel("Linear Growth Curve Model Matrix Specification", mxData( observed=covMat, type='cov', means=means, numObs=N ), mxMatrix( type="Full", nrow=7, ncol=7, free=F, values=c(0,0,0,0,0,1,0, 0,0,0,0,0,1,1, 0,0,0,0,0,1,2, 0,0,0,0,0,1,3, 0,0,0,0,0,1,4, 0,0,0,0,0,0,0, 0,0,0,0,0,0,0), byrow=TRUE, name="A" ), mxMatrix( type="Symm", nrow=7, ncol=7, free=c(T, F, F, F, F, F, F, F, T, F, F, F, F, F, F, F, T, F, F, F, F, F, F, F, T, F, F, F, F, F, F, F, T, F, F, F, F, F, F, F, T, T, F, F, F, F, F, T, T), values=c(0,0,0,0,0, 0, 0, 0,0,0,0,0, 0, 0, 0,0,0,0,0, 0, 0, 0,0,0,0,0, 0, 0, 0,0,0,0,0, 0, 0, 0,0,0,0,0, 1,0.5, 0,0,0,0,0,0.5, 1), labels=c("residual", NA, NA, NA, NA, NA, NA, NA, "residual", NA, NA, NA, NA, NA, NA, NA, "residual", NA, NA, NA, NA, NA, NA, NA, "residual", NA, NA, NA, NA, NA, NA, NA, "residual", NA, NA, NA, NA, NA, NA, NA, "vari", "cov", NA, NA, NA, NA, NA, "cov", "vars"), byrow= TRUE, name="S" ), mxMatrix( type="Full", nrow=5, ncol=7, free=F, values=c(1,0,0,0,0,0,0, 0,1,0,0,0,0,0, 0,0,1,0,0,0,0, 0,0,0,1,0,0,0, 0,0,0,0,1,0,0), byrow=T, dimnames=list(NULL, c(names(myLongitudinalData), "intercept", "slope")), name="F" ), mxMatrix( type="Full", nrow=1, ncol=7, values=c(0,0,0,0,0,1,1), free=c(F,F,F,F,F,T,T), labels=c(NA,NA,NA,NA,NA,"meani","means"), name="M" ), mxRAMObjective("A","S","F","M") ) growthCurveFit<-mxRun(growthCurveModel, suppressWarnings=TRUE) #Error ############################################################################ ###PHIL: My solution was to create arbitrary raw data that perfectly fit # the first and second moments and use that instead #Function to synthesize raw data from Cov and means with N observations momentGen<-function(C,M,N) { #C = covariance Matrix, M= means vector, N = sample size U<-eigen(C)$vectors L<-eigen(C)$values L.sqrt<-diag(sqrt(L)) C.sqrt<-U%*%L.sqrt%*%t(U) n<-nrow(C) Y.s<-scale(matrix(rnorm(N*n),nrow=N,ncol=n)) C.y<-cor(Y.s) Q<-eigen(C.y)$vectors D<-eigen(C.y)$values D.invSqrt<-diag(1/sqrt(D)) Z<-Y.s%*%Q%*%D.invSqrt X<-Z%*%C.sqrt raw<-t(t(X)+M) colnames(raw)<-colnames(C) raw } #create data require(OpenMx) data(myLongitudinalData) covMat<-cov(myLongitudinalData) means<-colMeans(myLongitudinalData) N<-nrow(myLongitudinalData) system.time(rawData<-momentGen(covMat,means,N)) #check cov(rawData) colMeans(rawData) #rerun using synthesized data growthCurveModel <- mxModel("Linear Growth Curve Model Matrix Specification", mxData( observed=rawData, type="raw" ), mxMatrix( type="Full", nrow=7, ncol=7, free=F, values=c(0,0,0,0,0,1,0, 0,0,0,0,0,1,1, 0,0,0,0,0,1,2, 0,0,0,0,0,1,3, 0,0,0,0,0,1,4, 0,0,0,0,0,0,0, 0,0,0,0,0,0,0), byrow=TRUE, name="A" ), mxMatrix( type="Symm", nrow=7, ncol=7, free=c(T, F, F, F, F, F, F, F, T, F, F, F, F, F, F, F, T, F, F, F, F, F, F, F, T, F, F, F, F, F, F, F, T, F, F, F, F, F, F, F, T, T, F, F, F, F, F, T, T), values=c(0,0,0,0,0, 0, 0, 0,0,0,0,0, 0, 0, 0,0,0,0,0, 0, 0, 0,0,0,0,0, 0, 0, 0,0,0,0,0, 0, 0, 0,0,0,0,0, 1,0.5, 0,0,0,0,0,0.5, 1), labels=c("residual", NA, NA, NA, NA, NA, NA, NA, "residual", NA, NA, NA, NA, NA, NA, NA, "residual", NA, NA, NA, NA, NA, NA, NA, "residual", NA, NA, NA, NA, NA, NA, NA, "residual", NA, NA, NA, NA, NA, NA, NA, "vari", "cov", NA, NA, NA, NA, NA, "cov", "vars"), byrow= TRUE, name="S" ), mxMatrix( type="Full", nrow=5, ncol=7, free=F, values=c(1,0,0,0,0,0,0, 0,1,0,0,0,0,0, 0,0,1,0,0,0,0, 0,0,0,1,0,0,0, 0,0,0,0,1,0,0), byrow=T, dimnames=list(NULL, c(names(myLongitudinalData), "intercept", "slope")), name="F" ), mxMatrix( type="Full", nrow=1, ncol=7, values=c(0,0,0,0,0,1,1), free=c(F,F,F,F,F,T,T), labels=c(NA,NA,NA,NA,NA,"meani","means"), name="M" ), mxRAMObjective("A","S","F","M") ) growthCurveFitSim<-mxRun(growthCurveModel, suppressWarnings=TRUE) #Works just fine #Identical to first run with acutal raw data summary(growthCurveFitSim) summary(growthCurveFit)