#make some data
set.seed(1234)
N <- 750
a <- matrix(rlnorm(10,.2,.5),10,1)
d <- matrix(rnorm(10), 10)
Theta <- matrix(sort(rnorm(N)))
pseudoIQ <- Theta * 5 + 100 + rnorm(N, 0 , 5)
group <- factor(rep(c('G1','G2','G3'), each = N/3))
data <- simdata(a,d,N, itemtype = rep('dich',10), Theta=Theta)
covdata <- data.frame(group, pseudoIQ)
#specify IRT model
model <- confmirt.model()
Theta = 1-10
#model with no person predictors
mod0 <- mirt(data, model, itemtype = 'Rasch')
#group as a fixed effect predictor (aka, uniform dif) and equal effect for all items with
# fixed.constrain = TRUE
mod1 <- mixedmirt(data, covdata, model, fixed = ~ group, itemtype = 'Rasch', fixed.constrain = TRUE)
anova(mod0, mod1)
summary(mod1)
coef(mod1)
#same model as above in lme4
wide <- data.frame(id=1:nrow(data),data,covdata)
long <- reshape2::melt(wide, id.vars = c('id', 'group', 'pseudoIQ'))
library(lme4)
lmod0 <- lmer(value ~ 0 + variable + (1|id), long, family = binomial)
lmod1 <- lmer(value ~ 0 + group + variable + (1|id), long, family = binomial)
anova(lmod0, lmod1)
#model using 2PL items instead of Rasch
mod1b <- mixedmirt(data, covdata, model, fixed = ~ group, itemtype = '2PL', fixed.constrain = TRUE)
anova(mod1, mod1b) #much better with 2PL models using all criteria (as expected, given simdata pars)
#global nonuniform dif (group interaction with latent variable)
(dif <- mixedmirt(data, covdata, model, fixed = ~ group * Theta, fixed.constrain = TRUE))
anova(mod1b, dif)
#free the interaction terms for each item to detect dif (less power for each item though)
sv <- mixedmirt(data, covdata, model, fixed = ~ group * Theta, pars = 'values')
constrain <- list(sv$parnum[sv$name == 'groupG2'], sv$parnum[sv$name == 'groupG3']) # main effects
itemdif <- mixedmirt(data, covdata, model, fixed = ~ group * Theta, fixed.constrain = FALSE,
constrain=constrain)
anova(dif, itemdif)
#continuous predictor and interaction model with group
mod2 <- mixedmirt(data, covdata, model, fixed = ~ group + pseudoIQ, fixed.constrain = TRUE)
mod3 <- mixedmirt(data, covdata, model, fixed = ~ group * pseudoIQ, fixed.constrain = TRUE)
summary(mod2)
anova(mod1b, mod2)
anova(mod2, mod3)
###########
##LLTM, and 2PL version of LLTM
data(SAT12)
data <- key2binary(SAT12,
key = c(1,4,5,2,3,1,2,1,3,1,2,4,2,1,5,3,4,4,1,4,3,3,4,1,3,5,1,3,1,5,4,5))
model <- confmirt.model()
Theta = 1-32
itemdesign <- data.frame(itemorder = factor(c(rep('easier', 16), rep('harder', 16))))
LLTM <- mixedmirt(data, model = model, fixed = ~ itemorder, itemtype = 'Rasch', itemdesign = itemdesign)
coef(LLTM)
wald(LLTM)
L <- matrix(c(-1, 1), 1)
wald(LLTM, L) #first half different from second
#compare to standard items with estimated slopes (2PL)?
twoPL <- mixedmirt(data, model = model, fixed = ~ itemorder, itemtype = '2PL', itemdesign = itemdesign)
coef(twoPL)
wald(twoPL)
L <- matrix(0, 1, 34)
L[1, 1] <- 1
L[1, 18] <- -1
wald(twoPL, L) #n.s.
anova(twoPL, LLTM)
#twoPL model better than LLTM, and don't draw the (spurious?) conclusion that the first
# half of the test is any easier/harder than the last
### Similar example, but with simulated data instead and using numeric item desing matrix
set.seed(1234)
N <- 750
a <- matrix(rep(1,10))
d <- matrix(c(rep(-1,5), rep(1,5)))
Theta <- matrix(rnorm(N))
data <- simdata(a, d, N, itemtype = rep('dich',10), Theta=Theta, D=1)
itemdesign <- data.frame(itempred=rep(1, ncol(data)))
model <- confmirt.model()
Theta = 1-10
sv <- mixedmirt(data, model = model, fixed = ~ itempred, pars = 'values',
itemtype = 'Rasch', itemdesign = itemdesign)
sv$value[sv$name == 'd'] <- 0
sv$est[sv$name == 'd'] <- FALSE
#make design such that the first 5 items are systematically more difficult than the last 5
constrain <- list()
constrain[[1]] <- sv$parnum[sv$name == 'itempred'][1:5]
constrain[[2]] <- sv$parnum[sv$name == 'itempred'][-c(1:5)]
mod <- mixedmirt(data, model = model, fixed = ~ itempred, pars = sv,
itemtype = 'Rasch', constrain = constrain, itemdesign = itemdesign)
coef(mod)
rasch <- mirt(data, 1, itemtype = 'Rasch', D=1)
anova(mod, rasch) #n.s., LLTM model a much better choice compared to Rasch
Run the code above in your browser using DataLab