mxFitFunctionMultigroup {OpenMx}R Documentation

Create a fit function used to fit multiple-group models


mxFitFunctionMultigroup creates a fit function consisting of the sum of the fit statistics from a list of submodels provided. Thus, it aggregates fit statistics from multiple submodels.

This total provides the optimization target for fitting a multi-group model.

In addition to being more compact and readable, using mxFitFunctionMultigroup has additional side effects which are valuable for multi-group modeling.

First, it aggregates analytic derivative calculations.

Second, it allows mxRefModels to compute saturated models for raw data, as this function can learn which are the constituent submodels.

Third, and finally, it allows mxCheckIdentification to evaluate the local identification of the multigroup model.


mxFitFunctionMultigroup(groups, ..., verbose = 0L)



vector of submodel names (strings)


Not used. Forces subsequent arguments to be specified by name.


the level of debugging output


Conceptually, mxFitFunctionMultigroup is equivalent to summing the subModel objectives in an mxAlgebra, and using an mxFitFunctionAlgebra to optimize the model based on this summed likelihood.

e.g. this 1-line call to mxFitFunctionMultigroup:

mxFitFunctionMultigroup(c("model1", "model2"))

is equivalent to the following pair of statements:

mxAlgebra(name = "myAlgebra", model1.objective + model2.objective)


Note: If needed, you can refer to the algebra generated by mxFitFunctionMultigroup as:


Where "modelName" is the name of the container or supermodel.

See Also

Other fit functions: mxFitFunctionML, mxFitFunctionWLS, mxFitFunctionAlgebra, mxFitFunctionGREML, mxFitFunctionR, mxFitFunctionRow

More information about the OpenMx package may be found here.


# Brief non-running example
mxFitFunctionMultigroup(c("model1", "model2")) # names of sub-models to be jointly optimised

# ===========================================
# = Longer, fully featured, running example =
# ===========================================

# Create and fit a model using mxMatrix, mxExpectationRAM, mxFitFunctionML,
# and mxFitFunctionMultigroup.
# The model is multiple group regression.
# Only the residual variances are allowed to differ across groups.


# Simulate some data

# Group 1
N1 = 100
x = rnorm(N1, mean= 0, sd= 1)
y = 0.5*x + rnorm(N1, mean= 0, sd= 1)
ds1 <- data.frame(x, y)
dsNames <- names(ds1)

# Group 2: y has greater variance; x & y slightly lower correlation...
N2= 150
x= rnorm(N2, mean= 0, sd= 1)
y= 0.5*x + rnorm(N2, mean= 0, sd= sqrt(1.5))
ds2 <- data.frame(x, y)

# Define the matrices (A matrix implementation of 2 RAM models)

I <- mxMatrix(name="I", type="Iden", nrow=2, ncol=2)
M <- mxMatrix(name = "M", type = "Full", nrow = 1, ncol = 2, values=0,
              free=TRUE, labels=c("Mean_x", "Mean_y"))
# A matrix containing a path "b" of x on y
A <- mxMatrix(name = "A", type = "Full", nrow = 2, ncol = 2, values=c(0,1,0,0),
              free=c(FALSE,TRUE,FALSE,FALSE), labels=c(NA, "b", NA, NA))

S1 <- mxMatrix(name = "S", type = "Diag", nrow = 2, ncol = 2, values=1,
              free=TRUE, labels=c("Var_x", "Resid_y_group1"))
S2 <- mxMatrix(name = "S", type = "Diag", nrow = 2, ncol = 2, values=1,
              free=TRUE, labels=c("Var_x", "Resid_y_group2"))

# Define the expectation
expect <- mxExpectationRAM('A', 'S', 'I', 'M', dimnames= dsNames)

# Choose a fit function
fitFunction <- mxFitFunctionML(rowDiagnostics=TRUE)
# Also return row likelihoods (the fit function value is still 1x1)

# Multiple-group fit function sums the model likelihoods
# from its component models
mgFitFun <- mxFitFunctionMultigroup(c('g1model', 'g2model'))

# Define model 1 and model 2
m1 = mxModel(model="g1model",
	M, S1, A, I, expect, fitFunction,
    mxData(cov(ds1), type="cov", numObs=N1, means=colMeans(ds1))
m2 = mxModel(model="g2model",
	M, S2, A, I, expect, fitFunction,
    mxData(cov(ds2), type="cov", numObs=N2, means=colMeans(ds2))

mg <- mxModel(model='multipleGroup', m1, m2, mgFitFun)
# note!: Paths with the same name in both submodels are
# constrained to the same value across models. i.e.,
# b has only 1 value, as does Var_x. But Resid_y can take distinct
# values in the two groups.

# Fit the model and print a summary
mg <- mxRun(mg)

# Examine fit function results
# Fit in -2lnL units)
mxEval(fitfunction, mg)

# Fit function results for each submodel:
mxEval(g1model.fitfunction, mg)
mxEval(g2model.fitfunction, mg)

mg2 = omxSetParameters(mg,
  labels = c("Resid_y_group1", "Resid_y_group2"),
  newlabels = "Resid_y", name = "equated")
mg2 = omxAssignFirstParameters(mg2)
mg2 = mxRun(mg2)

mxCompare(mg, mg2)
# ouch... that was a significant loss in fit: the residuals definately are larger in group2!

[Package OpenMx version 2.21.11 Index]