1
$\begingroup$

Suppose I had the following CFA model:

CFA model with two factors (f1 and f2) and 8 indicators (i1-i8)

To calculate the residual variance of, say, i1, one could subtract the factor variance (which in this case is standardized, hence = 1) from the squared factor loading (let's say it's 0.8). For example:

enter image description here

What about if I wanted to estimate the residual variance for indicator 5 (i5 - see red arrow in figure), which is non-congeneric, i.e. it loads on both factor 1 and factor 2?

My simple mind attempted to subtract the sum of squared factor loadings for i5 (e.g., 0.8^2 + 0.8^2) from the sum of factor variances (e.g., 1 + 1), but the result is implausible (0.72).

$\endgroup$
2
$\begingroup$

In the depicted model, you do not specify a covariance/correlation. If that is what you intended, then calculating the standardized residual variance for the cross-loading item is pretty straightforward:

  1. Square the standardized loading value for i5 on f1 (the % of variance explained in i5 by your first factor)
  2. Square the standardized loading value for i5 on f2 (the % of variance explained in i5 by your second factor)
  3. Subtract the sum of 1. and 2. from 1 (the standardized total amount of variance in i5), and that's your residual variance for i5.

You can see for yourself using a pretty straightforward in a example from lavaan. Here's code showing that this approach holds in a simple single-loading variable case (for x1; abbreviated output):

HS.model <- ' visual  =~ x1 + x2 + x3 
          textual =~ x4 + x5 + x6

          visual ~~0*textual'

fit <- cfa(HS.model, data=HolzingerSwineford1939, std.lv=T)
summary(fit, standardized = T)

Latent Variables:
               Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
visual =~                                                             
x1                0.724    0.090    8.043    0.000    0.724    0.621

Covariances:
               Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
visual ~~                                                             
textual           0.000                               0.000    0.000

Variances:
               Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
.x1                0.835    0.118    7.064    0.000    0.835    0.614

1-(0.621^2)
[1] 0.614359

Now the (uncorrelated) cross-loading case (x1 cross-loading onto textual):

HS.model.cross.nocorr <- ' visual  =~ x1 + x2 + x3 
          textual =~ x1 + x4 + x5 + x6

          visual ~~0*textual'

fit.cross <- cfa(HS.model.cross, data=HolzingerSwineford1939, std.lv=T)
summary(fit.cross, standardized = T)

Latent Variables:
               Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
visual =~                                                             
x1                0.620    0.085    7.289    0.000    0.620    0.545

textual =~                                                            
x1                0.370    0.061    6.074    0.000    0.370    0.325

Covariances:
               Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
visual ~~                                                             
textual           0.000                               0.000    0.000

Variances:
               Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
.x1                0.774    0.101    7.624    0.000    0.774    0.597

1-(0.545^2 + 0.325^2)
[1] 0.59735

Where things get messier is when the factors are correlated; we can no longer simply square and sum standardized loadings and subtract from 1:

HS.model.cross.corr <- ' visual  =~ x1 + x2 + x3 
          textual =~ x1 + x4 + x5 + x6

          visual ~~textual' 

Latent Variables:
               Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
visual =~                                                             
x1                0.646    0.091    7.099    0.000    0.646    0.554

textual =~                                                            
x1                0.291    0.073    3.983    0.000    0.291    0.249

Covariances:
               Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
visual ~~                                                             
textual           0.273    0.079    3.448    0.001    0.273    0.273

Variances:
               Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
.x1                0.754    0.101    7.455    0.000    0.754    0.555

1-(0.554^2 + 0.249^2)
[1] 0.631083   

:(
| cite | improve this answer | |
$\endgroup$
  • 1
    $\begingroup$ Amazing answer! You are right in assuming that there is no covariance between the factors (I guess I could have drawn a path between them and added the 'not = 0' symbol). I am trying to find a question to answer so I can upvote your answer! $\endgroup$ – PyjamaNinja Aug 29 '17 at 8:02
  • $\begingroup$ Glad it was helpful @PyjamaNinja. No need to go find another answer of mine elsewhere; you can just do that for this question if you want (since this was an answer that you actually found helpful). $\endgroup$ – jsakaluk Aug 29 '17 at 16:59
  • $\begingroup$ Note to self: "In this type of model, the general factor influences all items and the specific factors can be seen as residual factors explaining further correlations among subsets of items. Typically, you have all factors uncorrelated. This means that computation of the percentage variance explained by a certain factor is simply using the squared loading times the factor variance. Dividing by the item variance (i.e. y* variance, which is 1 if no covariates), gives the proportion variance in the item explained by the factor in question." (from tinyurl.com/yaa85c5l) $\endgroup$ – PyjamaNinja Jan 3 '18 at 9:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.