Copyright © 2007-2017 The OpenMx Project

Published on *OpenMx* (http://openmx.ssri.psu.edu)

Wiki home page [1]

- Extensible Open Source (!) code, multiprogrammer model
- Parallel computation
- R environment
- Joint ordinal/continuous
- IRT models
- Bigger models
- GREML, RAM, LISREL specs

If you have questions not answers, then add those here: That's how a wiki works.

There are a number of changes between Mx and OpenMx, mostly easy to learn.

You will still need to read in data, propose algebra, possibly create more than one group, estimate the model, and post-process and display the results. Much of the structure of an mx script translates easily into OpenMx, just with more structure. COnstraints becomes mxConstraint(), data statements such as SElect are replaced with calls to mxData(), and DEfinition-variables are implemented by . COvariance and MEans statements are replaced with calls to mxAlgebra(), mxMLObjective(), mxRAMObjective(), or mxFIMLObjective.. etc.

R has much more powerful access to data than did mx, including reading a range of formats, not barfing on names, and accessing data from a range of locations, including over the web etc.

You will need to replace Mx1.x Data, Missing, file, and SELECT statements with some R code to read in the data and a call of mxData()

This, for instance:

Data NI= 13 ! nr of inputvars per family Missing=-1.000 ! missing values must be exactly this string "-1.000" RE file=example.dat ! read in raw datafile, must be in same directory and not too long a path

would become:

# Read in data (could be a URL. Names are in the file (Header =T))data <- read.table("example.dat", header=TRUE, sep="\t")mxData(data, type="raw") # apply the data to a model

In mx 1.x, to model a variable at the individual level, you DEfined these variables from among the SElected variables.

In OpenMx, you no longer need to explicitly DEfine variables. Instead prefixing the name of a path or matrix label with "data." causes OpenMx to evaluate the matrix fit on subject-level data.

OpenMx automatically removes any such data.variables from the variables being models, and reserves it as a definition variable.

PS: this explains why "." style names (though legal in R) are illegal in OpenMx.

Mx used groups to structure its analyses. The comparable structure in OpenMx is the model. Because R provides a lot of functionality, the mapping is not complete. This is clearest in mx groups used for standardising results rather than defining a SEM model. These will often be replaced entirely with manipulation of the data in regular R code. In multi-group models, mx groups will often be mapped directly into OpenMx (sub-)models. Thus a two-group twin design may well be implemented with two models in OpenMx, contained in a parent model. mx scripts often begin with a "Define" group specifying a set of matrices, and this can usually be translated directly to an OpenMx model.

```
<h4>Operators</h4>
```

OpenMx uses R-style operators, which entails some very straightforward find-and-replace type changes.

Two very common functions: matrix multiplication and transposition, signified by "*" and "~" in old Mx, need to be changed to %*% and t(x) respectively.

A full list of function mappings is provided here operators and functions [2].

The other major change in OpenMx algebra is the addressing of symbols. For instance, in Mx 1.x, to include a matrix from another group in an algebra, you would import the matrix into the second group, then refer to it by its name. In OpenMx, you simply refer to objects in other models by their full name, i.e., to refer to matrix "A" in model "mz", you simply say "mz.A".

So if in mx you said

**Begin Matrices** = **Group** 1

**Means** M ;

In OpenMx, you would say

"**mxFIMLObjective**("expMean", "name.M"),

where "name" is the name of what was group 1.

To compare fits between models use mxCompare() [3].

To set the saturated 2*LL, you say:

summary(modelOut, SaturatedLikelihood=300)

The result of an MxRun is itself a model, populated with the final estimated values of the matrices and algebras you proposed.

So you can say:

fit<- mxRun(model) fit@matrices$a@values=0 fit@matrices$a@free=FALSE fit2<- mxRun(fit)

Options like NDecimals have not been re-implemented in OpenMx, as these are handled flexibly in R using round() etc.

Where you would previously have called \part(A,B) to extract the rectangle described by B out of matrix A, now you can use algebraic matrix labels [4] and Rs matrix addressing to meet these needs.

Numerical estimates of Standard Errors are part of the standard Summary().

Maximum likelihood confidence intervals are requested by including mxCI() [5] in your model, then mxRun(model, intervals=T) [6] to compute the CI's (which are then shown in the summary() )

**Links**

[1] http://openmx.psyc.virginia.edu/wiki/main-page

[2] http://openmx.psyc.virginia.edu/wiki/matrix-operators-and-functions

[3] http://openmx.psyc.virginia.edu/wiki/mxCompare-help

[4] http://openmx.psyc.virginia.edu/wiki/mxmatrix-help#Square_bracket_substitution

[5] http://openmx.psyc.virginia.edu/wiki/mxCI-help

[6] http://openmx.psyc.virginia.edu/wiki/mxRun-help