Plotting Unidimensional/Dichotomous Models

Updated Fri 24-Apr-2020

Setup and basics

This is an introduction to the wrightMap function in the WrightMap package. The wrightMap function creates Wright Maps based on person estimates and item parameters produced by an item response analysis. The CQmodel function reads output files created using ConQuest software and creates a set of data frames for easy data manipulation, bundled in a CQmodel object. The wrightMap function can take a CQmodel object as input or it can be used to create Wright Maps directly from data frames of person and item parameters.

Setup

Let’s start by installing the latest version of the package from CRAN.

library(WrightMap)

We will also install RColorBrewer to take advantage of its color palettes.

install.packages("RColorBrewer")
library(RColorBrewer)

A simple dichotomous example

To plot a simple Rasch model, we start by creating mock person and item estimates.

For the person proficiencies we create a single vector with 1000 values.

# We set the seed to reproduce the same results
set.seed(2020)
rasch.sim.thetas <- rnorm(1000)

And for the item difficulties we create a vector with 10 values.

rasch.sim.thresholds <- runif(10, -3, 3)

We now have all we need to create a WrightMap with a single line.

wrightMap( rasch.sim.thetas, rasch.sim.thresholds)

We can start to customize the Wright Map by simply relabeling its main parts using main.title , axis.logits , axis.persons and axis.items.

wrightMap(rasch.sim.thetas, rasch.sim.thresholds
	 , main.title = "This is my example Wright Map"
	, axis.persons = "This is the person distribution"
	, axis.items = "This are my survey questions")

The Person Side and the Item Side

If you do not like histograms, Wright Map has the option person.side that allows you to switch between histograms (the default option: personHist ) or density using the option personDens.

wrightMap(rasch.sim.thetas, rasch.sim.thresholds, person.side = personDens)

Or, you may want to change the way items are represented by using the option item.side , which offers in addition to itemModern (the default representation), it offers itemClassic (for ConQuest-style Wright Maps), and a itemHist for a histogram summary of the items.

The itemClassic options is well suited for cases where you want to include many items using less space (or if you really like the original plain text flavored Wright Maps). See in this example how we are including 150 item difficulties.

rasch.sim.thresholds.2 <- runif(150, -3, 3)
wrightMap(rasch.sim.thetas, rasch.sim.thresholds.2, item.side = itemClassic)

Alternatively, you can represent use a back-to-back histogram representation with itemHist (notice that in the following example we are using the option item.prop to adjust the relative sizes of the person and item side).

rasch.sim.thresholds.3 <- rnorm(150)
wrightMap(rasch.sim.thetas, rasch.sim.thresholds.2, item.side = itemHist, item.prop = 0.5)

Customizing Wright Maps

Let us focus on the defaults item and person side representations to explore their potential customizations.

You might want to remove the label for the item difficulties by setting show.thr.lab = FALSE.

wrightMap(rasch.sim.thetas, rasch.sim.thresholds, show.thr.lab = FALSE)

Or you might want to see just labels, by turning of symbols with show.thr.sym = FALSE.

wrightMap(rasch.sim.thetas, rasch.sim.thresholds, show.thr.sym = FALSE)

Customizing symbols

Let’s start by making all the symbols bigger with thr.sym.cex = 2.5 (default is 1).

wrightMap(rasch.sim.thetas, rasch.sim.thresholds
	, show.thr.lab = FALSE, thr.sym.cex = 2.5)

To select what kind of symbols you want to use you can use the thr.sym.pch parameter.

wrightMap(rasch.sim.thetas, rasch.sim.thresholds, show.thr.lab = FALSE
	, thr.sym.cex = 2.5, thr.sym.pch = 17)

For a list of all the characters that you can use in R and their code, you can type ?points or visit:

http://rgraphics.limnology.wisc.edu/pch.php

For the next couple of examples we will need some colors.

display.brewer.pal(10, "Paired")

itemcolors <- brewer.pal(10, "Paired")

Now let’s use those colors in our item difficulty symbols using the thr.sym.col.fg.

wrightMap(rasch.sim.thetas, rasch.sim.thresholds, show.thr.lab = FALSE
	, thr.sym.pch = 17, thr.sym.cex = 2.5, thr.sym.col.fg = itemcolors)

Notice that there is also a thr.sym.col.bg parameter that controls the secondary color of symbols that have both foreground and background (i.e. the PCH’s from 21 to 25).

You’ll notice that our color vector has 10 colors, and we have 10 item difficulties. In the wrightMap function, each item difficulty receives it’s color from the corresponding color vector. This means that you can control the properties of each one of the points separately. Let’s just change the color, symbol and size of the 2nd and 8th item difficulty by passing custom vectors to the thr.sym.pch , thr.sym.cex , and thr.sym.col.fg parameters.

itemcolors28 <- c("grey", "red", "grey", "grey", "grey", "grey", "grey", "red", 
    "grey")
itempch28 <- c(19, 18, 19, 19, 19, 19, 19, 18, 19)
itemcex28 <- c(1, 2.5, 1, 1, 1, 1, 1, 2.5, 1)

wrightMap(rasch.sim.thetas, rasch.sim.thresholds, show.thr.lab = FALSE, thr.sym.pch = itempch28, 
    thr.sym.cex = itemcex28, thr.sym.col.fg = itemcolors28)

Customizing labels

But if you do not like symbols that much, you can stick to labeling the item difficulty parameters. However, we need some items names to make this more interesting.

itemnames <- c("Dasher", "Dancer", "Prancer", "Vixen", "Comet", "Cupid", "Donner", 
    "Blitzen", "Rudolph", "Olive")

With those ten names in a vector we can now assign them to our item difficulties using the thr.lab.text parameter.

wrightMap(rasch.sim.thetas, rasch.sim.thresholds, show.thr.sym = FALSE
	, thr.lab.text = itemnames)

Just as we did with the symbols, we can can control the size of the text using the thr.lab.cex parameter.

wrightMap(rasch.sim.thetas, rasch.sim.thresholds, show.thr.sym = FALSE
	, thr.lab.text = itemnames, thr.lab.cex = 1.5)

And we can of course control the colors using thr.lab.col.

wrightMap(rasch.sim.thetas, rasch.sim.thresholds, show.thr.sym = FALSE
	, thr.lab.text = itemnames, thr.lab.col = itemcolors, thr.lab.cex = 1.5)

Finally, if you want to go crazy, you can also change the type style using thr.lab.font. This parameter follows the R convention where 1 = plain, 2 = bold, 3 = italic, 4 = bold italic.

For this example, we are going to pass a vector of length 4 with each style. wrightMap will deal with this by repeating it until it matches the number of item difficulties, 10 in this case, so it will produce the following vector: c(1,2,3,4,1,2,3,4,1,2) .

wrightMap(rasch.sim.thetas, rasch.sim.thresholds, show.thr.sym = FALSE
	, thr.lab.text = itemnames, thr.lab.col = itemcolors
	, thr.lab.cex = 1.5, thr.lab.font = c(1:4))