hoping someone can offer some guidance here.
I'm creating a multivariate simulation using the simDesign package, I am varying the number of factors as well as items that load on each factor. I would like to write a command that identifies the number of factors present in factornumbers and assigns the appropriate items to them (no cross loading). I will be testing all combinations of the conditions below and more, and I would like to have a model command that acknowledge the iterations of differing models, so I don't have to write multiple model statements.
factornumbers<-c(1,2,3,5)
itemsperfactor<-c(5,10,30)
What lavaan and mirt are looking for is below:
mirtmodel<-mirt.model('
F1=1-15
F2=16-30
MEAN=F1,F2
COV=F1*F2')
lavmodel <- ' F1=~ Item_1 + Item_2 + Item_3 + Item_4 + Item_5 + Item_6 + Item_7 + Item_8 + Item_9 + Item_10 + Item_11 + Item_12 + Item_13 + Item_14 + Item_15
F2=~ Item_16 + Item_17 + Item_18 + Item_19 + Item_20 + Item_21 + Item_22 + Item_23 + Item_24 + Item_25 + Item_26 + Item_27 + Item_28 + Item_29 + Item_30'
The simDesign package offers this example, I would like to expand on it but I'm not sure I have the know-how:
lavmodel<-paste0('F=~ ', paste0(colnames(dat)[1L], ' + '),
paste0(colnames(dat)[-1L], collapse = ' + '))
What I would like is a single mirt and lavaan command that finds the number of factors specified in the factornumbers command and assigns the correct items specified in the data as well as itemsperfactor.
EDIT: I would like the model identification to pick up on which factor & item structure is in use for that condition and fill in the model identification with the correct information.
For Example:
mirtmodel<-mirt.model('
F1=1-1
F2=6-10
F3=11-15
F4=16-20
F5=21-25
MEAN=F1,F2,F3,F4,F5
COV=F1*F2*F3*F4*F5')
Or
mirtmodel<-mirt.model('
F1=1-30
F2=31-60
MEAN=F1,F2
COV=F1*F2')
And also the corresponding lavaan models.
The idea here is to paste different strings together so that the condition
input (row of the respective Design
object) is all that is required to construct a suitable model specification string. Generating syntax for simulations is arguably the most annoying part of simulations, but at least in R there are a good number of helpful string operations (plus, packages like stringr
).
Here's my interpretation of what you are currently looking for using base R functions.
library(SimDesign)
library(mirt)
Design <- createDesign(factornumbers = c(1,2,3,5),
itemsperfactor = c(5,10,30))
gen_syntax_mirt <- function(condition){
fn <- with(condition, factornumbers)
ipf <- with(condition, itemsperfactor)
nitems <- fn * ipf
maxloads <- sort(seq(nitems, ipf, length.out = fn))
minloads <- c(1, maxloads[-length(maxloads)] + 1)
fnames <- paste0('F', 1:fn)
df <- cbind(fnames, ' = ', minloads, '-', maxloads)
s1 <- apply(df, 1, paste0, collapse = '')
s2 <- paste0('MEAN = ', paste0(fnames, collapse = ','))
s3 <- paste0('COV = ', paste0(fnames, collapse = '*'))
ret <- paste0(c(s1, s2, s3), collapse = '\n')
mirt.model(ret)
}
gen_syntax_mirt(Design[1,])
gen_syntax_mirt(Design[10,])
The input to this function is a single row from the Design
input to runSimulation()
, so you can see here that it will work just fine. Do something similar for lavaan
's syntax and you'll be set.