# Constraining loadings on factor so average of loadings equals 1 and average of intercepts equals 0

2 posts / 0 new
Offline
Joined: 01/19/2010 - 23:28
Constraining loadings on factor so average of loadings equals 1 and average of intercepts equals 0

I am running a CFA and would like to use the "effects coding" method of identification described by Little, Slegers, and Card (2006). In the effects coding method, the loadings of a factor are constrained so that the average of the loadings equals 1 and the average of the intercepts equals 0. How can I do this with OpenMx? I imagine it involves mxConstraint or mxAlgebra, but am not sure where to begin. Here's a small example of a model that I'd like to modify to use effects coding:

oneFactorModel <- mxModel("CFA",
type="RAM",
manifestVars=c("x1","x2","x3","x4","x5","x6"),
latentVars="LatentFactor1",

                      #Data
mxData(observed=myFADataRaw, type="raw"),

#Residual Variances
mxPath(from=c("x1","x2","x3","x4","x5","x6"),
arrows=2,
free=TRUE,
values=c(1,1,1,1,1,1),
labels=c("e1","e2","e3","e4","e5","e6")),

#Latent Variance
mxPath(from="LatentFactor1",
arrows=2,
free=TRUE,
values=1,
labels ="varF1"),

#Factor Loadings
mxPath(from="LatentFactor1",
to=c("x1","x2","x3","x4","x5","x6"),
arrows=1,
free=c(FALSE,TRUE,TRUE,TRUE,TRUE,TRUE),
values=c(1,1,1,1,1,1),
labels =c("loading1","loading2","loading3","loading4","loading5","loading6")),

#Means
mxPath(from="one",
to=c("x1","x2","x3","x4","x5","x6","LatentFactor1"),
arrows=1,
free=c(TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,FALSE),
values=c(1,1,1,1,1,1,0),
labels =c("meanx1","meanx2","meanx3","meanx4","meanx5","meanx6",NA)))


Thanks!
-Isaac

Offline
Joined: 07/31/2009 - 15:26
Example

Here's an example. It takes the frontpage model, and identifies it by fixing the mean of the factor loadings to be 1. This is done by setting one of the loadings to be a function of the others. It could also be done with an mxConstraint, but using an mxAlgebra will make it run a bit faster.

require(OpenMx)
data(demoOneFactor)
manifests <- names(demoOneFactor)
latents <- c("G")
nvar <- length(manifests)
llab <- paste0('load', 1:nvar)
llab[nvar] <- 'loadAlg[1,1]' # label of one loading is set to be an algebra
factorModel <- mxModel("One Factor",
type="RAM",
manifestVars=manifests,
latentVars=latents,
mxPath(from=latents, to=manifests,
free=c(rep(TRUE, nvar-1), FALSE), labels=llab),
mxAlgebra(1*5 - (load1 + load2 + load3 + load4), 'loadAlg'),
# 1 is the desired value for the mean loading
# 5 is the number of loadings
# We define the fifth loading as a function of the other four
mxPath(from=manifests, arrows=2),
mxPath(from=latents, arrows=2, values=1.0),
mxData(observed=cov(demoOneFactor), type="cov", numObs=500))
summary(factorRun <- mxRun(factorModel))
L <- mxEval(A, factorRun)[1:5,6]
L
mean(L)

Here's the output.

Running One Factor
Summary of One Factor

free parameters:
name matrix row col   Estimate   Std.Error A
1              load1      A  x1   G 0.66701648 0.013915176
2              load2      A  x2   G 0.84589835 0.013378773
3              load3      A  x3   G 0.96947636 0.013743159
4              load4      A  x4   G 1.18030772 0.013650689
5  One Factor.S[1,1]      S  x1  x1 0.04081421 0.002812720
6  One Factor.S[2,2]      S  x2  x2 0.03802002 0.002805797
7  One Factor.S[3,3]      S  x3  x3 0.04082720 0.003152312
8  One Factor.S[4,4]      S  x4  x4 0.03938708 0.003408879
9  One Factor.S[5,5]      S  x5  x5 0.03628709 0.003678561
10 One Factor.S[6,6]      S   G   G 0.35452043 0.022940191

observed statistics:  15
estimated parameters:  10
degrees of freedom:  5
fit value ( -2lnL units ):  -3648.281
saturated fit value ( -2lnL units ):  -3655.665
number of observations:  500
chi-square:  X2 ( df=5 ) = 7.384002,  p = 0.1936117
Information Criteria:
|  df Penalty  |  Parameters Penalty  |  Sample-Size Adjusted
AIC:      -2.615998               27.38400                       NA
BIC:     -23.689038               69.53008                 37.78947
CFI: 0.9993583
TLI: 0.9987166   (also known as NNFI)
RMSEA:  0.03088043  [95% CI (0, 0.08139005)]
Prob(RMSEA <= 0.05): 0.7142842
OpenMx does not recommend using GFI, AGFI, NFI (aka Bentler-Bonett), or SRMR:
See help(mxSummary) for why.
timestamp: 2015-06-23 15:21:42
Wall clock time (HH:MM:SS.hh): 00:00:00.06
OpenMx version number: 2.2.4.53
Need help?  See help(mxSummary)

> L <- mxEval(A, factorRun)[1:5,6]
> L
x1        x2        x3        x4        x5
0.6670165 0.8458983 0.9694764 1.1803077 1.3373011
> mean(L)
[1] 1
Log in or register to post comments