knitr::opts_chunk$set(collapse = TRUE, comment = "#>") has_erm <- requireNamespace("eRm", quietly = TRUE)
PPass() (Person Parameter assessment) estimates the abilities, computes the person fit and returns both in one table, together with the other person variables. It accepts
fourpl_df contains an id, the sex and the responses of 60 persons to 12 items of a 3PL test. items names the item columns (positions or names); all other columns are kept as person variables. mod chooses the model, and the item parameters must match it.
library(PP) data(fourpl_df) res <- PPass(fourpl_df, items = 3:14, thres = attr(fourpl_df, "diffpar"), slopes = attr(fourpl_df, "slopes"), lowerA = attr(fourpl_df, "lowerA")) res
By default, PPass() computes WLE estimates and all four person fit statistics (lz, lz*, infit and outfit). Other arguments of PP_4pl(), PP_gpcm() and PPall() can be passed on, e.g. type = "mle" or a prior for type = "map". summary() shows the distribution of the estimates, the person fit and the persons flagged by lz* (two-sided, as in the summary of Pfit()):
s <- summary(res)
plot() shows the person fit map: lz* against the estimate, with the critical values of summary() and the flagged persons labelled, here by their id. which = "precision" shows the measurement precision of the test and which = "profile" the answers of single persons (see ?"pp-plots").
plot(res, label = "id")
The result is a data.frame. It can be filtered, merged or written to a file like any other data.frame; as.data.frame() drops the extra information.
res[res$sex == "w" & res$status == "ok", c("id", "estimate", "SE", "lzstar")][1:5, ] knitr::kable(head(as.data.frame(res)[, c("id", "sex", "estimate", "SE", "lzstar", "infit")]), digits = 3)
JKpp() and PV() work directly on the result, without estimating again:
head(JKpp(res)$estimates)
The model follows from the item parameters: here slopes and lowerA make it a 3PL model. A threshold matrix with several thresholds per item gives the PCM (all slopes 1) or the GPCM; together with lowerA or upperA it gives a test with both dichotomous (4PL) and polytomous (GPCM) items, estimated with PPall().
cat("*The eRm package is not installed, so the code of this section is shown without results.*\n")
eRm estimates item parameters by conditional maximum likelihood; eRm::person.parameter() then gives maximum likelihood estimates of the abilities. PPass() takes the fitted object and adds WLE, MAP, EAP and robust estimates, the person fit, the jackknife and plausible values.
library(eRm) rm1 <- RM(raschdat1) res_rm <- PPass(rm1) res_rm
The maximum likelihood estimates are the same as those of eRm:
res_mle <- PPass(rm1, type = "mle", fitindices = "lzstar") pp <- person.parameter(rm1) ok <- res_mle$status == "ok" max(abs(res_mle$estimate[ok] - pp$theta.table[ok, "Person Parameter"]))
eRm stores the parameters of the item categories as easiness parameters. PPass() converts them into PP thresholds, so the eRm package is not even needed to run PPass() on a saved object. Partial credit and rating scale models are estimated with PP_gpcm(), with all slopes equal to 1:
set.seed(2751) thres <- rbind(c(-2, -1.2, -0.5, 0), c(-1, 0.3, 1, 1.5), c(0.5, NA, NA, 2)) x <- sim_gpcm(thres = thres, alpha = 1, theta = rnorm(300)) res_pcm <- PPass(PCM(x), type = "map") summary(res_pcm$estimate)
With several time points (mpoints) and groups (groupvec), every combination of item, time point and group is a virtual item with its own parameters. A person answers the virtual items of their group and gets one ability estimate across all time points. eRm gives no person parameters for models with group contrasts; PPass() does:
x2 <- sim_gpcm(thres = thres, alpha = 1, theta = rnorm(300, 0.5)) lpcm <- LPCM(cbind(x, x2), mpoints = 2, groupvec = rep(1:2, 150)) res_lpcm <- PPass(lpcm) res_lpcm
Plausible values need a prior, so they require an EAP or MAP estimate, such as res_pcm above:
set.seed(1) pv <- PV(res_pcm, npv = 5) head(pv$pvdraws, 3)
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.