# \donttest{
### load SAT12 and compute bifactor model with 3 specific factors
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))
specific <- c(2,3,2,3,3,2,1,2,1,1,1,3,1,3,1,2,1,1,3,3,1,1,3,1,3,3,1,3,2,3,1,2)
mod1 <- bfactor(data, specific)
summary(mod1)
itemplot(mod1, 18, drop.zeros = TRUE) #drop the zero slopes to allow plotting
# complete factor score predictions (general + specific factors)
eaps <- fscores(mod1)
# factor score predictions for general factors only (more accurate due
# to lower dimensional integration)
eaps_gen <- fscores(mod1, method = 'EAP_general')
head(cbind(eaps_gen, NA, eaps))
# similar EAP estimates, but with respect to sum-scores
fscores(mod1, method = 'EAPsum_2.0', full.scores=FALSE)
# alternative model definition via ?mirt.model syntax
specific2 <- "S1 = 7,9,10,11,13,15,17,18,21,22,24,27,31
S2 = 1,3,6,8,16,29,32
S3 = 2,4,5,12,14,19,20,23,25,26,28,30"
mod2 <- bfactor(data, specific2)
anova(mod1, mod2) # same
# also equivalent using item names instead (not run)
specific3 <- "S1 = Item.7, Item.9, Item.10, Item.11, Item.13, Item.15,
Item.17, Item.18, Item.21, Item.22, Item.24, Item.27, Item.31
S2 = Item.1, Item.3, Item.6, Item.8, Item.16, Item.29, Item.32
S3 = Item.2, Item.4, Item.5, Item.12, Item.14, Item.19,
Item.20, Item.23, Item.25, Item.26, Item.28, Item.30"
# mod3 <- bfactor(data, specific3)
# anova(mod1, mod2, mod3) # all same
### Try with fixed guessing parameters added
guess <- rep(.1,32)
mod2 <- bfactor(data, specific, guess = guess)
coef(mod2)
anova(mod1, mod2)
## don't estimate specific factor for item 32
specific[32] <- NA
mod3 <- bfactor(data, specific)
anova(mod3, mod1)
# same, but with syntax (not run)
specific3 <- "S1 = 7,9,10,11,13,15,17,18,21,22,24,27,31
S2 = 1,3,6,8,16,29
S3 = 2,4,5,12,14,19,20,23,25,26,28,30"
# mod3b <- bfactor(data, specific3)
# anova(mod3b)
#########
# mixed itemtype example
# simulate data
a <- matrix(c(
1,0.5,NA,
1,0.5,NA,
1,0.5,NA,
1,0.5,NA,
1,0.5,NA,
1,0.5,NA,
1,0.5,NA,
1,NA,0.5,
1,NA,0.5,
1,NA,0.5,
1,NA,0.5,
1,NA,0.5,
1,NA,0.5,
1,NA,0.5),ncol=3,byrow=TRUE)
d <- matrix(c(
-1.0,NA,NA,
-1.5,NA,NA,
1.5,NA,NA,
0.0,NA,NA,
2.5,1.0,-1,
3.0,2.0,-0.5,
3.0,2.0,-0.5,
3.0,2.0,-0.5,
2.5,1.0,-1,
2.0,0.0,NA,
-1.0,NA,NA,
-1.5,NA,NA,
1.5,NA,NA,
0.0,NA,NA),ncol=3,byrow=TRUE)
items <- rep('2PL', 14)
items[5:10] <- 'graded'
sigma <- diag(3)
dataset <- simdata(a,d,5000,itemtype=items,sigma=sigma)
itemstats(dataset)
specific <- "S1 = 1-7
S2 = 8-14"
simmod <- bfactor(dataset, specific)
coef(simmod, simplify=TRUE)
#########
# General testlet response model (Wainer, 2007)
# simulate data
set.seed(1234)
a <- matrix(0, 12, 4)
a[,1] <- rlnorm(12, .2, .3)
ind <- 1
for(i in 1:3){
a[ind:(ind+3),i+1] <- a[ind:(ind+3),1]
ind <- ind+4
}
print(a)
d <- rnorm(12, 0, .5)
sigma <- diag(c(1, .5, 1, .5))
dataset <- simdata(a,d,2000,itemtype=rep('2PL', 12),sigma=sigma)
itemstats(dataset)
# estimate by applying constraints and freeing the latent variances
specific <- "S1 = 1-4
S2 = 5-8
S3 = 9-12"
model <- "G = 1-12
CONSTRAIN = (1, a1, a2), (2, a1, a2), (3, a1, a2), (4, a1, a2),
(5, a1, a3), (6, a1, a3), (7, a1, a3), (8, a1, a3),
(9, a1, a4), (10, a1, a4), (11, a1, a4), (12, a1, a4)
COV = S1*S1, S2*S2, S3*S3"
simmod <- bfactor(dataset, specific, model)
coef(simmod, simplify=TRUE)
# Constrained testlet model (Bradlow, 1999)
model2 <- "G = 1-12
CONSTRAIN = (1, a1, a2), (2, a1, a2), (3, a1, a2), (4, a1, a2),
(5, a1, a3), (6, a1, a3), (7, a1, a3), (8, a1, a3),
(9, a1, a4), (10, a1, a4), (11, a1, a4), (12, a1, a4),
(GROUP, COV_22, COV_33, COV_44)
COV = S1*S1, S2*S2, S3*S3"
simmod2 <- bfactor(dataset, specific, model2)
coef(simmod2, simplify=TRUE)
anova(simmod2, simmod)
#########
# Two-tier model
# simulate data
set.seed(1234)
a <- matrix(c(
1,0,0.5,NA,NA,
1,0,0.5,NA,NA,
1,0,0.5,NA,NA,
1,0,0.5,NA,NA,
1,0,0.5,NA,NA,
1,0,NA,0.5,NA,
1,0,NA,0.5,NA,
1,0,NA,0.5,NA,
0,1,NA,0.5,NA,
0,1,NA,0.5,NA,
0,1,NA,0.5,NA,
0,1,NA,NA,0.5,
0,1,NA,NA,0.5,
0,1,NA,NA,0.5,
0,1,NA,NA,0.5,
0,1,NA,NA,0.5),ncol=5,byrow=TRUE)
d <- matrix(rnorm(16))
items <- rep('2PL', 16)
sigma <- diag(5)
sigma[1,2] <- sigma[2,1] <- .4
dataset <- simdata(a,d,2000,itemtype=items,sigma=sigma)
itemstats(dataset)
specific <- "S1 = 1-5
S2 = 6-11
S3 = 12-16"
model <- '
G1 = 1-8
G2 = 9-16
COV = G1*G2'
# quadpts dropped for faster estimation, but not as precise
simmod <- bfactor(dataset, specific, model, quadpts = 15, TOL = 1e-3)
coef(simmod, simplify=TRUE)
summary(simmod)
itemfit(simmod, QMC=TRUE)
M2(simmod, QMC=TRUE)
residuals(simmod, QMC=TRUE)
# EAP predictions for all factors (high dimensional)
eaps_all <- fscores(simmod, QMC=TRUE, quadpts=50000)
head(eaps_all)
maps <- fscores(simmod, method = 'MAP')
head(maps)
######
# Multiple-group bifactor example from Cai, Yang, Hansen (2011)
# Table 1 info from Cai, Yang, and Hansen (2011)
intercept <- c(1, .25, -.25, -1, 1, .25, -.25, -1,1,
.25, -.25, -1,1, .25, -.25, -1)
theta0 <- c(1, 1.4,1.7,2,
1.4,1.7,2,1,
1.7,2,1,1.4,
2, 1, 1.4, 1.7)
thetan <- c(.8,1.5,1.2,1,
1,.8,1.5,1.2,
1.2,1,.8,1.5,
1.5,1.2,1,.8)
thetaN <- matrix(0, 16, 4)
thetaN[1:4, 1] <- thetan[1:4]
thetaN[1:4+4, 2] <- thetan[1:4+4]
thetaN[1:4+8, 3] <- thetan[1:4+8]
thetaN[1:4+12, 4] <- thetan[1:4+12]
as <- cbind(theta0, thetaN)
as
# data generation for focal group in publication does not have response
# for items 13-16. However, full-data approach presented first
N <- 1000
itemtype <- '2PL'
gmeans <- c(1, -.5, 0, .5, 0)
sigma <- diag(c(.8, 1.2, 1.5, 1, 1))
datG1 <- simdata(as, intercept, N=N, itemtype='2PL')
datG2 <- simdata(as, intercept, N=N, itemtype='2PL',
mu = gmeans, sigma = sigma)
dat <- rbind(datG1, datG2)
group <- rep(c('G1', 'G2'), each=N)
specific <- "S1 = 1-4
S2 = 5-8
S3 = 9-12
S4 = 13-16"
mod <- bfactor(dat, specific, group=group, SE=TRUE,
invariance=c('free_means', 'free_vars', colnames(dat)))
coef(mod, simplify=TRUE)
# DIF testing for general dimension only with likelihood ratio tests (not run)
if(FALSE){
mirtCluster() # allocate computing cores
DIF(mod, which.par=c('a1', 'd'), scheme='drop')
}
## same analysis, however items 13:16 do not exist in the focal group
datG2[,13:16] <- NA # use this to match publication
dat <- rbind(datG1, datG2)
head(dat)
tail(dat)
# specify mean/cov structure explicitly
model2 <- "G = 1-16
MEAN [G2] = G, S1, S2, S3
COV [G2] = G*G, S1*S1, S2*S2, S3*S3"
mod2 <- bfactor(dat, specific, model2, group=group, invariance=colnames(dat))
coef(mod2, simplify=TRUE)
# }
Run the code above in your browser using DataLab