## ---- include = FALSE--------------------------------------------------------- knitr::opts_chunk$set( collapse = TRUE, comment = "#>", out.width = "70%", # tidy = TRUE, # tidy.opts=list(arrow=TRUE,width.cutoff = 50), eval=T ) ## ----message=FALSE, echo = FALSE---------------------------------------------- library(irtpwr) ## ----------------------------------------------------------------------------- res <- function(altpars, nullpars = NULL) { n.items <- length(altpars[[1]]) # we can read off the number of items from the altpars object # the A matrix represents the calculations that need to be performed on the item parameters according to the hypothesis. in This case, only the difficulty of the first item needs to be extracted. Amat <- c(0, 1, rep(0, (n.items - 1) * 2)) |> (function(x) matrix(x, ncol = n.items * 2, byrow = TRUE))() # the c vector is the value that the item parameters are compared to after transformation by the A matrix. In this case, the difficulty parameter is only compared against 0. cvec = 0 # By specifying a mirt.model, we instruct mirt on how to fit the restricted model. In this case, it is a model where the first difficulty parameter is kept at 0. model = mirt::mirt.model(paste("F = 1-", n.items, " FIXED = (1, d) START = (1,d,0)")) re <- list(n.items = n.items, itemtype = "2PL", Amat = Amat, cvec = cvec, model = model) return(re) } ## ----------------------------------------------------------------------------- unres <- function(altpars) { # We first transform the parameters altpars from a list to a vector using the longpars argument. It results from a concatenation of the discrimination and difficulty parameters. longpars = pars.long(pars = altpars, itemtype = "2PL") # For the unrestricted model, we fit a simple 2PL model. This is specified in mirt using a 1 and the "2PL" itemtype. model = 1 itemtype = "2PL" re <- list(parsets = altpars, model = model, itemtype = itemtype, longpars = longpars) return(re) } ## ----------------------------------------------------------------------------- maximizeL <- function(hyp) { # Hypothesis-specific algorithm to find the # maximum likelihood restricted parameter set # in this case, the a parameter of the first item is searched for. maxlpreload <- function(pars) { # returns the density for each response # pattern under the model parameters pars # setting up all response patterns patterns <- as.matrix(expand.grid(lapply(seq_len(length(pars$a)), function(x) c(0, 1)))) pre <- c() #calculating the density for (i in seq_len(nrow(patterns))) { pre[i] <- funs$g(patterns[i, ], pars) } return(pre) } maxl <- function(x, pars, pre) { # calculates the likelihood of parameters # x given model 'pars' # setting up all response patterns patterns <- as.matrix(expand.grid(lapply(seq_len(length(pars$a)), function(x) c(0, 1)))) # collecting all parameters in a list, inserting x as the first a parameter x <- list(a = c(x, pars$a[2:length(pars$a)]), d = c(0, pars$d[2:length(pars$d)])) res <- c() # calculating the likelihoods for each pattern under this parameter set for (i in seq_len(nrow(patterns))) { px <- pre[i] qx <- funs$g(patterns[i, ], x) res[i] <- { px * log(qx) } } re <- -sum(res) } resmod <- hyp$resmod unresmod <- hyp$unresmod pars <- unresmod$parsets # loading the model specific density functions funs <- load.functions(unresmod$itemtype) # setting some starting value for the optimization startval <- pars$a[1] # calculating the densities as definied above maxlpre <- maxlpreload(pars) # finding the a parameter with the highest likelihood optpar <- stats::optim(startval, function(x) { maxl(x, pars, maxlpre) }, method = "BFGS") re <- pars # saving the resulting item parameters re$a <- c(optpar$par[1], pars$a[2:length(pars$a)]) re$d <- c(0, pars$d[2:length(pars$d)]) return(re) } ## ----------------------------------------------------------------------------- h_2PL_basic <- list(res = res, unres = unres, maximizeL = maximizeL) ## ----------------------------------------------------------------------------- altpars <- list(a = rlnorm(5, sdlog = 0.4), d = rnorm(5)) altpars$d[1] <- 0.2 hyp <- setup.hypothesis(type = h_2PL_basic, altpars = altpars) res <- irtpwr(hyp = hyp, alpha = 0.05, power = 0.8) summary(res)