Information Matrix Test

This vignette reproduces the example shows the use of the information matrix test when collapsing categories of a Partial Credit Model.

library(IMTest)
## Loading required package: ltm
## Loading required package: MASS
## Loading required package: msm
## Loading required package: polycor
library(lme4)
## Loading required package: Matrix
library(reshape2)

A commonly analyzed dataset in the illustration of IRT methods consists of 316 responses to 24 items referring to verbally aggressive reactions to situations that may be frustrating. Responses to the items are collected on a three point ordinal scale, with categories labelled as yes, perhaps, or no. The dataset is publicly available, for example through the lme4 package in R. This vignette analyzes item responses to the first 12 items, and investigates the potential model misspecification when collapsing categories of those items.

data(VerbAgg)

x = dcast(VerbAgg[,c( "id","item", "resp")], id~item)
## Using resp as value column: use value.var to override.
for(i in 2:25){
  x[,i] = factor(x[,i], levels = c("no", "perhaps", "yes"))
}

my_data = x[,2:13]

J = dim(my_data)[[2]]
n = dim(my_data)[[1]]

First, a set of index vectors is created to test both item-level parameters of each item separately.

# Create index vectors
ind = list()
for(i in 1:J){
  ind[[i]] = rep(0, J*2)
  ind[[i]][(2*i-1):(2*i)] = 1
}

A collapsing function is generated, showing that no collapsing has occurred, and the gpcm_IMT function is run. A matrix is initialized to store the p-values.

col = split(rep(c(1:3), J), rep(1:J, each = 3))
temp_data = collapse_data(my_data, col, "rasch")
mod = gpcm_IMT(temp_data$data, constraint = "rasch")

## Creates a matrix to store results.
pval = matrix(c(0), nrow = J, ncol = 3)

The following set of code runs the IMT for the uncollapsed data, and for two forms of collapsing: collapsing the middle category up, and collapsing the middle category down.

# No Collapsing
for(i in 1:J){
  test_fit = IMT(mod, "rasch", R = 5000, ind[[i]])
  pval[i,1] = pchisq(test_fit$Tstat, test_fit$df, lower.tail = F)
}

# Collapsing the middle categoy up.
for(i in 1:J){
  col = split(rep(c(1:3), J), rep(1:J, each = 3))
  col[[i]] = c(1,2,2)
  temp_data = collapse_data(my_data, col, "rasch")
  mod = gpcm_IMT(temp_data$data, constraint = "rasch")
  test_fit = IMT(mod, "rasch", R = 5000, temp_data$ind)
  pval[i,2] = pchisq(test_fit$Tstat, test_fit$df, lower.tail = F)
}

# Collapsing the middle category down.
for(i in 1:J){
  col = split(rep(c(1:3), J), rep(1:J, each = 3))
  col[[i]] = c(1,1,2)
  temp_data = collapse_data(my_data, col, "rasch")
  mod = gpcm_IMT(temp_data$data, constraint = "rasch")
  test_fit = IMT(mod, "rasch", R = 5000, temp_data$ind)
  pval[i,3] = pchisq(test_fit$Tstat, test_fit$df, lower.tail = F)
}

Originally, all but one item fails to reject goodness-of-fit. After collapsing in one direction, four items now reject goodness-of-fit. After collapsing in the other direction, no items reject goodness-of-fit.

# Original fit: all but question 8 fail to reject goodness-of-fit.
p.adjust(pval[,1], method = "fdr")
##  [1] 0.39369401 0.65051326 0.65051326 0.70741999 0.65051326 0.70741999
##  [7] 0.39369401 0.02258113 0.65051326 0.39369401 0.65051326 0.65051326
# After collapsing: question 8 now fails to reject goodness-of-fit, but 4 other questions reject.
p.adjust(pval[,2], method = "fdr")
##  [1] 0.017993729 0.019557593 0.302406914 0.022581141 0.009967955 0.346316022
##  [7] 0.236763532 0.168535039 0.631541904 0.660177480 0.081544868 0.794322194
# Had it been collapsed the other direction, all would fail to reject.
p.adjust(pval[,3], method = "fdr")
##  [1] 0.09986702 0.04484242 0.65764342 0.26333299 0.15971296 0.15971296
##  [7] 0.43149156 0.38528871 0.15971296 0.43149156 0.34195058 0.26333299