Hi! The 3PL IRT model is usually defined as shown here.
First, I we can define a function, irt_prob
that calculates the probability of a correct response, with or without c parameters. Then we pass that function to one more apply()
function. The full code is below:
irt_prob <- function(logit, c = NULL) {
if (is.null(c)) {
1 / ( 1 + exp( -logit ) )
} else {
c + ((1 - c) / (1 + exp( -logit ) ) )
}
}
irt.sim <- function( nitem = 20, npers = 100 ) {
i.loc <- rnorm( nitem )
p.loc <- rnorm( npers )
i.slp <- rlnorm( nitem, sdlog = .4 )
i.gus <- rbeta( nitem, shape1 = 5, shape2 = 17)
temp <- matrix( rep( p.loc, length( i.loc ) ), ncol = length( i.loc ) )
logits <- t( apply( temp , 1, '-', i.loc ) )
logits <- t( apply( logits, 1, '*', i.slp ) )
# For 2PL:
# probabilities <- t( apply( logits, 1, irt_prob ) )
# For 3PL:
probabilities <- t( apply( logits, 1, irt_prob, c = i.gus ) )
resp.prob <- matrix( probabilities, ncol = nitem)
obs.resp <- matrix( sapply( c(resp.prob), rbinom, n = 1, size = 1), ncol = length(i.loc) )
output <- list()
output$i.loc <- i.loc
output$i.slp <- i.slp
output$p.loc <- p.loc
output$resp <- obs.resp
output
}
I've generated the c-parameters from a beta(5,17) distribution, which will give an average value of ~.2.