Imposing constraints on EFA using efaUnrotate

43 views
Skip to first unread message

Fabrício Fialho

unread,
Sep 7, 2017, 4:11:49 PM9/7/17
to lavaan
Hi,

If it makes sense at all, I just wonder if it is possible to impose a parameter constraint on EFA model using efaUrotate. I actually would like to constraint residual variances to be > 0. Is there any not-so-complicated way to do it?

Terrence Jorgensen

unread,
Sep 10, 2017, 6:17:09 AM9/10/17
to lavaan
I actually would like to constraint residual variances to be > 0. Is there any not-so-complicated way to do it?

The EFA model syntax is automatically generated, but you can indirectly add additional constraints as model-syntax commands passed to lavaan() via the constraints argument.  If you use parTable(fit) to extract the parameter table from the unrotated lavaan object, you can see which labels lavaan generates for the residual variances.  

unrotated <- efaUnrotate(HolzingerSwineford1939, nf = 3, varList = paste0("x", 1:9))
PT
<- parTable(unrotated)
PT
[PT$op == "~~", ]

   id     lhs op     rhs block user free ustart exo label group plabel start   est    se
28 28 factor1 ~~ factor1     1    1    0      1   0           1  .p28. 1.000 1.000 0.000
29 29 factor2 ~~ factor2     1    1    0      1   0           1  .p29. 1.000 1.000 0.000
30 30 factor3 ~~ factor3     1    1    0      1   0           1  .p30. 1.000 1.000 0.000
40 40 factor1 ~~ factor2     1    1    0      0   0           1  .p40. 0.000 0.000 0.000
41 41 factor1 ~~ factor3     1    1    0      0   0           1  .p41. 0.000 0.000 0.000
42 42 factor2 ~~ factor3     1    1    0      0   0           1  .p42. 0.000 0.000 0.000
43 43      x1 ~~      x1     1    0   37     NA   0           1  .p43. 0.679 0.696 0.087
44 44      x2 ~~      x2     1    0   38     NA   0           1  .p44. 0.691 1.035 0.102
45 45      x3 ~~      x3     1    0   39     NA   0           1  .p45. 0.637 0.692 0.097
46 46      x4 ~~      x4     1    0   40     NA   0           1  .p46. 0.675 0.377 0.048
47 47      x5 ~~      x5     1    0   41     NA   0           1  .p47. 0.830 0.403 0.061
48 48      x6 ~~      x6     1    0   42     NA   0           1  .p48. 0.598 0.365 0.042
49 49      x7 ~~      x7     1    0   43     NA   0           1  .p49. 0.592 0.594 0.106
50 50      x8 ~~      x8     1    0   44     NA   0           1  .p50. 0.511 0.479 0.080
51 51      x9 ~~      x9     1    0   45     NA   0           1  .p51. 0.508 0.551 0.060

You see that the residual variances for x1-x9 are labeled ".p43." - ".p51.", so you can add inequality constraints when you run the model again.

(positiveVariances <- paste0('.p', 43:51, '. > 0'))
unrotated
<- efaUnrotate(HolzingerSwineford1939, nf = 3, varList = paste0("x", 1:9),
                         constraints
= positiveVariances)

However, I would not recommend constrained estimation as a solution for Heywood cases.  Constraining it potentially masks other problems with your model, and forcing negative estimates to be positive will bias other model parameters.


Instead, test whether the Heywood case is consistent with sampling error:


If sampling error cannot be discounted (because the 95% CI includes positive values), and your model fits well, then it is reasonable to assume the Heywood case is due to sampling error rather than model misspecification.  But EFA models are exploratory models anyway, not particularly well suited to represent specific theoretical models.

Terrence D. Jorgensen
Postdoctoral Researcher, Methods and Statistics
Research Institute for Child Development and Education, the University of Amsterdam

Fabrício Fialho

unread,
Sep 21, 2017, 1:50:52 PM9/21/17
to lavaan
Hi Terence,
Many thanks for explaining how to use the 'constraints' in this context. 
Reply all
Reply to author
Forward
0 new messages