effects-coding (constrain factor loadings)

1,610 views
Skip to first unread message

René

unread,
Sep 14, 2012, 10:40:15 AM9/14/12
to lav...@googlegroups.com

Dear lavaan-group,

I'm trying to run a multigroup-CFA with effects-coding, e.g. for each construct constrain the factor loadings of the measured indicators to average to one (like suggested by Card & Little In Studying Aggression with Structural Equation Modeling ). But it ends up beeing singular. What has to be changed to make this work?


library(lavaan)

HS.model <- '

visual   =~ c(l11,l11)*x1 + c(l21,l21)*x2 + c(l31,l31)*x3

textual  =~ c(l12,l12)*x4 + c(l22,l22)*x5 + c(l32,l32)*x6

speed   =~ c(l13,l13)*x4 + c(l23,l23)*x5 + c(l33,l33)*x6


l11 == 3 - l21 - l31

l12 == 3 - l22 - l32

l13 == 3 - l23 - l33'

fit <-

lavaan( model = HS.model,

data = HolzingerSwineford1939,

auto.var = TRUE,

auto.fix.first = FALSE,

group = "school" ,

group.equal = c("loadings")

)


Error in solve.default(E) :

… singular


thanks in advance,

kind regards,

René


sessionInfo()


R version 2.15.1 (2012-06-22)

Platform: i686-pc-linux-gnu (32-bit)


locale:

[1] LC_CTYPE=de_DE.UTF-8 LC_NUMERIC=C

[3] LC_TIME=de_DE.UTF-8 LC_COLLATE=de_DE.UTF-8

[5] LC_MONETARY=de_DE.UTF-8 LC_MESSAGES=de_DE.UTF-8

[7] LC_PAPER=C LC_NAME=C

[9] LC_ADDRESS=C LC_TELEPHONE=C

[11] LC_MEASUREMENT=de_DE.UTF-8 LC_IDENTIFICATION=C


attached base packages:

[1] stats graphics grDevices utils datasets methods base


other attached packages:

[1] lavaan_0.4-14


loaded via a namespace (and not attached):

[1] stats4_2.15.1 tools_2.15.1



yrosseel

unread,
Sep 14, 2012, 12:27:45 PM9/14/12
to lav...@googlegroups.com
On 09/14/2012 04:40 PM, Ren� wrote:
> Dear lavaan-group,
>
> I'm trying to run a multigroup-CFA with effects-coding, e.g. for each
> construct constrain the factor loadings of the measured indicators to
> average to one (like suggested by Card & Little In Studying Aggression
> with Structural Equation Modeling ). But it ends up beeing singular.
> What has to be changed to make this work?
>
>
> library(lavaan)
>
> HS.model <- '
> visual =~ c(l11,l11)*x1 + c(l21,l21)*x2 + c(l31,l31)*x3
> textual =~ c(l12,l12)*x4 + c(l22,l22)*x5 + c(l32,l32)*x6
> speed =~ c(l13,l13)*x4 + c(l23,l23)*x5 + c(l33,l33)*x6
>
> l11 == 3 - l21 - l31
> l12 == 3 - l22 - l32
> l13 == 3 - l23 - l33'
>
> fit <-
> lavaan( model = HS.model,
> data = HolzingerSwineford1939,
> auto.var = TRUE,
> auto.fix.first = FALSE,
> group = "school" ,
> group.equal = c("loadings")
> )
>
>
> Error in solve.default(E) :

Several things. First, for the 'speed' factor, the indicators are x7, x8
and x9 (not x4, x5 and x6). Second, you are using the lavaan() function.
This means you need to specify _all_ the parameters, either in the
syntax, or by using various auto.* and other flags). You forgot the
intercepts of the observed variables, and the covariances among the
exogenous latent variables:

HS.model <- '
visual =~ c(l11,l11)*x1 + c(l21,l21)*x2 + c(l31,l31)*x3
textual =~ c(l12,l12)*x4 + c(l22,l22)*x5 + c(l32,l32)*x6
speed =~ c(l13,l13)*x7 + c(l23,l23)*x8 + c(l33,l33)*x9

l11 == 3 - l21 - l31
l12 == 3 - l22 - l32
l13 == 3 - l23 - l33'

fit <- lavaan(model = HS.model, data = HolzingerSwineford1939,
auto.var = TRUE, auto.fix.first = FALSE,
group = "school", auto.cov.lv.x = TRUE,
int.ov.free = TRUE)

> fit
lavaan (0.5-10) converged normally after 354 iterations

Number of observations per group
Pasteur 156
Grant-White 145

Estimator ML
Minimum Function Chi-square 124.044
Degrees of freedom 54
P-value 0.000

Chi-square for each group:

Pasteur 68.824
Grant-White 55.219


Hope this helps,

Yves.





Rene Mayer

unread,
Sep 16, 2012, 4:29:35 AM9/16/12
to lav...@googlegroups.com
On 14.09.2012 18:27, yrosseel wrote:
> library(lavaan)
>
> HS.model <- '
> visual =~ c(l11,l11)*x1 + c(l21,l21)*x2 + c(l31,l31)*x3
> textual =~ c(l12,l12)*x4 + c(l22,l22)*x5 + c(l32,l32)*x6
> speed =~ c(l13,l13)*x4 + c(l23,l23)*x5 + c(l33,l33)*x6
>
> l11 == 3 - l21 - l31
> l12 == 3 - l22 - l32
> l13 == 3 - l23 - l33'
>
> fit <-
> lavaan( model = HS.model,
> data = HolzingerSwineford1939,
> auto.var = TRUE,
> auto.fix.first = FALSE,
> group = "school" ,
> group.equal = c("loadings")
> )

Thanks Yves,
yes this helps!
But even with your corrections I'm confused by the following error message

Error in solve.default(E) :
System ist f�r den Rechner singul�r: reziproke Konditionszahl =
1.13637e-21
Warnmeldung:
In estimateVCOV(lavaanModel, samplestats = lavaanSampleStats, options =
lavaanOptions, :
lavaan WARNING: could not compute standard errors!

while it states that it has converged normally.

> fit
lavaan (0.4-14) converged normally after 344 iterations
...

I don't know if this is due to my machine, OS or do I have to provide
starting values.
kind regards,
Ren�


yrosseel

unread,
Sep 16, 2012, 5:01:04 AM9/16/12
to lav...@googlegroups.com
It is due to the version number of lavaan (0.4-14). Please update to the
newest version (0.5-9), where we have changed the way standard errors
are computed in the presence of constraints.

The error in the 0.4-14 was due to the fact that the 'expected
information matrix' (called E in lavaan), was not of full rank, and
could not be inverted.

(I also see now that we don't need to specify the group.equal= argument
in the lavaan call, since the loadings have been fixed already in the
syntax).

Yves.


René Mayer

unread,
Sep 16, 2012, 8:59:40 AM9/16/12
to lav...@googlegroups.com
YAhh, that's reliev everything worked after the update to 0.5-9. It's
really flexible to be able to make those constraints.
the best,
Ren�

Markus Mattsson

unread,
Jun 5, 2013, 6:42:55 AM6/5/13
to lav...@googlegroups.com
Dear Yves & lavaan-group,

I'd like to follow up on this discussion and to consider the case of using effects coding when fitting a CFA model in a single group. I assume the above example could be modified as follows for this purpose:

HS.model.2 <- '
visual  =~ c(l11)*x1 + c(l21)*x2 + c(l31)*x3
textual =~ c(l12)*x4 + c(l22)*x5 + c(l32)*x6
speed   =~ c(l13)*x7 + c(l23)*x8 + c(l33)*x9


l11 == 3 - l21 - l31
l12 == 3 - l22 - l32
l13 == 3 - l23 - l33
'

fit.2 <- lavaan(model = HS.model.2, data = HolzingerSwineford1939,

                 auto.var = TRUE, auto.fix.first = FALSE,
                 auto.cov.lv.x = TRUE,
                 int.ov.free = TRUE)

lavaan then converges normally:

> summary(fit.2)
lavaan (0.5-13) converged normally after 280 iterations

  Number of observations                           301

  Estimator                                         ML
  Minimum Function Test Statistic               85.306
  Degrees of freedom                                24
  P-value (Chi-square)                           0.000


But when I try to obtain modification indices, I get the following error:

> modindices(fit.2)
Error in solve.default(Q22) :
  system is computationally singular: reciprocal condition number = 6.43178e-18

On the other hand, when I try to obtain modification indices when comparing two groups (fitting the model specified by Yves above), the modification indices are computed normally. This is a mystery to me, but perhaps someone in the group could point me in the right direction?

I'm running lavaan 0.5-13 and R version 3.0.1 (2013-05-16) on Platform: x86_64-apple-darwin10.8.0 (64-bit)

Kind regards,

Markus Mattsson

yrosseel

unread,
Jun 6, 2013, 10:06:20 AM6/6/13
to lav...@googlegroups.com
On 06/05/2013 12:42 PM, Markus Mattsson wrote:
> > modindices(fit.2)
> Error in solve.default(Q22) :
> system is computationally singular: reciprocal condition number =
> 6.43178e-18

That is most likely a bug. Q22 is proportional to the information matrix
of the unconstrained free parameters (size: 24x24), but this is not
taking into account the 3 explicit constraints...

In general: I need to figure out how to do a score test if constrained
inference has been used.

Yves.

yrosseel

unread,
Dec 17, 2013, 1:49:09 PM12/17/13
to lav...@googlegroups.com

> But when I try to obtain modification indices, I get the following error:
>
> > modindices(fit.2)
> Error in solve.default(Q22) :
> system is computationally singular: reciprocal condition number =
> 6.43178e-18

This is (finally) fixed in the dev version of lavaan 0.5-16.

Yves.

Amanda Pollitt

unread,
Jun 3, 2014, 2:41:47 PM6/3/14
to lav...@googlegroups.com
I'm trying to do effects coding with no groups and I'm getting an error. Syntax:

allalc.model<-'
w1alc =~ c(l11)*w1use + c(l21)*w1binge + c(l31)*w1prob
w2alc =~ c(l12)*w2use + c(l22)*w2binge + c(l32)*w2prob
w3alc =~ c(l13)*w3use + c(l23)*w3binge + c(l33)*w3prob
w4alc =~ c(l14)*w4use + c(l24)*w4binge + c(l34)*w4prob
w1alc ~~ w2alc + w3alc + w4alc
w2alc ~~ w3alc + w4alc
w3alc ~~ w4alc
w1use ~~ w2use + w3use + w4use
w1binge ~~ w2binge + w3binge + w4binge
w1prob ~~ w2prob + w3prob + w4prob
l11 == 3 - l21 - l31 
l12 == 3 - l22 - l32 
l13 == 3 - l23 - l33
l14 == 3 - l24 - l34
'
alc.cfa <- cfa(allalc.model, data = aim3alc, missing="ML", auto.fix.first=FALSE)

Error:
Error in Model(partable = lavaanParTable, start = lavaanStart, representation = lavaanOptions$representation,  : 
  lavaan ERROR: non-free parameter(s) in inequality constraint: l11

I think it has to do with the fact that I am doing a CFA, and something about the way that the CFA syntax constrains things. Is there different code for effects coding with CFAs?

Alex Schoemann

unread,
Jun 3, 2014, 10:46:17 PM6/3/14
to lav...@googlegroups.com
Effects coding won't work with the cfa function. cfa will always try to set the scale using either a marker variable or fixed factor method (specifying auto.fixed.first in cfa does not do anything). To use effects coding you need to use the lavaan function. To get the same defaults as the cfa function (except for auto.fix.first=TRUE) use the following (based off of the cfa documentation):

alc.cfa <- cfa(allalc.model, data = aim3alc, missing="ML", auto.fix.first=FALSE, int.ov.free = TRUE, int.lv.free = FALSE, auto.fix.single = TRUE, auto.var = TRUE, auto.cov.lv.x = TRUE, auto.cov.y = TRUE)

Alex

yrosseel

unread,
Jun 5, 2014, 8:42:03 AM6/5/14
to lav...@googlegroups.com
On 06/04/2014 04:46 AM, Alex Schoemann wrote:
> Effects coding won't work with the cfa function. cfa will always try to
> set the scale using either a marker variable or fixed factor method

In fact, you can do this using the cfa() function. You can 'override'
the fix-first-loading-to-one default by using the 'NA*' modifier. And
you also need to 'label' the first indicator. Since you can only use one
modifier at a time, you must repeat the first indicator on the right
hand side, each time with a different indicator:

HS.model <- '
visual =~ NA*x1 + v1*x1 + v2*x2 + v3*x3
textual =~ NA*x4 + t1*x4 + t2*x5 + t3*x6
speed =~ NA*x7 + s1*x7 + s2*x8 + s3*x9

v1 == 3 - v2 - v3
t1 == 3 - t2 - t3
s1 == 3 - s2 - s3
'

fit <- cfa(HS.model, data=HolzingerSwineford1939)
summary(fit)

Yves.

Alex Schoemann

unread,
Jun 5, 2014, 2:35:15 PM6/5/14
to lav...@googlegroups.com
Thanks Yves! Time to update my examples for class...

Amanda Pollitt

unread,
Jun 5, 2014, 3:02:01 PM6/5/14
to lav...@googlegroups.com
Thank you, Yves! Very, very helpful.

yvonne

unread,
Dec 27, 2017, 10:02:00 AM12/27/17
to lavaan
Hi,

I know this is an old question.
I am trying to use effect-coding do get factor scores that are of the same scale as my variables.
As I have about 20% missing data, I ran multiple imputation then CFA using the semtools package.

My codes for reference:

mapg.model <- ' MAPG  =~ NA*mapg1+ v1*mapg1 +  v2*mapg2 + v3*mapg3
                          v1 == 3 - v2 - v3  '

out1 <- runMI(mapg.model, 
              data=mice.imp,
              fun="cfa",
              meanstructure = TRUE)
summary(out1)
head(lavPredict(out1))
lavPredict(out1, fsm=TRUE, method="regression")

I received this warning 'In lav_partable_constraints_ceq(partable, con = LIST,  ... : lavaan WARNING: non-free parameter(s) in equality constraint(s): v1 v2 v3'

In addition, the factor scores were still not on the same scale as my variables. My variables on the scale of 1-5.

Have I missed out any steps or is my understanding of effects-coding wrong?

Thanks in advance !

Edward Rigdon

unread,
Dec 27, 2017, 10:18:19 AM12/27/17
to lav...@googlegroups.com
You have freed the first oading on the common factor, but not otherwise scaled the factor. So my guess would be that lavaan is implicitly constrfaining another loading to achieve identification. If you add a line to scale the factor, like:
MAPG~~1*MAPG
that may resolve the warning message.
As for the scale of your "factor scores," why not transform them afterward? They will be standard normal to begin with, so if you want their mean to be about 3, add 3 to the scores. Their variance starts out at 1, but if you want their variance to be K, multiply the scores by the square root of K.
I am by intent not addressing the problem of factor indeterminacy.

--
You received this message because you are subscribed to the Google Groups "lavaan" group.
To unsubscribe from this group and stop receiving emails from it, send an email to lavaan+unsubscribe@googlegroups.com.
To post to this group, send email to lav...@googlegroups.com.
Visit this group at https://groups.google.com/group/lavaan.

For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages