Multidimensional Example

This example demonstrates how a multidimensional IRT test can be scored and modified for offline and on-line use. As well, it compares the effect of scoring the entire test given all possible responses to the use of a CAT scheme. The final section demonstrates how various elements in the GUI can be modified for more customized presentations.

The following code-block defines 100 items for a two factor math test measuring addition and multiplication.

library('mirtCAT')
options(stringsAsFactors = FALSE)

# define population IRT parameters
set.seed(1234)
nitems <- 120
itemnames <- paste0("Item.", 1:nitems)
a <- matrix(c(rlnorm(nitems/2, 0.2, 0.3), rnorm(nitems/4, 0, 0.3), numeric(nitems/2),
    rnorm(nitems/4, 0, 0.3), rlnorm(nitems/2, 0.2, 0.3)), nitems)
d <- matrix(rnorm(nitems))
pars <- data.frame(a, d)
colnames(pars) <- c("a1", "a2", "d")
trait_cov <- matrix(c(1, 0.5, 0.5, 1), 2, 2)

# create mirt_object
mod <- generate.mirt_object(pars, itemtype = "2PL", latent_covariance = trait_cov)

# math items definitions addition for one factor and multiplication for the other
questions <- answers <- character(nitems)
options <- matrix("", nitems, 5)
spacing <- floor(d - min(d)) + 1  #easier items have more variation

for (i in 1:nitems) {
    if (i < 31) {
        # addition
        n1 <- sample(1:100, 1)
        n2 <- sample(101:200, 1)
        ans <- n1 + n2
        questions[i] <- paste0(n1, " + ", n2, " = ?")
    } else if (i < 61) {
        # addition and multiplication
        n1 <- sample(1:50, 1)
        n2 <- sample(51:100, 1)
        m1 <- sample(1:10, 1)
        m2 <- sample(1:10, 1)
        ans <- n1 + n2 + m1 * m2
        questions[i] <- paste0(n1, " + ", n2, " + ", m1, " * ", m2, " = ?")
    } else if (i < 91) {
        # multiplication and addition
        n1 <- sample(1:10, 1)
        n2 <- sample(1:10, 1)
        m1 <- sample(1:25, 1)
        m2 <- sample(1:25, 1)
        ans <- n1 + n2 + m1 * m2
        questions[i] <- paste0(m1, " * ", m2, " + ", n1, " + ", n2, " = ?")
    } else {
        # multiplication
        m1 <- sample(1:50, 1)
        m2 <- sample(1:50, 1)
        ans <- n1 + n2 + m1 * m2
        questions[i] <- paste0(m1, " * ", m2, " = ?")
    }
    answers[i] <- as.character(ans)
    ch <- ans + sample(c(-5:-1, 1:5) * spacing[i, ], 5)
    ch[sample(1:5, 1)] <- ans
    options[i, ] <- as.character(ch)
}

# load list of items and their answers
df <- data.frame(Question = questions, Option = options, Answer = answers, Type = "radio")

Run the GUI using Drule selection, MAP estimation, and stopping when \(SE(\hat{\theta}) < 0.4\) OR 50 items have been administered, and start item is the T-rule (because the D-rule does not work when no items have previously been answered).

result <- mirtCAT(df, mod, criteria = 'Drule', start_item = 'Trule',
                  design = list(min_SEM = 0.4, max_items = 50))
print(result)
plot(result)