You are here

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

2 posts / 0 new
Last post
dadrivr's picture
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

mhunter's picture
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