Baloo--
Here are 3 approaches. The first fixes the first higher order loading to 1, and constrains residual covariances of the first order factors to 0. (Fixing the first loading to 1 is a default for the cfa() and sem() functions.) The second frees the first higher order loading but fixes the variance of the higher order factor to 1. The third frees the first loading but forces the three higher order loadings to average 1. With only 3 first order factors, the higher order model is statistically equivalent to the CFA, as suggested by the equal fit and DF which this code produces.
library(lavaan)
# fix first higher order loading to 1
m1<-'
visual =~ x1 + x2 + x3
textual =~ x4 + x5 + x6
speed =~ x7 + x8 + x9
ho =~ 1*visual+textual+speed # first loading explicitly fixed to 1
visual+textual ~~ 0*speed
visual ~~ 0*textual
'
fit.m1 <- sem(m1, data=HolzingerSwineford1939)
summary(fit.m1)
# fix variance of higher order factor to 1
m2<-'
visual =~ x1 + x2 + x3
textual =~ x4 + x5 + x6
speed =~ x7 + x8 + x9
ho =~ NA*visual+textual+speed # free first loading, or sem will fix to 1
visual+textual ~~ 0*speed
visual ~~ 0*textual
ho ~~ 1*ho # fix variance of higher order factor to 1
'
fit.m2 <- sem(m2, data=HolzingerSwineford1939)
summary(fit.m2)
# fix average loading on higher order factor to 1
m3<-'
visual =~ x1 + x2 + x3
textual =~ x4 + x5 + x6
speed =~ x7 + x8 + x9
ho =~ NA*visual+a*visual+b*textual+c*speed # NA to free first loading
visual+textual ~~ 0*speed
visual ~~ 0*textual
a == 3 - b - c # average loading = 1
'
fit.m3 <- sem(m3, data=HolzingerSwineford1939)
summary(fit.m3)
# base CFA model
mbase<-'
visual =~ x1 + x2 + x3
textual =~ x4 + x5 + x6
speed =~ x7 + x8 + x9
'
fit.mbase <- sem(mbase, data=HolzingerSwineford1939)
summary(fit.mbase)