\name{plotPImap} \alias{plotPImap} \title{Person-Item Map (aka Wright Map)} \description{ The is an improved version of the person-item map (\code{eRm::\link[eRm]{plotPImap}}) from the \code{eRm} package. The improvements include more control over colors (in particular, some of the color choices in the base version were not showing on certain projectors). From the eRm documentation: A person-item map displays the location of item (and threshold) parameters as well as the distribution of person parameters.along the latent dimension. Person-item maps are useful to compare the range and position of the item measure distribution (lower panel) to the range and position of the person measure distribution (upper panel). Items should ideally be located along the whole scale to meaningfully measure the `ability' of all persons. } \usage{ plotPImap(object, item.subset = "all", sorted = FALSE, main = "Person-Item Map", latdim = "Latent Dimension", pplabel = "Person\nAbility\nDistribution", cex.gen = 0.7, xrange = NULL, warn.ord = TRUE, warn.ord.colour = "black", irug = TRUE, pp = NULL, ppdcol = "red") } \arguments{ \item{object}{Object of class \code{\link[eRm]{Rm}} or \code{\link[eRm]{dRm}} providing the fit model.} \item{item.subset}{Subset of items to be plotted. Either a numeric vector indicating the column in \code{X} or a character vector indicating the column name. If \code{"all"}, all items are plotted. The number of items to be plotted must be > 1.} \item{sorted}{A logical value. If \code{TRUE}, the items are sorted in increasing order according to their location on the latent dimension.} \item{main}{Character. The main title of the plot.} \item{latdim}{Label for the x-axis, i.e., the name of the latent dimension.} \item{pplabel}{Title for the upper panel displaying the person latent variable distribution.} \item{cex.gen}{A real value corresponding to the \code{\link[graphics]{par}} parameter \code{cex}. This provides a scaling factor for ploted text and symbols. Here \code{cex.gen} applies to all text labels. The default is 0.7.} \item{xrange}{Range for the x-axis.} \item{warn.ord}{A logical value. If \code{TRUE} (the default) asterisks are displayed in the right margin of the lower panel to indicate nonordinal threshold locations for polytomous items.} \item{warn.ord.colour}{A colour specification. Nonordinal threshold locations for polytomous items are coloured with this colour to make them more visible. This is especially useful when there are many items so that the plot is quite dense. The default is \code{"black"}, so that there is no distinction made.} \item{irug}{If \code{TRUE} (the default), all thresholds are plotted below the person distribution to indicate where the included items are most informative.} \item{pp}{If non-\code{NULL}, this contains the \code{\link[eRm]{person.parameter}} data of the data object, avoiding the need to recalculate it.} \item{ppdcol}{A color specification, default is \code{"red"}. This gives the color of the person latent variable (parameter) distribution. This is the only change of arguments from \code{eRm::plotPImap}, which used the color \code{"grey"}.} } \details{ This function is nearly identical to \code{eRm::\link[eRm]{plotPImap}}, with the exception that the color of the person latent variable distribution can be changed. The shade of gray used in the original was not always visible when projected by a project with a weak light. From the original documentation. Item locations are displayed with bullets, threshold locations with circles. } \value{ Called for its side effects (producing a plot). } \references{ Bond, T.G., and Fox Ch.M. (2007). \emph{Applying the Rasch Model. Fundamental Measurement in the Human Sciences. 2nd Edition.} Lawrence Erlbaum Associates. } \author{ Patrick Mair, Reinhold Hatzinger, patches from Julian Gilbey and Marco J. Maier. Code hacked to change the color by Russell Almond. } \note{ The \code{eRm} package uses the term \emph{person parameter} for the latent variable. I (Russell) prefer to reserve the term \emph{parameter} for quantities which are not person-specific. } \seealso{ \code{\link[eRm]{plotPImap}}, \code{\link{kidmap}}, \code{\link{wrongMap}} } \examples{ ##---- Should be DIRECTLY executable !! ---- ##-- ==> Define data, use random, ##-- or do help(data=index) for the standard data sets. ## The function is currently defined as function (object, item.subset = "all", sorted = FALSE, main = "Person-Item Map", latdim = "Latent Dimension", pplabel = "Person\nAbility\nDistribution", cex.gen = 0.7, xrange = NULL, warn.ord = TRUE, warn.ord.colour = "black", irug = TRUE, pp = NULL, ppdcol = "red") { def.par <- par(no.readonly = TRUE) if ((object$model == "LLTM") || (object$model == "LRSM") || (object$model == "LPCM")) stop("Item-Person Map are computed only for RM, RSM, and PCM!") if (object$model == "RM" || max(object$X, na.rm = TRUE) < 2) { dRm <- TRUE threshtable <- cbind(object$betapar, object$betapar) * -1 rownames(threshtable) <- substring(rownames(threshtable), first = 6, last = 9999) } else { dRm <- FALSE threshtable <- thresholds(object)$threshtable[[1]] } tr <- as.matrix(threshtable) if (is.character(item.subset)) { if (length(item.subset) > 1 && all(item.subset \%in\% rownames(threshtable))) tr <- tr[item.subset, ] else if (length(item.subset) != 1 || !(item.subset == "all")) stop("item.subset misspecified. Use 'all' or vector of at least two valid item indices/names.") } else { if (length(item.subset) > 1 && all(item.subset \%in\% 1:nrow(tr))) tr <- tr[item.subset, ] else stop("item.subset misspecified. Use 'all' or vector of at least two valid item indices/names.") } if (sorted) tr <- tr[order(tr[, 1], decreasing = FALSE), ] loc <- as.matrix(tr[, 1]) tr <- as.matrix(tr[, -1]) if (is.null(pp)) suppressWarnings(pp <- person.parameter(object)) else if (class(pp) != "ppar" || !identical(pp$X, object$X)) stop("pp is not a person.parameter object which matches the main Rasch data object!") theta <- unlist(pp$thetapar) tt <- table(theta) ttx <- as.numeric(names(tt)) yrange <- c(0, nrow(tr) + 1) if (is.null(xrange)) xrange <- range(c(tr, theta), na.rm = T) nf <- layout(matrix(c(2, 1), 2, 1, byrow = TRUE), heights = c(1, 3), T) par(mar = c(2.5, 4, 0, 1)) plot(xrange, yrange, xlim = xrange, ylim = yrange, main = "", ylab = "", type = "n", yaxt = "n", xaxt = "n") axis(2, at = 1:nrow(tr), labels = rev(rownames(tr)), las = 2, cex.axis = cex.gen) axis(1, at = seq(floor(xrange[1]), ceiling(xrange[2])), cex.axis = cex.gen, padj = -1.5) mtext(latdim, 1, 1.2, cex = cex.gen + 0.1) if (irug == TRUE) { y.offset <- nrow(tr) * 0.0275 tr.rug <- as.numeric(tr) if (any(is.na(tr.rug))) tr.rug <- tr.rug[-which(is.na(tr.rug))] segments(tr.rug, rep(yrange[2], length(tr.rug)) + y.offset, tr.rug, rep(yrange[2], length(tr.rug)) + 100) } warn <- rep(" ", nrow(tr)) for (j in 1:nrow(tr)) { i <- nrow(tr) + 1 - j assign("trpoints", tr[i, !is.na(tr[i, ])]) npnts <- length(trpoints) if (!dRm && !all(sort(trpoints) == trpoints)) ptcol = warn.ord.colour else ptcol = "black" if (npnts > 1) points(sort(trpoints), rep(j, npnts), type = "b", cex = 1, col = ptcol) if (dRm) { lines(xrange * 1.5, rep(j, 2), lty = "dotted") } else { if (npnts > 1) text(sort(trpoints), rep(j, npnts), (1:npnts)[order(trpoints)], cex = cex.gen, pos = 1, col = ptcol) if (!all(sort(trpoints) == trpoints)) warn[j] <- "*" } points(loc[i], j, pch = 20, cex = 1.5, col = ptcol) } if (warn.ord) axis(4, at = 1:nrow(tr), tick = FALSE, labels = warn, hadj = 2.5, padj = 0.7, las = 2) par(mar = c(0, 4, 3, 1)) plot(ttx, tt, type = "n", main = main, axes = FALSE, ylab = "", xlim = xrange, ylim = c(0, max(tt))) points(ttx, tt, type = "h", col = ppdcol, lend = 2, lwd = 5) mtext(pplabel, 2, 0.5, las = 2, cex = cex.gen) box() par(def.par) } } % Add one or more standard keywords, see file 'KEYWORDS' in the % R documentation directory. \keyword{ ~kwd1 }% use one of RShowDoc("KEYWORDS") \keyword{ ~kwd2 }% __ONLY ONE__ keyword per line