Update Users Guide pages A through F for the expectation-fit change.
[openmx:openmx.git] / docs / source / FactorAnalysis_Matrix.rst
1 .. _factoranalysis-matrix-specification:
2
3 Factor Analysis, Matrix Specification
4 =====================================
5
6 This example will demonstrate latent variable modeling via the common factor model using RAM matrices for model specification. We'll walk through two applications of this approach: one with a single latent variable, and one with two latent variables. As with previous examples, these two applications are split into four files, with each application represented separately with raw and covariance data. These examples can be found in the following files:
7
8 * http://openmx.psyc.virginia.edu/svn/trunk/demo/OneFactorModel_MatrixCov.R
9 * http://openmx.psyc.virginia.edu/svn/trunk/demo/OneFactorModel_MatrixRaw.R
10 * http://openmx.psyc.virginia.edu/svn/trunk/demo/TwoFactorModel_MatrixCov.R
11 * http://openmx.psyc.virginia.edu/svn/trunk/demo/TwoFactorModel_MatrixRaw.R
12
13 Parallel versions of this example, using path-centric specification of models rather than matrices, can be found here:
14
15 * http://openmx.psyc.virginia.edu/svn/trunk/demo/OneFactorModel_PathCov.R
16 * http://openmx.psyc.virginia.edu/svn/trunk/demo/OneFactorModel_PathRaw.R
17 * http://openmx.psyc.virginia.edu/svn/trunk/demo/TwoFactorModel_PathCov.R
18 * http://openmx.psyc.virginia.edu/svn/trunk/demo/TwoFactorModel_PathRaw.R
19
20
21 Common Factor Model
22 -------------------
23
24 The common factor model is a method for modeling the relationships between observed variables believed to measure or indicate the same latent variable. While there are a number of exploratory approaches to extracting latent factor(s), this example uses structural modeling to fit confirmatory factor models. The model for any person and path diagram of the common factor model for a set of variables :math:`x_{1}` - :math:`x_{6}` are given below.
25
26 .. math::
27    :nowrap:
28    
29    \begin{eqnarray*} 
30    x_{ij} = \mu_{j} + \lambda_{j} * \eta_{i} + \epsilon_{ij}
31    \end{eqnarray*}
32
33 .. image:: graph/OneFactorModel.png
34     :height: 2in
35
36 While 19 parameters are displayed in the equation and path diagram above (6 manifest variances, six manifest means, six factor loadings and one factor variance), we must constrain either the factor variance or one factor loading to a constant to identify the model and scale the latent variable. As such, this model contains 18 parameters. Unlike the manifest variable examples we've run up until now, this model is not fully saturated. The means and covariance matrix for six observed variables contain 27 degrees of freedom, and thus our model contains 9 degrees of freedom. 
37
38 Data
39 ^^^^
40
41 Our first step to running this model is to include the data to be analyzed. The data for this example contain nine variables. We'll select the six we want for this model using the selection operators used in previous examples. Both raw and covariance data are included below, but only one is required for any model.
42
43 .. code-block:: r
44
45     data(myFADataRaw)
46     names(myFADataRaw)
47
48     oneFactorRaw <- myFADataRaw[,c("x1", "x2", "x3", "x4", "x5", "x6")]
49
50     myFADataCov <- matrix(
51         c(0.997, 0.642, 0.611, 0.672, 0.637, 0.677, 0.342, 0.299, 0.337,
52           0.642, 1.025, 0.608, 0.668, 0.643, 0.676, 0.273, 0.282, 0.287,
53           0.611, 0.608, 0.984, 0.633, 0.657, 0.626, 0.286, 0.287, 0.264,
54           0.672, 0.668, 0.633, 1.003, 0.676, 0.665, 0.330, 0.290, 0.274,
55           0.637, 0.643, 0.657, 0.676, 1.028, 0.654, 0.328, 0.317, 0.331,
56           0.677, 0.676, 0.626, 0.665, 0.654, 1.020, 0.323, 0.341, 0.349,
57           0.342, 0.273, 0.286, 0.330, 0.328, 0.323, 0.993, 0.472, 0.467,
58           0.299, 0.282, 0.287, 0.290, 0.317, 0.341, 0.472, 0.978, 0.507,
59           0.337, 0.287, 0.264, 0.274, 0.331, 0.349, 0.467, 0.507, 1.059),
60         nrow=9,
61         dimnames=list(
62             c("x1", "x2", "x3", "x4", "x5", "x6", "y1", "y2", "y3"),
63             c("x1", "x2", "x3", "x4", "x5", "x6", "y1", "y2", "y3")),
64     )
65
66     oneFactorCov <- myFADataCov[c("x1","x2","x3","x4","x5","x6"), 
67                         c("x1","x2","x3","x4","x5","x6")]
68
69     myFADataMeans <- c(2.988, 3.011, 2.986, 3.053, 3.016, 3.010, 2.955, 2.956, 2.967)
70     names(myFADataMeans) <- c("x1","x2","x3","x4","x5","x6")
71
72     oneFactorMeans <- myFADataMeans[1:6]
73
74
75 Model Specification
76 ^^^^^^^^^^^^^^^^^^^
77
78 The following code contains all of the components of our model. Before running a model, the OpenMx library must be loaded into R using either the ``require()`` or ``library()`` function. All objects required for estimation (data, matrices, an expectation function, and a fit function) are included in their functions. This code uses the ``mxModel`` function to create an ``MxModel`` object, which we will then run.
79
80 .. code-block:: r
81
82     manifestVars <- c("x1","x2","x3","x4","x5","x6")
83     latentVars <- "F1"
84
85     oneFactorModel <- mxModel("Common Factor Model Matrix Specification", 
86         mxData(
87             myFADataRaw, 
88             type="raw"
89         ),
90         # asymmetric paths
91         mxMatrix(
92             type="Full", 
93             nrow=7, 
94             ncol=7,
95             values=c(0,0,0,0,0,0,1,
96                      0,0,0,0,0,0,1,
97                      0,0,0,0,0,0,1,
98                      0,0,0,0,0,0,1,
99                      0,0,0,0,0,0,1,
100                      0,0,0,0,0,0,1,
101                      0,0,0,0,0,0,0),
102             free=c(F, F, F, F, F, F, F,
103                    F, F, F, F, F, F, T,
104                    F, F, F, F, F, F, T,
105                    F, F, F, F, F, F, T,
106                    F, F, F, F, F, F, T,
107                    F, F, F, F, F, F, T,
108                    F, F, F, F, F, F, F),
109             labels=c(NA,NA,NA,NA,NA,NA,"l1",
110                      NA,NA,NA,NA,NA,NA,"l2",
111                      NA,NA,NA,NA,NA,NA,"l3",
112                      NA,NA,NA,NA,NA,NA,"l4",
113                      NA,NA,NA,NA,NA,NA,"l5",
114                      NA,NA,NA,NA,NA,NA,"l6",
115                      NA,NA,NA,NA,NA,NA,NA),
116             byrow=TRUE,
117             name="A"
118         ),
119         # symmetric paths
120         mxMatrix(
121             type="Symm",
122             nrow=7,
123             ncol=7, 
124             values=c(1,0,0,0,0,0,0,
125                      0,1,0,0,0,0,0,
126                      0,0,1,0,0,0,0,
127                      0,0,0,1,0,0,0,
128                      0,0,0,0,1,0,0,
129                      0,0,0,0,0,1,0,
130                      0,0,0,0,0,0,1),
131             free=c(T, F, F, F, F, F, F,
132                    F, T, F, F, F, F, F,
133                    F, F, T, F, F, F, F,
134                    F, F, F, T, F, F, F,
135                    F, F, F, F, T, F, F,
136                    F, F, F, F, F, T, F,
137                    F, F, F, F, F, F, T),
138             labels=c("e1", NA,   NA,   NA,   NA,   NA,   NA,
139                      NA, "e2",   NA,   NA,   NA,   NA,   NA,
140                      NA,   NA, "e3",   NA,   NA,   NA,   NA,
141                      NA,   NA,   NA, "e4",   NA,   NA,   NA,
142                      NA,   NA,   NA,   NA, "e5",   NA,   NA,
143                      NA,   NA,   NA,   NA,   NA, "e6",   NA,
144                      NA,   NA,   NA,   NA,   NA,   NA, "varF1"),
145             byrow=TRUE,
146             name="S"
147         ),
148         # filter matrix
149         mxMatrix(
150             type="Full", 
151             nrow=6, 
152             ncol=7,
153             free=FALSE,
154             values=c(1,0,0,0,0,0,0,
155                      0,1,0,0,0,0,0,
156                      0,0,1,0,0,0,0,
157                      0,0,0,1,0,0,0,
158                      0,0,0,0,1,0,0,
159                      0,0,0,0,0,1,0),
160             byrow=TRUE,
161             name="F"
162         ),
163         # means
164         mxMatrix(
165             type="Full", 
166             nrow=1, 
167             ncol=7,
168             values=c(1,1,1,1,1,1,0),
169             free=c(T,T,T,T,T,T,F),
170             labels=c("meanx1","meanx2","meanx3","meanx4","meanx5","meanx6",NA),
171             name="M"
172         ),
173         mxExpectationRAM("A","S","F","M",
174             dimnames=c(manifestVars, latentVars)),
175         mxFitFunctionML()
176     )
177
178 This ``mxModel`` function can be split into several parts. First, we give the model a name. The first argument in an ``mxModel`` function has a special function. If an object or variable containing an ``MxModel`` object is placed here, then ``mxModel`` adds to or removes pieces from that model. If a character string (as indicated by double quotes) is placed first, then that becomes the name of the model. Models may also be named by including a ``name`` argument. This model is named ``"Common Factor Model Matrix Specification"``.
179
180 The second component of our code creates an ``MxData`` object. The example above, reproduced here, first references the object where our data is, then uses the ``type`` argument to specify that this is raw data.
181
182 .. code-block:: r
183
184     mxData(
185         observed=oneFactorRaw, 
186         type="raw"
187     )
188   
189 If we were to use a covariance matrix and vector of means as data, we would replace the existing ``mxData`` function with this one:
190
191 .. code-block:: r
192
193     mxData(
194         observed=oneFactorCov, 
195         type="cov",
196         numObs=500,
197         means=oneFactorMeans
198     ) 
199   
200 Model specification is carried out using ``mxMatrix`` functions to create matrices for a RAM specified model. The **A** matrix specifies all of the asymmetric paths or regressions in our model. In the common factor model, these parameters are the factor loadings. This matrix is square, and contains as many rows and columns as variables in the model (manifest and latent, typically in that order). Regressions are specified in the **A** matrix by placing a free parameter in the row of the dependent variable and the column of independent variable. 
201
202 The common factor model requires that one parameter (typically either a factor loading or factor variance) be constrained to a constant value. In our model, we will constrain the first factor loading to a value of 1, and let all other loadings be freely estimated. All factor loadings have a starting value of one and labels of ``"l1"`` - ``"l6"``.
203
204 .. code-block:: r
205
206     # asymmetric paths
207     mxMatrix(
208         type="Full",
209         nrow=7,
210         ncol=7,
211         values=c(0,0,0,0,0,0,1,
212                  0,0,0,0,0,0,1,
213                  0,0,0,0,0,0,1,
214                  0,0,0,0,0,0,1,
215                  0,0,0,0,0,0,1,
216                  0,0,0,0,0,0,1,
217                  0,0,0,0,0,0,0),
218         free=c(F, F, F, F, F, F, F,
219                F, F, F, F, F, F, T,
220                F, F, F, F, F, F, T,
221                F, F, F, F, F, F, T,
222                F, F, F, F, F, F, T,
223                F, F, F, F, F, F, T,
224                F, F, F, F, F, F, F),
225         labels=c(NA,NA,NA,NA,NA,NA,"l1",
226                  NA,NA,NA,NA,NA,NA,"l2",
227                  NA,NA,NA,NA,NA,NA,"l3",
228                  NA,NA,NA,NA,NA,NA,"l4",
229                  NA,NA,NA,NA,NA,NA,"l5",
230                  NA,NA,NA,NA,NA,NA,"l6",
231                  NA,NA,NA,NA,NA,NA,NA),
232         byrow=TRUE,
233         name="A"
234     )
235
236 The second matrix in a RAM model is the **S** matrix, which specifies the symmetric or covariance paths in our model. This matrix is symmetric and square, and contains as many rows and columns as variables in the model (manifest and latent, typically in that order). The symmetric paths in our model consist of six residual variances and one factor variance. All of these variances are given starting values of one and labels ``"e1"`` - ``"e6"`` and ``"varF1"``.
237
238 .. code-block:: r
239
240     # symmetric paths
241     mxMatrix(
242         type="Symm", 
243         nrow=7, 
244         ncol=7, 
245         values=c(1,0,0,0,0,0,0,
246                  0,1,0,0,0,0,0,
247                  0,0,1,0,0,0,0,
248                  0,0,0,1,0,0,0,
249                  0,0,0,0,1,0,0,
250                  0,0,0,0,0,1,0,
251                  0,0,0,0,0,0,1),
252         free=c(T, F, F, F, F, F, F,
253                F, T, F, F, F, F, F,
254                F, F, T, F, F, F, F,
255                F, F, F, T, F, F, F,
256                F, F, F, F, T, F, F,
257                F, F, F, F, F, T, F,
258                F, F, F, F, F, F, T),
259         labels=c("e1", NA,   NA,   NA,   NA,   NA,   NA,
260                  NA, "e2",   NA,   NA,   NA,   NA,   NA,
261                  NA,   NA, "e3",   NA,   NA,   NA,   NA,
262                  NA,   NA,   NA, "e4",   NA,   NA,   NA,
263                  NA,   NA,   NA,   NA, "e5",   NA,   NA,
264                  NA,   NA,   NA,   NA,   NA, "e6",   NA,
265                  NA,   NA,   NA,   NA,   NA,   NA, "varF1"),
266         byrow=TRUE,
267         name="S"
268     )
269       
270 The third matrix in our RAM model is the **F** or filter matrix. Our data contains six observed variables, but the **A** and **S** matrices contain seven rows and columns. For our model to define the covariances present in our data, we must have some way of projecting the relationships defined in the **A** and **S** matrices onto our data. The **F** matrix filters the latent variables out of the expected covariance matrix, and can also be used to reorder variables. 
271
272 The **F** matrix will always contain the same number of rows as manifest variables and columns as total (manifest and latent) variables. If the manifest variables in the **A** and **S** matrices precede the latent variables and are in the same order as the data, then the **F** matrix will be the horizontal adhesion of an identity matrix and a zero matrix. This matrix contains no free parameters, and is made with the ``mxMatrix`` function below.
273
274 .. code-block:: r
275
276     # filter matrix
277     mxMatrix(
278         type="Full",
279         nrow=6, 
280         ncol=7,
281         free=FALSE,
282         values=c(1,0,0,0,0,0,0,
283                  0,1,0,0,0,0,0,
284                  0,0,1,0,0,0,0,
285                  0,0,0,1,0,0,0,
286                  0,0,0,0,1,0,0,
287                  0,0,0,0,0,1,0),
288         byrow=TRUE,
289         name="F"
290     )
291
292 The last matrix of our model is the **M** matrix, which defines the means and intercepts for our model. This matrix describes all of the regressions on the constant in a path model, or the means conditional on the means of exogenous variables. This matrix contains a single row, and one column for every manifest and latent variable in the model. In our model, the latent variable has a constrained mean of zero, while the manifest variables have freely estimated means, labeled ``"meanx1"`` through ``"meanx6"``.
293
294 .. code-block:: r
295
296     # means
297     mxMatrix(
298         type="Full", 
299         nrow=1, 
300         ncol=7,
301         values=c(1,1,1,1,1,1,0),
302         free=c(T,T,T,T,T,T,F),
303         labels=c("meanx1","meanx2","meanx3","meanx4","meanx5","meanx6",NA),
304         name="M"
305     )
306
307 The final parts of this model are the expectation function and the fit function. The expectation defines how the specified matrices combine to create the expected covariance matrix of the data.  The fit defines how the expectation is compared to the data to create a single scalar number that is minimized. In a RAM specified model, the expected covariance matrix is defined as:       
308           
309 .. math::
310    :nowrap:
311    
312    \begin{eqnarray*} 
313    ExpCovariance = F * (I - A)^{-1} * S * ((I - A)^{-1})' * F'
314    \end{eqnarray*}        
315
316 The expected means are defined as:
317
318 .. math::
319    :nowrap:
320    
321    \begin{eqnarray*} 
322    ExpMean = F * (I - A)^{-1} * M 
323    \end{eqnarray*} 
324
325 The free parameters in the model can then be estimated using maximum likelihood for covariance and means data, and full information maximum likelihood for raw data. Although users may define their own expected covariance matrices using ``mxExpectationNormal`` and other functions in OpenMx, the ``mxExpectationRAM`` function computes the expected covariance and means matrices when the **A**, **S**, **F** and **M** matrices are specified. The **M** matrix is required both for raw data and for covariance or correlation data that includes a means vector.  The ``mxExpectationRAM`` function takes four arguments, which are the names of the **A**, **S**, **F** and **M** matrices in your model.  The ``mxFitFunctionML`` yields maximum likelihood estimates of structural equation models.  It uses full information maximum likelihood when the data are raw.
326
327 .. code-block:: r
328
329     mxExpectationRAM("A", "S", "F", "M"),
330     mxFitFunctionML()
331
332 The model now includes an observed covariance matrix (i.e., data), model matrices, an expectation function, and a fit function.  So the model has all the required elements to define the expected covariance matrix and estimate parameters.
333
334 The model can now be run using the ``mxRun`` function, and the output of the model can be accessed from the ``@output`` slot of the resulting model.  A summary of the output can be reached using ``summary()``.
335
336 .. code-block:: r
337
338     oneFactorFit <- mxRun(oneFactorModel)
339
340     oneFactorFit@output
341
342     summary(oneFactorFit)
343     
344     
345 Rather than specifying the model using RAM notation, we can also write the model explicitly with self-declared matrices, matching the formula for the expected mean and covariance structure of the one factor model:
346
347 .. math::
348    :nowrap:
349    
350    \begin{eqnarray*} 
351    mu_x = varMeans + (facLoadings * facMeans)'
352    sigma_x = facLoadings * facVariances * facLoadings' + resVariances
353    \end{eqnarray*}
354
355 We start with displaying the complete script.  Note that we have used the succinct form of coding and that the ``mxData`` command did not change.
356
357 .. code-block:: r
358
359     oneFactorModel <- mxModel("Common Factor Model Matrix Specification", 
360         mxData( observed=myFADataRaw, type="raw" ),
361         mxMatrix( type="Full", nrow=6, ncol=1, values=1, free=c(F,T,T,T,T,T), 
362             labels=c("l1","l2","l3","l4","l5","l6"), 
363             name="facLoadings" ),
364         mxMatrix( type="Symm", nrow=1, ncol=1, values=1, free=T, 
365             labels="varF1", 
366             name="facVariances" ),
367         mxMatrix( type="Diag", nrow=6, ncol=6, free=T, values=1, 
368             labels=c("e1","e2","e3","e4","e5","e6"), 
369             name="resVariances" ),
370         mxMatrix( type="Full", nrow=1, ncol=6, values=1, free=T,
371             labels=c("meanx1","meanx2","meanx3","meanx4","meanx5","meanx6"), 
372             name="varMeans" ),
373         mxMatrix( type="Full", nrow=1, ncol=1, values=0, free=F, 
374             name="facMeans" ),
375         mxAlgebra( expression= facLoadings %&% facVariances + resVariances, 
376             name="expCov" ),
377         mxAlgebra(expression= varMeans + t(facLoadings %*% facMeans), 
378             name="expMean" ),
379         mxExpectationNormal( covariance="expCov", means="expMean", dimnames=manifestVars),
380         mxFitFunctionML()
381     )
382     oneFactorFit<-mxRun(oneFactorModel)
383
384 The first ``mxMatrix`` statement declares a ``Full`` **6x1** matrix of factor loadings to be estimated, called "facLoadings".  We fix the first factor loading to 1 for identification.  Even though we specify just one start value of 1 which is recycled for each of the elements in the matrix, it becomes the fixed value for the first factor loading and the start value for the other factor loadings.  The second ``mxMatrix`` is a ``symmetric`` **1x1** which estimates the variance of the factor, named "facVariances".  The third ``mxMatrix`` is a ``Diag`` **6x6** matrix for the residual variances, named "resVariances".  The fourth ``mxMatrix`` is a ``Full`` **1x6** matrix of free elements for the means of the observed variables, called "varMeans".  The fifth ``mxMatrix`` is a ``Full`` **1x1** matrix with a fixed value of zero for the factor mean, named "facMeans".  
385
386 We then use two algebra statements to work out the expected mean and covariance matrices.  Note that the formula's for the expression of the expected covariance and the expected mean vector map directly on to the mathematical equations.  The arguments for the ``mxExpectationNormal`` function now refer to these algebras for the expected covariance and expected means.  The ``dimnames`` are used to map them onto the observed variables.  The fit function compares the expectation and the observation (i.e. data) to optimize free parameters.
387
388
389 Two Factor Model
390 ----------------
391
392 The common factor model can be extended to include multiple latent variables. The model for any person and path diagram of the common factor model for a set of variables :math:`x_{1}` - :math:`x_{3}` and :math:`y_{1}` - :math:`y_{3}` are given below.
393
394 .. math::
395    :nowrap:
396    
397    \begin{eqnarray*} 
398    x_{ij} = \mu_{j} + \lambda_{j} * \eta_{1i} + \epsilon_{ij}\\
399    y_{ij} = \mu_{j} + \lambda_{j} * \eta_{2i} + \epsilon_{ij}
400    \end{eqnarray*}
401
402 .. image:: graph/TwoFactorModel.png
403     :height: 2in
404
405 Our model contains 21 parameters (6 manifest variances, six manifest means, six factor loadings, two factor variances and one factor covariance), but each factor requires one identification constraint. Like in the common factor model above, we will constrain one factor loading for each factor to a value of one. As such, this model contains 19 parameters. The means and covariance matrix for six observed variables contain 27 degrees of freedom, and thus our model contains 8 degrees of freedom. 
406
407 The data for the two factor model can be found in the ``myFAData`` files introduced in the common factor model. For this model, we will select three x variables (``x1-x3``) and three y variables (``y1-y3``).d
408
409 .. code-block:: r
410
411     twoFactorRaw <- myFADataRaw[,c("x1", "x2", "x3", "y1", "y2", "y3")]
412
413     twoFactorCov <- myFADataCov[c("x1","x2","x3","y1","y2","y3"),
414                                 c("x1","x2","x3","y1","y2","y3")]
415
416     twoFactorMeans <- myFADataMeans[c(1:3,7:9)]
417   
418 Specifying the two factor model is virtually identical to the single factor case. The ``mxData`` function has been changed to reference the appropriate data, but is identical in usage. We've added a second latent variable, so the **A** and **S** matrices are now of order 8x8. Similarly, the **F** matrix is now of order 6x8 and the **M** matrix of order 1x8. The ``mxExpectationRAM`` has not changed. The code for our two factor model looks like this:
419
420 .. code-block:: r
421
422     twoFactorModel <- mxModel("Two Factor Model Matrix Specification", 
423         type="RAM",
424         mxData(
425             observed=twoFactorRaw, 
426             type="raw",
427         ),
428         # asymmetric paths
429         mxMatrix(
430             type="Full",
431             nrow=8, 
432             ncol=8,
433             values=c(0,0,0,0,0,0,1,0,
434                      0,0,0,0,0,0,1,0,
435                      0,0,0,0,0,0,1,0,
436                      0,0,0,0,0,0,0,1,
437                      0,0,0,0,0,0,0,1,
438                      0,0,0,0,0,0,0,1,
439                      0,0,0,0,0,0,0,0,
440                      0,0,0,0,0,0,0,0),
441             free=c(F, F, F, F, F, F, F, F,
442                    F, F, F, F, F, F, T, F,
443                    F, F, F, F, F, F, T, F,
444                    F, F, F, F, F, F, F, F,
445                    F, F, F, F, F, F, F, T,
446                    F, F, F, F, F, F, F, T,
447                    F, F, F, F, F, F, F, F,
448                    F, F, F, F, F, F, F, F),
449             labels=c(NA,NA,NA,NA,NA,NA,"l1", NA,
450                      NA,NA,NA,NA,NA,NA,"l2", NA,
451                      NA,NA,NA,NA,NA,NA,"l3", NA,
452                      NA,NA,NA,NA,NA,NA, NA,"l4",
453                      NA,NA,NA,NA,NA,NA, NA,"l5",
454                      NA,NA,NA,NA,NA,NA, NA,"l6",
455                      NA,NA,NA,NA,NA,NA, NA, NA,
456                      NA,NA,NA,NA,NA,NA, NA, NA),
457             byrow=TRUE,
458             name="A"
459         ),
460         # symmetric paths
461         mxMatrix(
462             type="Symm", 
463             nrow=8, 
464             ncol=8, 
465             values=c(1,0,0,0,0,0, 0, 0,
466                      0,1,0,0,0,0, 0, 0,
467                      0,0,1,0,0,0, 0, 0,
468                      0,0,0,1,0,0, 0, 0,
469                      0,0,0,0,1,0, 0, 0,
470                      0,0,0,0,0,1, 0, 0,
471                      0,0,0,0,0,0, 1,.5,
472                      0,0,0,0,0,0,.5, 1),
473             free=c(T, F, F, F, F, F, F, F,
474                    F, T, F, F, F, F, F, F,
475                    F, F, T, F, F, F, F, F,
476                    F, F, F, T, F, F, F, F,
477                    F, F, F, F, T, F, F, F,
478                    F, F, F, F, F, T, F, F,
479                    F, F, F, F, F, F, T, T,
480                    F, F, F, F, F, F, T, T),
481             labels=c("e1", NA,   NA,   NA,   NA,   NA,    NA,    NA,
482                      NA, "e2",   NA,   NA,   NA,   NA,    NA,    NA,
483                      NA,   NA, "e3",   NA,   NA,   NA,    NA,    NA,
484                      NA,   NA,   NA, "e4",   NA,   NA,    NA,    NA,
485                      NA,   NA,   NA,   NA, "e5",   NA,    NA,    NA,
486                      NA,   NA,   NA,   NA,   NA, "e6",    NA,    NA,
487                      NA,   NA,   NA,   NA,   NA,   NA, "varF1", "cov",
488                      NA,   NA,   NA,   NA,   NA,   NA, "cov", "varF2"),
489             byrow=TRUE,
490             name="S"
491         ),
492         # filter matrix
493         mxMatrix(
494             type="Full",
495             nrow=6, 
496             ncol=8,
497             free=F,
498             values=c(1,0,0,0,0,0,0,0,
499                      0,1,0,0,0,0,0,0,
500                      0,0,1,0,0,0,0,0,
501                      0,0,0,1,0,0,0,0,
502                      0,0,0,0,1,0,0,0,
503                      0,0,0,0,0,1,0,0),
504             byrow=T,
505             name="F"
506         ),
507         # means
508         mxMatrix(
509             type="Full",
510             nrow=1, 
511             ncol=8,
512             values=c(1,1,1,1,1,1,0,0),
513             free=c(T,T,T,T,T,T,F,F),
514             labels=c("meanx1","meanx2","meanx3",
515                      "meanx4","meanx5","meanx6",
516                       NA,NA),
517             name="M"
518         ),
519         mxExpectationRAM("A","S","F","M"),
520         mxFitFunctionML()
521     )
522
523 The four ``mxMatrix`` functions have changed slightly to accomodate the changes in the model. The **A** matrix, shown below, is used to specify the regressions of the manifest variables on the factors. The first three manifest variables (``"x1"``-``"x3"``) are regressed on ``"F1"``, and the second three manifest variables (``"y1"``-``"y3"``) are regressed on ``"F2"``. We must again constrain the model to identify and scale the latent variables, which we do by constraining the first loading for each latent variable to a value of one.
524
525 .. code-block:: r
526
527     # asymmetric paths
528     mxMatrix(
529         type="Full",
530         nrow=8, 
531         ncol=8,
532         values=c(0,0,0,0,0,0,1,0,
533                  0,0,0,0,0,0,1,0,
534                  0,0,0,0,0,0,1,0,
535                  0,0,0,0,0,0,0,1,
536                  0,0,0,0,0,0,0,1,
537                  0,0,0,0,0,0,0,1,
538                  0,0,0,0,0,0,0,0,
539                  0,0,0,0,0,0,0,0),
540         free=c(F, F, F, F, F, F, F, F,
541                F, F, F, F, F, F, T, F,
542                F, F, F, F, F, F, T, F,
543                F, F, F, F, F, F, F, F,
544                F, F, F, F, F, F, F, T,
545                F, F, F, F, F, F, F, T,
546                F, F, F, F, F, F, F, F,
547                F, F, F, F, F, F, F, F),
548         labels=c(NA,NA,NA,NA,NA,NA,"l1", NA,
549                  NA,NA,NA,NA,NA,NA,"l2", NA,
550                  NA,NA,NA,NA,NA,NA,"l3", NA,
551                  NA,NA,NA,NA,NA,NA, NA,"l4",
552                  NA,NA,NA,NA,NA,NA, NA,"l5",
553                  NA,NA,NA,NA,NA,NA, NA,"l6",
554                  NA,NA,NA,NA,NA,NA, NA, NA,
555                  NA,NA,NA,NA,NA,NA, NA, NA),
556         byrow=TRUE,
557         name="A"
558     )
559       
560 The **S** matrix has an additional row and column, and two additional parameters. For the two factor model, we must add a variance term for the second latent variable and a covariance between the two latent variables.  
561       
562 .. code-block:: r
563
564     # symmetric paths
565     mxMatrix(
566         type="Symm", 
567         nrow=8, 
568         ncol=8, 
569         values=c(1,0,0,0,0,0, 0, 0,
570                  0,1,0,0,0,0, 0, 0,
571                  0,0,1,0,0,0, 0, 0,
572                  0,0,0,1,0,0, 0, 0,
573                  0,0,0,0,1,0, 0, 0,
574                  0,0,0,0,0,1, 0, 0,
575                  0,0,0,0,0,0, 1,.5,
576                  0,0,0,0,0,0,.5, 1),
577         free=c(T, F, F, F, F, F, F, F,
578                F, T, F, F, F, F, F, F,
579                F, F, T, F, F, F, F, F,
580                F, F, F, T, F, F, F, F,
581                F, F, F, F, T, F, F, F,
582                F, F, F, F, F, T, F, F,
583                F, F, F, F, F, F, T, T,
584                F, F, F, F, F, F, T, T),
585         labels=c("e1", NA,   NA,   NA,   NA,   NA,    NA,    NA,
586                  NA, "e2",   NA,   NA,   NA,   NA,    NA,    NA,
587                  NA,   NA, "e3",   NA,   NA,   NA,    NA,    NA,
588                  NA,   NA,   NA, "e4",   NA,   NA,    NA,    NA,
589                  NA,   NA,   NA,   NA, "e5",   NA,    NA,    NA,
590                  NA,   NA,   NA,   NA,   NA, "e6",    NA,    NA,
591                  NA,   NA,   NA,   NA,   NA,   NA, "varF1", "cov",
592                  NA,   NA,   NA,   NA,   NA,   NA, "cov", "varF2"),
593         byrow=TRUE,
594         name="S"
595     )
596       
597 The **F** and **M** matrices contain only minor changes. The **F** matrix is now of order 6x8, but the additional column is simply a column of zeros. The **M** matrix contains an additional column (with only a single row), which contains the mean of the second latent variable. As this model does not contain a parameter for that latent variable, this mean is constrained to zero.
598
599 The model is now ready to run using the ``mxRun`` function, and the output of the model can be accessed from the ``@output`` slot of the resulting model.  A summary of the output can be reached using ``summary()``.
600
601 These models may also be specified using paths instead of matrices. See :ref:`factoranalysis-path-specification` for path specification of these models.