Hello everyone,
I'm fairly new to structural equation modeling in general and do not know the lavaan package very well so far.
My goal is to fit an "Thurstonian IRT-Model" to binary forced choice questionnaire data and I would like to know if this can already be done in lavaan and if so I would be grateful for some model fitting advice.
The model was developed by Anna Brown and published recently. A graphical representation looks like this:
some characteristics of the model
## sample data
n <- 200
i1i2 <- sample(c(0,1), n, replace=T)
i3i4 <- sample(c(0,1), n, replace=T)
i5i6 <- sample(c(0,1), n, replace=T)
i7i8 <- sample(c(0,1), n, replace=T)
data <- as.data.frame(cbind(i1i2, i3i4, i5i6, i7i8)) ## specify and fit model
model <- '
T1 =~ i1i2 + i3i4 + i5i6 + i7i8
'
## attempts to identify a second latent variable with negative loadings
## add:
'
T2 =~ i1i2 + i3i4 + i5i6 + i7i8 # doesnt fit
T2 =~ -1*i1i2 + -1*i3i4 + -1*i5i6 + -1*i7i8 # all Parameters fixed, no estimate
T2 =~ -i1i2 - i3i4 - i5i6 - i7i8 # doesnt fit
'
fit <- lavaan(model=model, model.type="sem", data=data, estimator="DWLS")
summary(fit)
## attempts access estimates for every case
parameterEstimates(fit)
coef(fit, type="user")## attempts to fix Variances and Uniqueness
## add:
'
T1 ~~ 1*T1
i1i2 ~~0.5*i1i2
i3i4 ~~0.5*i3i4
i5i6 ~~0.5*i5i6
i7i8 ~~0.5*i7i8
'I hope, I provided enough information to determine, wether lavaan will be able to compute this model. Looking forward to your answers,
Henning
PS: For those of you, that are familiar with MPlus, i added an mplus-example from the original publication.
MPLUS-Syntax
TITLE: Example forced-choice questionnaire with 3 Triplets (=9 Items) measuring 3 Traits
DATA: FILE IS /Users/Henning/Data/Consulting;
VARIABLE: NAMES ARE i25i26 i83i84 i141i142 i199i200;
USEVARIABLES ARE ALL;
CATEGORICAL ARE ALL;
ANALYSIS:
ESTIMATOR IS wlsm;
PARAMETERIZATION IS theta;
MODEL:
! latent traits are indicated by binary outcomes directly
Trait1 BY i1i2*1 i1i3*1 (l1)
i4i5*1 i4i6*1 (l4)
i7i8*1 i7i9*1 (l7);
Trait2 BY i1i2*-1 (l2_m)
i2i3*1 (l2)
i4i5*-1 (l5_m)
i5i6*1 (l5)
i7i8*-1 (l8_m)
i8i9*1 (l8);
Trait3 BY i1i3*-1 i2i3*-1 (l3_m)
i4i6*-1 i5i6*-1 (l6_m)
i7i9*-1 i8i9*-1 (l9_m);
! variances for all traits are set to 1
Trait1-Trait3@1;
! traits are freely correlated
Trait1 WITH Trait2* Trait3*;
Trait2 WITH Trait3*;
! pairwise errors are free; parameters are declared here to impose constraints later
i1i2*1 (e1e2);
i1i3*1 (e1e3);
i2i3*1 (e2e3);
i4i5*1 (e4e5);
i4i6*1 (e4e6);
i5i6*1 (e5e6);
i7i8*1 (e7e8);
i7i9*1 (e7e9);
i8i9*1 (e8e9);
! errors related to the same utility are correlated, some are with minus sign i1i2 WITH i1i3*.5 (e1);
i1i2 WITH i2i3*-.5 (e2_m);
i1i3 WITH i2i3*.5 (e3);
i4i5 WITH i4i6*.5 (e4);
i4i5 WITH i5i6*-.5 (e5_m);
i4i6 WITH i5i6*.5 (e6);
i7i8 WITH i7i9*.5 (e7);
i7i8 WITH i8i9*-.5 (e8_m);
i7i9 WITH i8i9*.5 (e9);
MODEL CONSTRAINT:
!loadings relating to the same item are equal in absolute value
l2=-l2_m; l5=-l5_m; l8=-l8_m;
! errors of pairs are equal to sum of 2 utility errors
e1e2=e1-e2_m;
e1e3=e1+e3;
e3= -e2_m+e3;
e4e5=e4- e5_m;
e4e6=e4+e6;
e5e6= -e5_m+e6;
e7e8=e7- e8_m;
e7e9=e7+e9;
e8e9= -e8_m+e9;
!fixing unique variances of one utility per block to identify the model e3=.5; e6=.5; e9=.5;
SAVEDATA: ! trait scores for individuals are estimated and saved in a file FILE IS ExampleTestResults.dat;
SAVE=FSCORES;## specify and fit model
model <- '
T1 =~ i1i2 + i3i4 + i5i6 + i7i8
'
## attempts to identify a second latent variable with negative loadings
## add:
'
T2 =~ i1i2 + i3i4 + i5i6 + i7i8 # doesnt fit
T2 =~ -1*i1i2 + -1*i3i4 + -1*i5i6 + -1*i7i8 # all Parameters fixed, no estimate
T2 =~ -i1i2 - i3i4 - i5i6 - i7i8 # doesnt fit
'
...
e5e6= -e5_m<span style="color: #660;" cla
! pairwise errors are free; parameters are declared here to impose constraints later
i1i2*1 (e1e2);
i1i3*1 (e1e3);
i2i3*1 (e2e3);
...
! errors of pairs are equal to sum of 2 utility errors
e1e2=e1-e2_m;
e1e3=e1+e3;
e3= -e2_m+e3;
e4e5=e4- e5_m;
...
Also, I'm wondering if lavaan is going to be able to compute MAP factor scores.
Any help would be greatly appreciated! Thanks!
I can't figure out how to write these two parts from the Mplus syntax in lavaan:
Also, I'm wondering if lavaan is going to be able to compute MAP factor scores.
how can I label the scales y* in the "theta" parameterization and put constraints on them?
y1 ~*~ c(scale1, scale1)*y1myData <- read.table("http://www.statmodel.com/usersguide/chap5/ex5.16.dat")
names(myData) <- c("u1","u2","u3","u4","u5","u6","x1","x2","x3","g")
model <- '
f1 =~ u1 + u2 + u3
f2 =~ u4 + u5 + u6
'
fit1 <- cfa(model, data = myData, ordered = paste0("u", 1:6),
group = "g", group.equal = c("loadings","thresholds"))
summary(fit1, fit.measures = TRUE, standardized = TRUE)
scales <- ' u1 ~*~ c(NA, NA)*u1 + c(scale1, scale1)*u1 '
fit2 <- cfa(c(model, scales), data = myData, ordered = paste0("u", 1:6),
group = "g", group.equal = c("loadings","thresholds"))
summary(fit2, fit.measures = TRUE, standardized = TRUE)Yves,