--- title: Person assessment with PPass, also for eRm models author: Manuel Reif output: rmarkdown::html_vignette vignette: > %\VignetteEngine{knitr::rmarkdown} %\VignetteIndexEntry{Person assessment with PPass, also for eRm models} %\VignetteEncoding{UTF-8} --- ```{r setup, include = FALSE} knitr::opts_chunk$set(collapse = TRUE, comment = "#>") has_erm <- requireNamespace("eRm", quietly = TRUE) ``` `PPass()` (**P**erson **P**arameter **ass**essment) estimates the abilities, computes the person fit and returns both in one table, together with the other person variables. It accepts - a data.frame (or matrix) with item responses, together with known item parameters, or - a model fitted with the eRm package: the Rasch model, the linear logistic test model, the rating scale model, the partial credit model and their linear versions, also with several time points and groups. ## Data with item parameters `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. ```{r ppass} 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()`): ```{r summary} 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"`). ```{r plot, fig.width = 6, fig.height = 4.5, fig.alt = "lz* of every person against the WLE estimate, flagged persons highlighted and labelled with their id"} 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. ```{r df} 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: ```{r jk} 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()`. ## Models fitted with eRm ```{r erm-note, echo = FALSE, results = "asis", eval = !has_erm} 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. ```{r rm, eval = has_erm} library(eRm) rm1 <- RM(raschdat1) res_rm <- PPass(rm1) res_rm ``` The maximum likelihood estimates are the same as those of eRm: ```{r rm-mle, eval = has_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: ```{r pcm, eval = has_erm} 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: ```{r lpcm, eval = has_erm} 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: ```{r pv, eval = has_erm} set.seed(1) pv <- PV(res_pcm, npv = 5) head(pv$pvdraws, 3) ```