IRT without the normality assumption

library(IRTest)
#> Thank you for using IRTest!
#> Please cite the package as:
#> Li, S. (2022). IRTest: Parameter estimation of item response theory with estimation of latent distribution (Version 1.11.0). R package.
#> URL: https://CRAN.R-project.org/package=IRTest
library(ggplot2)
library(gridExtra)

0. Introduction

Installation

The CRAN version of IRTest can be installed on R-console with:

install.packages("IRTest")

For the development version, it can be installed on R-console with:

devtools::install_github("SeewooLi/IRTest")

Functions

Followings are the functions of IRTest.




1. Dichotomous items

The function DataGeneration can be used in a preparation step. This function returns a set of artificial data and the true parameters underlying the data.

Alldata <- DataGeneration(seed = 123456789,
                          model_D = rep(2, each=15),
                          N=1000,
                          nitem_D = 15,
                          nitem_P = 0,
                          latent_dist = "2NM",
                          d = 1.664,
                          sd_ratio = 2,
                          prob = 0.3)

data <- Alldata$data_D
theta <- Alldata$theta
data[1:500, 1] <- NA
data[501:1000, 2] <- NA
colnames(data) <- paste0("item", 1:15)




Mod1 <- IRTest_Dich(data = data,
                    model = 2,
                    latent_dist = "LLS",
                    h=4)




### Summary
summary(Mod1)
#> Convergence:  
#> Successfully converged below the threshold of 1e-04 on 59th iterations. 
#> 
#> Model Fit:  
#>  log-likeli   -7068.59 
#>    deviance   14137.18 
#>         AIC   14205.18 
#>         BIC   14372.04 
#>          HQ   14268.6 
#> 
#> The Number of Parameters:  
#>        item   30 
#>        dist   4 
#>       total   34 
#> 
#> The Number of Items:  
#> dichotomous   15 
#> polyotomous   0 
#> 
#> The Estimated Latent Distribution:  
#> method - LLS 
#> ----------------------------------------
#>                                           
#>                                           
#>                                           
#>                                           
#>           . . @ @ . . . . . .             
#>         . @ @ @ @ @ @ @ @ @ @ @ .         
#>       . @ @ @ @ @ @ @ @ @ @ @ @ @ .       
#>     . @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ .     
#>     @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ .   
#>   @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ . 
#> +---------+---------+---------+---------+
#> -2        -1        0         1         2

### The estimated item parameters
Mod1$par_est
#>                a          b c
#> item1  1.5482348 -0.0500929 0
#> item2  2.6085923  0.1571163 0
#> item3  1.6243276 -1.5336590 0
#> item4  0.9021883 -1.1022953 0
#> item5  2.6063085 -1.7876418 0
#> item6  0.9836554  0.4230422 0
#> item7  2.2405290 -1.5049362 0
#> item8  0.9008773 -0.4870385 0
#> item9  2.2504983 -0.4800820 0
#> item10 1.5732867  0.3165573 0
#> item11 0.9200077 -0.6694386 0
#> item12 1.1548618  0.2808033 0
#> item13 2.3778572  0.6054447 0
#> item14 1.7783967 -0.5748971 0
#> item15 1.1481623 -0.9873728 0

### The asymptotic standard errors of item parameters
Mod1$se
#>                 a          b  c
#> item1  0.15789514 0.07447963 NA
#> item2  0.22980804 0.05852801 NA
#> item3  0.14245397 0.08866138 NA
#> item4  0.08343962 0.10975113 NA
#> item5  0.28614320 0.08343519 NA
#> item6  0.07960166 0.07565105 NA
#> item7  0.19917307 0.06790716 NA
#> item8  0.07774926 0.08291844 NA
#> item9  0.14017385 0.04034026 NA
#> item10 0.10163763 0.05081731 NA
#> item11 0.07959281 0.08702539 NA
#> item12 0.08465565 0.06405675 NA
#> item13 0.15126882 0.04028549 NA
#> item14 0.11560521 0.04854175 NA
#> item15 0.09255787 0.08275086 NA

### The estimated ability parameters
plot(theta, Mod1$theta)
abline(b=1, a=0)

plot(Mod1, mapping = aes(colour="Estimated"), linewidth = 1) +
  lims(
    y = c(0, .75)
  )+
  geom_line(
    mapping=aes(
      x=seq(-6,6,length=121), 
      y=dist2(
        seq(-6,6,length=121),
        prob = .3, 
        d=1.664, 
        sd_ratio = 2
        ), 
      colour="True"),
    linewidth = 1)+
  labs(
    title="The estimated latent density using '2NM'", colour= "Type"
    )+
  theme_bw()

p1 <- plot_item(Mod1,1)
p2 <- plot_item(Mod1,4)
p3 <- plot_item(Mod1,8)
p4 <- plot_item(Mod1,10)
grid.arrange(p1, p2, p3, p4, ncol=2, nrow=2)

item_fit(Mod1)
#>             stat df p.value
#> item1  22.245527  7  0.0023
#> item2  15.283081  7  0.0325
#> item3   9.424785  7  0.2236
#> item4   9.946374  7  0.1916
#> item5  16.656066  7  0.0198
#> item6  11.397278  7  0.1222
#> item7  21.323089  7  0.0033
#> item8  10.454490  7  0.1642
#> item9  17.924949  7  0.0123
#> item10 36.161617  7  0.0000
#> item11 11.463653  7  0.1196
#> item12 36.035805  7  0.0000
#> item13 45.592035  7  0.0000
#> item14 22.112628  7  0.0024
#> item15 13.309416  7  0.0649
reliability(Mod1)
#> $summed.score.scale
#> $summed.score.scale$test
#> test reliability 
#>        0.8422169 
#> 
#> $summed.score.scale$item
#>     item1     item2     item3     item4     item5     item6     item7     item8 
#> 0.3334579 0.5410581 0.2198303 0.1362230 0.2572202 0.1784357 0.2926032 0.1533377 
#>     item9    item10    item11    item12    item13    item14    item15 
#> 0.4593840 0.3361294 0.1541039 0.2277817 0.4783934 0.3619255 0.1943880 
#> 
#> 
#> $theta.scale
#> test reliability 
#>        0.8144877

Each examinee’s posterior distribution is identified in the E-step of the estimation algorithm (i.e., EM algorithm). Posterior distributions can be found in Mod1$Pk.

set.seed(1)
selected_examinees <- sample(1:1000,6)
post_sample <- 
  data.frame(
    X = rep(seq(-6,6, length.out=121),6), 
    prior = rep(Mod1$Ak/(Mod1$quad[2]-Mod1$quad[1]), 6),
    posterior = 10*c(t(Mod1$Pk[selected_examinees,])), 
    ID = rep(paste("examinee", selected_examinees), each=121)
    )

ggplot(data=post_sample, mapping=aes(x=X))+
  geom_line(mapping=aes(y=posterior, group=ID, color='Posterior'))+
  geom_line(mapping=aes(y=prior, group=ID, color='Prior'))+
  labs(title="Posterior densities for selected examinees", x=expression(theta), y='density')+
  facet_wrap(~ID, ncol=2)+
  theme_bw()

ggplot()+
  stat_function(
    fun = inform_f_test,
    args = list(Mod1)
  )+ 
  stat_function(
    fun=inform_f_item,
    args = list(Mod1, 1),
    mapping = aes(color="Item 1")
  )+
  stat_function(
    fun=inform_f_item,
    args = list(Mod1, 2),
    mapping = aes(color="Item 2")
  )+
  stat_function(
    fun=inform_f_item,
    args = list(Mod1, 3),
    mapping = aes(color="Item 3")
  )+
  stat_function(
    fun=inform_f_item,
    args = list(Mod1, 4),
    mapping = aes(color="Item 4")
  )+
  stat_function(
    fun=inform_f_item,
    args = list(Mod1, 5),
    mapping = aes(color="Item 5")
  )+
  lims(x=c(-6,6))+
  labs(title="Test information function", x=expression(theta), y='information')+
  theme_bw()


2. Polytomous items

Alldata <- DataGeneration(seed = 123456789,
                          model_P = "GRM",
                          categ = rep(c(3,7), each = 7),
                          N=1000,
                          nitem_D = 0,
                          nitem_P = 14,
                          latent_dist = "2NM",
                          d = 1.664,
                          sd_ratio = 2,
                          prob = 0.3)

data <- Alldata$data_P
theta <- Alldata$theta
data[1:500, 1:3] <- NA
data[501:1000, 4:6] <- NA
colnames(data) <- paste0("item", 1:14)



Mod1 <- IRTest_Poly(data = data,
                    model = "GRM",
                    latent_dist = "KDE")



### Summary
summary(Mod1)
#> Convergence:  
#> Successfully converged below the threshold of 1e-04 on 34th iterations. 
#> 
#> Model Fit:  
#>  log-likeli   -13521.86 
#>    deviance   27043.72 
#>         AIC   27185.72 
#>         BIC   27534.17 
#>          HQ   27318.16 
#> 
#> The Number of Parameters:  
#>        item   70 
#>        dist   1 
#>       total   71 
#> 
#> The Number of Items:  
#> dichotomous   0 
#> polyotomous   14 
#> 
#> The Estimated Latent Distribution:  
#> method - KDE 
#> ----------------------------------------
#>                                           
#>                                           
#>                                           
#>                       . . .               
#>             . . . . @ @ @ @ @             
#>         . @ @ @ @ @ @ @ @ @ @ @           
#>       . @ @ @ @ @ @ @ @ @ @ @ @ @         
#>       @ @ @ @ @ @ @ @ @ @ @ @ @ @ @       
#>     @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @     
#> . @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ . 
#> +---------+---------+---------+---------+
#> -2        -1        0         1         2

### The estimated item parameters
Mod1$par_est
#>                a         b_1         b_2          b_3          b_4       b_5
#> item1  1.7043784  0.74865891  1.53420766           NA           NA        NA
#> item2  0.8846157 -0.32006881  0.92029681           NA           NA        NA
#> item3  0.5588543 -0.19748249  1.35920250           NA           NA        NA
#> item4  2.4763231 -0.85717570  0.54704169           NA           NA        NA
#> item5  1.6204885 -2.49625570 -2.29776627           NA           NA        NA
#> item6  1.7491337 -0.66410285  1.40035909           NA           NA        NA
#> item7  1.4917295 -0.31252097  0.06130535           NA           NA        NA
#> item8  1.6384013 -0.79007811 -0.39455628  0.142561160  0.295955756 0.3537926
#> item9  1.3475277 -2.26129426 -0.33776421  0.037042248  0.506641583 0.9069336
#> item10 1.5086113 -0.69013942 -0.37302428 -0.227752789 -0.111045135 0.5764796
#> item11 1.1475076 -1.04019929 -0.48917899  0.336338098  1.766380697 1.8109564
#> item12 2.3972209 -0.39985382 -0.11664459 -0.002042453  0.263375064 0.4901485
#> item13 2.4600482 -1.61488559 -0.79149838 -0.690683785  0.007890178 0.6024068
#> item14 1.1156322  0.04418557  0.09917351  0.786914926  1.461954550 1.8877157
#>              b_6
#> item1         NA
#> item2         NA
#> item3         NA
#> item4         NA
#> item5         NA
#> item6         NA
#> item7         NA
#> item8  0.3768889
#> item9  1.9525856
#> item10 0.9008752
#> item11 2.0296898
#> item12 1.4973700
#> item13 0.8040770
#> item14 2.0903264

### The asymptotic standard errors of item parameters
Mod1$se
#>                 a        b_1        b_2        b_3        b_4        b_5
#> item1  0.15731869 0.06242257 0.09731298         NA         NA         NA
#> item2  0.11497255 0.13998903 0.12150061         NA         NA         NA
#> item3  0.10846085 0.20254118 0.23869754         NA         NA         NA
#> item4  0.16865426 0.04925493 0.06561369         NA         NA         NA
#> item5  0.26617304 0.23118714 0.20042700         NA         NA         NA
#> item6  0.13339678 0.06314805 0.11705753         NA         NA         NA
#> item7  0.09011754 0.05267810 0.05088791         NA         NA         NA
#> item8  0.08423321 0.05521290 0.04859132 0.04696646 0.04815551 0.04881195
#> item9  0.07000093 0.11948123 0.05595773 0.05361261 0.05687136 0.06484487
#> item10 0.07755460 0.05700703 0.05168208 0.05023591 0.04954010 0.05370851
#> item11 0.06720232 0.08078369 0.06582956 0.06303822 0.10898226 0.11123833
#> item12 0.10185498 0.03838411 0.03632132 0.03591914 0.03591876 0.03707540
#> item13 0.09805476 0.05678053 0.03945096 0.03841788 0.03537082 0.03744249
#> item14 0.07256900 0.06328054 0.06315802 0.07345596 0.09986829 0.12231608
#>               b_6
#> item1          NA
#> item2          NA
#> item3          NA
#> item4          NA
#> item5          NA
#> item6          NA
#> item7          NA
#> item8  0.04910645
#> item9  0.10417814
#> item10 0.06070338
#> item11 0.12293823
#> item12 0.05527452
#> item13 0.04001182
#> item14 0.13438262

### The estimated ability parameters
plot(theta, Mod1$theta)
abline(b=1, a=0)

plot(Mod1, mapping = aes(colour="Estimated"), linewidth = 1) +
  lims(
    y = c(0, .75)
  )+
  geom_line(
    mapping=aes(
      x=seq(-6,6,length=121), 
      y=dist2(
        seq(-6,6,length=121),
        prob = .3, 
        d=1.664, 
        sd_ratio = 2
        ), 
      colour="True"),
    linewidth = 1)+
  labs(
    title="The estimated latent density using '2NM'", colour= "Type"
    )+
  theme_bw()

p1 <- plot_item(Mod1,1)
p2 <- plot_item(Mod1,4)
p3 <- plot_item(Mod1,8)
p4 <- plot_item(Mod1,10)
grid.arrange(p1, p2, p3, p4, ncol=2, nrow=2)

item_fit(Mod1)
#>             stat df p.value
#> item1  19.199622 15  0.2048
#> item2  12.002601 15  0.6788
#> item3  25.051363 15  0.0493
#> item4  10.026432 15  0.8181
#> item5   7.904608 15  0.9276
#> item6  18.502001 15  0.2372
#> item7  22.142382 15  0.1041
#> item8  52.309671 47  0.2754
#> item9  49.125761 47  0.3880
#> item10 46.938716 47  0.4751
#> item11 45.235199 47  0.5459
#> item12 59.079366 47  0.1112
#> item13 58.751810 47  0.1168
#> item14 33.698693 47  0.9275
reliability(Mod1)
#> $summed.score.scale
#> $summed.score.scale$test
#> test reliability 
#>        0.8715555 
#> 
#> $summed.score.scale$item
#>      item1      item2      item3      item4      item5      item6      item7 
#> 0.34573986 0.17570870 0.07915247 0.58057425 0.13546337 0.41254037 0.33993893 
#>      item8      item9     item10     item11     item12     item13     item14 
#> 0.40973373 0.34945629 0.38850461 0.27263404 0.59694514 0.63259823 0.24462347 
#> 
#> 
#> $theta.scale
#> test reliability 
#>        0.8900987

Each examinee’s posterior distribution is identified in the E-step of the estimation algorithm (i.e., EM algorithm). Posterior distributions can be found in Mod1$Pk.

set.seed(1)
selected_examinees <- sample(1:1000,6)
post_sample <- 
  data.frame(
    X = rep(seq(-6,6, length.out=121),6), 
    prior = rep(Mod1$Ak/(Mod1$quad[2]-Mod1$quad[1]), 6),
    posterior = 10*c(t(Mod1$Pk[selected_examinees,])), 
    ID = rep(paste("examinee", selected_examinees), each=121)
    )

ggplot(data=post_sample, mapping=aes(x=X))+
  geom_line(mapping=aes(y=posterior, group=ID, color='Posterior'))+
  geom_line(mapping=aes(y=prior, group=ID, color='Prior'))+
  labs(title="Posterior densities for selected examinees", x=expression(theta), y='density')+
  facet_wrap(~ID, ncol=2)+
  theme_bw()

ggplot()+
  stat_function(
    fun = inform_f_test,
    args = list(Mod1)
  )+ 
  stat_function(
    fun=inform_f_item,
    args = list(Mod1, 1),
    mapping = aes(color="Item 1 (3 cats)")
  )+
  stat_function(
    fun=inform_f_item,
    args = list(Mod1, 2),
    mapping = aes(color="Item 2 (3 cats)")
  )+
  stat_function(
    fun=inform_f_item,
    args = list(Mod1, 3),
    mapping = aes(color="Item 3 (3 cats)")
  )+
  stat_function(
    fun=inform_f_item,
    args = list(Mod1, 8),
    mapping = aes(color="Item 8 (7 cats)")
  )+
  stat_function(
    fun=inform_f_item,
    args = list(Mod1, 9),
    mapping = aes(color="Item 9 (7 cats)")
  )+
  stat_function(
    fun=inform_f_item,
    args = list(Mod1, 10, "p"),
    mapping = aes(color="Item10 (7 cats)")
  )+
  lims(x=c(-6,6))+
  labs(title="Test information function", x=expression(theta), y='information')+
  theme_bw()


3. Mixed-format test

As in the cases of dichotomous and polytomous items, the function DataGeneration can be used in the preparation step. This function returns artificial data and some useful objects for analysis (i.e., theta, data_D, item_D, data_P, & item_P).

Alldata <- DataGeneration(seed = 123456789,
                          model_D = rep(2,10),
                          model_P = "GRM",
                          categ = rep(5,5),
                          N=1000,
                          nitem_D = 10,
                          nitem_P = 5,
                          latent_dist = "2NM",
                          d = 1.664,
                          sd_ratio = 1,
                          prob = 0.5)

DataD <- Alldata$data_D
DataP <- Alldata$data_P
theta <- Alldata$theta

DataD[1:250, 1] <- NA
DataD[251:500, 2] <- NA
DataP[501:750, 1] <- NA
DataP[751:1000, 2] <- NA
colnames(DataD) <- paste0("item", 1:10)
colnames(DataP) <- paste0("item", 1:5)




Mod1 <- IRTest_Mix(data_D = DataD,
                   data_P = DataP,
                   model_D = "2PL",
                   model_P = "GRM",
                   latent_dist = "KDE")




### Summary
summary(Mod1)
#> Convergence:  
#> Successfully converged below the threshold of 1e-04 on 40th iterations. 
#> 
#> Model Fit:  
#>  log-likeli   -2690308 
#>    deviance   5380616 
#>         AIC   5380708 
#>         BIC   5380934 
#>          HQ   5380794 
#> 
#> The Number of Parameters:  
#>        item   45 
#>        dist   1 
#>       total   46 
#> 
#> The Number of Items:  
#> dichotomous   10 
#> polyotomous   5 
#> 
#> The Estimated Latent Distribution:  
#> method - KDE 
#> ----------------------------------------
#>                                           
#>                                           
#>                                           
#>                           . .             
#>           @ @ @ .     . @ @ @ .           
#>         @ @ @ @ @ @ @ @ @ @ @ @ .         
#>       . @ @ @ @ @ @ @ @ @ @ @ @ @         
#>       @ @ @ @ @ @ @ @ @ @ @ @ @ @ @       
#>     @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @     
#>   @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ . 
#> +---------+---------+---------+---------+
#> -2        -1        0         1         2

### The estimated item parameters
Mod1$par_est
#> $Dichotomous
#>               a           b c
#> item1  1.989290  0.07350262 0
#> item2  1.311346  0.09624470 0
#> item3  1.506160 -1.83722816 0
#> item4  1.995491 -1.12215813 0
#> item5  1.520043 -1.80533398 0
#> item6  2.219981  0.37844228 0
#> item7  2.426492 -1.62323274 0
#> item8  2.005543 -0.54995116 0
#> item9  1.427447 -0.48720215 0
#> item10 1.139450  0.44453035 0
#> 
#> $Polytomous
#>              a        b_1        b_2        b_3       b_4
#> item1 1.754255  0.1814927  0.9939145  1.6376303 1.8813178
#> item2 1.663549 -0.9695364 -0.2111917  0.5296833 1.1783305
#> item3 2.074764 -1.8136802 -0.4874640 -0.3282495 1.5535644
#> item4 1.937562 -2.4872253 -1.3719417  0.8551318 1.3206532
#> item5 2.153521 -0.9760964 -0.9397605  0.4116650 0.5374997

### The asymptotic standard errors of item parameters
Mod1$se
#> $Dichotomous
#>                 a          b  c
#> item1  0.14073359 0.04984134 NA
#> item2  0.10724796 0.06592267 NA
#> item3  0.14937706 0.12076865 NA
#> item4  0.14926820 0.05543049 NA
#> item5  0.14880331 0.11676753 NA
#> item6  0.13588900 0.04021894 NA
#> item7  0.23681702 0.07315133 NA
#> item8  0.12600345 0.04435457 NA
#> item9  0.09635028 0.05640130 NA
#> item10 0.08498392 0.06696300 NA
#> 
#> $Polytomous
#>                a        b_1        b_2        b_3        b_4
#> item1 0.10988078 0.05410323 0.07308293 0.10263130 0.11815205
#> item2 0.09194558 0.05904893 0.05260639 0.06233022 0.08181282
#> item3 0.09556186 0.07288193 0.04180610 0.04101146 0.06239914
#> item4 0.09754078 0.11901859 0.05902085 0.04744692 0.05910688
#> item5 0.10171816 0.04669610 0.04597569 0.04053825 0.04164812

### The estimated ability parameters
plot(theta, Mod1$theta)
abline(b=1, a=0)

plot(Mod1, mapping = aes(colour="Estimated"), linewidth = 1) +
  lims(
    y = c(0, .75)
  )+
  geom_line(
    mapping=aes(
      x=seq(-6,6,length=121), 
      y=dist2(
        seq(-6,6,length=121),
        prob = .3, 
        d=1.664, 
        sd_ratio = 2
        ), 
      colour="True"),
    linewidth = 1)+
  labs(
    title="The estimated latent density using '2NM'", colour= "Type"
    )+
  theme_bw()

p1 <- plot_item(Mod1,1, type="d")
p2 <- plot_item(Mod1,4, type="d")
p3 <- plot_item(Mod1,8, type="d")
p4 <- plot_item(Mod1,10, type="d")
grid.arrange(p1, p2, p3, p4, ncol=2, nrow=2)

p1 <- plot_item(Mod1,1, type="p")
p2 <- plot_item(Mod1,2, type="p")
p3 <- plot_item(Mod1,3, type="p")
p4 <- plot_item(Mod1,4, type="p")
grid.arrange(p1, p2, p3, p4, ncol=2, nrow=2)

item_fit(Mod1)
#> $Dichotomous
#>             stat df p.value
#> item1  10.746874  7  0.1500
#> item2   7.321550  7  0.3962
#> item3   8.481994  7  0.2920
#> item4   9.802941  7  0.2000
#> item5   7.616955  7  0.3676
#> item6  13.190573  7  0.0676
#> item7  11.783101  7  0.1079
#> item8  11.161640  7  0.1317
#> item9  16.052971  7  0.0246
#> item10 12.154971  7  0.0956
#> 
#> $Polytomous
#>           stat df p.value
#> item1 31.03797 31  0.4643
#> item2 57.97701 31  0.0023
#> item3 47.25933 31  0.0309
#> item4 49.06922 31  0.0207
#> item5 49.25978 31  0.0198
reliability(Mod1)
#> $summed.score.scale
#> $summed.score.scale$test
#> test reliability 
#>        0.8844702 
#> 
#> $summed.score.scale$item
#>   item1_D   item2_D   item3_D   item4_D   item5_D   item6_D   item7_D   item8_D 
#> 0.4336241 0.2709802 0.1758603 0.3381361 0.1809670 0.4627470 0.2971349 0.4134781 
#>   item9_D  item10_D   item1_P   item2_P   item3_P   item4_P   item5_P 
#> 0.2908335 0.2176764 0.4018832 0.4537284 0.5136929 0.4405026 0.5361866 
#> 
#> 
#> $theta.scale
#> test reliability 
#>        0.8844788

Each examinee’s posterior distribution is identified in the E-step of the estimation algorithm (i.e., EM algorithm). Posterior distributions can be found in Mod1$Pk.

set.seed(1)
selected_examinees <- sample(1:1000,6)
post_sample <- 
  data.frame(
    X = rep(seq(-6,6, length.out=121),6), 
    prior = rep(Mod1$Ak/(Mod1$quad[2]-Mod1$quad[1]), 6),
    posterior = 10*c(t(Mod1$Pk[selected_examinees,])), 
    ID = rep(paste("examinee", selected_examinees), each=121)
    )

ggplot(data=post_sample, mapping=aes(x=X))+
  geom_line(mapping=aes(y=posterior, group=ID, color='Posterior'))+
  geom_line(mapping=aes(y=prior, group=ID, color='Prior'))+
  labs(title="Posterior densities for selected examinees", x=expression(theta), y='density')+
  facet_wrap(~ID, ncol=2)+
  theme_bw()

ggplot()+
  stat_function(
    fun = inform_f_test,
    args = list(Mod1)
  )+ 
  stat_function(
    fun=inform_f_item,
    args = list(Mod1, 1, "d"),
    mapping = aes(color="Dichotomous Item 1")
  )+
  stat_function(
    fun=inform_f_item,
    args = list(Mod1, 2, "d"),
    mapping = aes(color="Dichotomous Item 2")
  )+
  stat_function(
    fun=inform_f_item,
    args = list(Mod1, 3, "d"),
    mapping = aes(color="Dichotomous Item 3")
  )+
  stat_function(
    fun=inform_f_item,
    args = list(Mod1, 1, "p"),
    mapping = aes(color="Polytomous Item 1")
  )+
  stat_function(
    fun=inform_f_item,
    args = list(Mod1, 2, "p"),
    mapping = aes(color="Polytomous Item 2")
  )+
  stat_function(
    fun=inform_f_item,
    args = list(Mod1, 3, "p"),
    mapping = aes(color="Polytomous Item 3")
  )+
  lims(x=c(-6,6))+
  labs(title="Test information function", x=expression(theta), y='information')+
  theme_bw()