Using WrightMap with the TAM package

[This article was first published on R Snippets for IRT, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

WrightMap features close integration with Conquest, allowing you to easily read from its output files. However, this is just a nice convenience for Conquest users, as WrightMap was designed to create beautiful item-person plots simply reading standard R matrices; all you need is a matrix of item parameters and a matrix of person estimates and you can start creating nice Wright Maps. For this reason, the WrightMap package can be used to plot the results of any IRT software, and makes it very easy to integrate with other R packages that estimate IRT models.

This post will show you how you can integrate R with one of these estimation packages, the Test Analysis Module (TAM) package in just a couple of lines.


Let’s start by loading TAM


And we can use one of TAM’s simulated datasets (without any missing data in this case) for this example:


##  num [1:2000, 1:40] 1 0 1 1 1 1 1 1 1 1 ...
##  - attr(*, "dimnames")=List of 2
##   ..$ : NULL
##   ..$ : chr [1:40] "I1" "I2" "I3" "I4" ...

We use the data command to load the sim.rash dataset. A quick look with str confirms that we now have a simulated dataset with responses from 2000 persons (rows) to 40 items (cols). We are ready to go!

Analysis with TAM

In this example we will run a Rasch model using the TAM command tam.mml, which will estimate the model given these responses using a marginal maximum likelihood method.

mod1 <- tam.mml(resp=sim.rasch)

The estimation should take very little time (although I imagine your mileage may vary depending on your computer), and you should see a summary of the results and the total that it took to run the analysis.

Person estimates

You can get person estimates in several ways in TAM, but for this example I will use the tam.wle command, that produces Warm Likelihood Estimates for each respondent.

persons.mod1 <- tam.wle( mod1 )

## Iteration in WLE/MLE estimation  1   | Maximal change  0.3986 
## Iteration in WLE/MLE estimation  2   | Maximal change  0.073 
## Iteration in WLE/MLE estimation  3   | Maximal change  0.0011 
## Iteration in WLE/MLE estimation  4   | Maximal change  1e-04 
## ----
## WLE Reliability = 0.894


## 'data.frame':    2000 obs. of  7 variables:
##  $ pid         : int  1 2 3 4 5 6 7 8 9 10 ...
##  $ N.items     : num  40 40 40 40 40 40 40 40 40 40 ...
##  $ PersonScores: num  19 14 35 14 27 12 23 17 5 12 ...
##  $ PersonMax   : num  40 40 40 40 40 40 40 40 40 40 ...
##  $ theta       : num  -0.116 -0.791 2.373 -0.791 0.964 ...
##  $ error       : num  0.366 0.377 0.498 0.377 0.382 ...
##  $ WLE.rel     : num  0.894 0.894 0.894 0.894 0.894 ...

If we look at the resulting matrix, we can see that we have several columns, including:

  • pid: the ID of the respondent
  • N.items:the number of items
  • PersonScores: The score of each person
  • PersonMax: The maximum possible score of each person
  • theta: The WLE estimate
  • error: The standard error of the WLE estimate
  • WLE.rel: The WLE reliability

You can look at the TAM documentation for more details, but for this example, we want to focus on the theta column, which contains the person estimates we need to create our Wright map.

We can get the data we need then by selecting just that column:

WLEestimates.mod1 <- persons.mod1$theta

Item parameters

And we can get our item estimates using the tam.threshold command.

thresholds.mod1 <- tam.threshold(mod1)

Creating the Wright Map

With this two matrices we are ready to plot our Wright Map:

wrightMap(WLEestimates.mod1, thresholds.mod1)

Wright Map - Default

And you can start editing it to make it nicer:

wrightMap(WLEestimates.mod1, thresholds.mod1, show.thr.lab = FALSE, label.items = c(1:40), label.items.rows = 3)

Wright Map - Customized

To leave a comment for the author, please follow the link and comment on their blog: R Snippets for IRT. offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)