The intial steps to run a full structural equation model using OpenMx mirror those used to run a confirmatory factor analysis using OpenMx. It is necessary to have R installed on your computer and to have downloaded OpenMX.
The present tutorial relies on this running example. To use the OpenMx package, launch R and load the library.
The present example will rely on a raw data file saved in SPSS format. The foreign library is used to read in SPSS data.
> library(foreign) > intell<-read.spss("http://www.methodsconsultants.com/data/intelligence.sav", to.data.frame=TRUE)
This reads in the data from a remote server and saves the file as an object named intell. The names function can be used to preview the variable names in the file.
> names(intell)  "reading" "writing" "math" "analytic" "simpsons" "familyguy" "amerdad"
The first four variables represent test scores meant to tap latent intelligence. The last three variables represent reviews of three televsion shows. Before calling the OpenMx function that will estimate the structural equation model, it is helpful to collect the names of the observed variables into one vector (name it “observed”) and the names of the latent variables into another (name it “latents”).
> observed<-names(intell) > latents<-c("intelligence","humor")
The function used to specify the model is mxModel. The SEM is described as follows:
> sem<-mxModel("Full SEM Model", type="RAM", + manifestVars=observed, + latentVars=latents, + mxPath(from="humor", to=c("simpsons","familyguy","amerdad"), + free=c(F,T,T), values=c(1,1,1), labels=c("l1","l2","l3"), ), + mxPath(from="intelligence", to=c("reading","writing","math","analytic"), + labels=c("l4","l5","l6","l7")), + mxPath(from="intelligence", to="humor",labels="g1"), + mxPath(from=observed,arrows=2,labels=c("d1","d2","d3","d4","e1","e2","e3")), + mxPath(from=latents, arrows=2,free=c(F,T),values=c(1,1)), + mxData(cov(intell),type="cov",numObs=100) + )
The model is saved as an object named sem. The first argument in this example names the model. The second argument, type="RAM", tells R that the user is thinking in terms of a path model (RAM stands for “reticular action model”). Alternatively, OpenMx can understand more explicit matrix programming.
The next two arguments, manifestVars and latentVars, assign the names of the observed and unobserved variables, respectively.
The subsequent five commands specify the paths for the model. In the first, one arrow is drawn from the latent variable humor to each of the observed variables simpsons, familyguy, and amerdad. In order to help identify the model, the first loading (from Humor to Simpsons) is constrained to equal one. This is done by specifying free=c(F,T,T), which means that the first loading will not be left as a free parameter but the remaining two will be. The next argument, values=c(1,1,1), is used to 1) specify the value of a constraint for the elements in free set to F (for FALSE); and 2) specify the starting values for the numeric optimizer for the elements in free that were set to T (for TRUE). The labels argument specifies a shorthand name for each parameter to facilitate reading the output.
The next call to mxPath specifies the paths between the latent variable intelligence and the observed variables reading, writing, math, and analytic. Labels are again assigned to name each path. Because all of the respective loadings are left free, no additional arguments are necessary (the free argument defaults to T). An additional call to mxPath specifies the arrow running from intelligence to humor.
The final two calls to mxPath specify the variances for the observed and latent variables. In each case, there is a from argument but no to, and the arrows argument is set equal to 2. This reflects a common convention in drawing path diagrams in which variances are represented with a two-headed arrow. The first of the final two mxPath functions specifies the variances for the observed variables, and the second specifies the variances for the latent variables. In this example, a second model identifying assumption is that the variance for intelligence is constrained to equal 1 using the free and values arguments, while the variance for humor is left free.
The final function, mxData specifies the data source. Although the data were read in raw from a PASW file, the cov function converts the variables into a covariance matrix. The type argument is then set to "cov", for covariance. The reason for this conversion is to keep the estimation in line with LISREL and other packages that default to analyzing a covariance matrix. However, it is possible to leave the data in raw format and specify type="raw". Doing so then defaults to FIML estimation, which is appropriate when there are missing observations in the data file.
To run the model, use the name of the model object as the sole argument to the function mxRun. Save the results into an object named results.
> results<-mxRun(sem) Running Full SEM Model
View the results using the summary function.
> summary(results) reading writing math analytic simpsons Min. :0.1884 Min. :0.1413 Min. :0.2737 Min. :0.2147 Min. :0.1413 1st Qu.:0.2237 1st Qu.:0.1681 1st Qu.:0.2847 1st Qu.:0.2367 1st Qu.:0.2210 Median :0.8187 Median :0.7063 Median :0.7718 Median :0.7063 Median :0.2777 Mean :0.6047 Mean :0.5294 Mean :0.6073 Mean :0.5659 Mean :0.3943 3rd Qu.:0.8309 3rd Qu.:0.7952 3rd Qu.:0.8205 3rd Qu.:0.8088 3rd Qu.:0.6049 Max. :1.1169 Max. :0.9316 Max. :0.9953 Max. :0.9491 Max. :0.6897 familyguy amerdad Min. :0.1826 Min. :0.1536 1st Qu.:0.2395 1st Qu.:0.2016 Median :0.2737 Median :0.2917 Mean :0.4297 Mean :0.4233 3rd Qu.:0.6098 3rd Qu.:0.6353 Max. :0.8527 Max. :0.8443 name matrix row col Estimate Std.Error 1 l4 A reading intelligence 0.9426912 0.05852687 2 l5 A writing intelligence 0.8426396 0.05440416 3 l6 A math intelligence 0.9128734 0.05377982 4 l7 A analytic intelligence 0.8636460 0.05451091 5 g1 A humor intelligence 0.2417027 0.05744189 6 l2 A familyguy humor 1.0150916 0.06320135 7 l3 A amerdad humor 1.0995753 0.05726605 8 d1 S reading reading 0.2282711 0.03119336 9 d2 S writing writing 0.2216014 0.02622611 10 d3 S math math 0.1619638 0.02504869 11 d4 S analytic analytic 0.2032078 0.02675401 12 e1 S simpsons simpsons 0.1169711 0.02202420 13 e2 S familyguy familyguy 0.2625278 0.03379653 14 e3 S amerdad amerdad 0.1518444 0.02795843 15 S humor humor 0.5143109 0.06382999 Observed statistics: 28 Estimated parameters: 15 Degrees of freedom: 13 -2 log likelihood: 50.62404 Saturated -2 log likelihood: 36.94575 numObs: 100 Chi-Square: 13.67829 p: 0.3968841 AIC (Mx): -12.32171 BIC (Mx): -23.09446 adjusted BIC: RMSEA: 0.0228421 frontend elapsed time: 0.250772 secs backend elapsed time: 0.1482589 secs
The results mirror those produced by LISREL for the same model.
Still have questions? Contact us!