Plots a person-item map (also known as a Wright map or targeting plot) for Bayesian IRT models fitted with brms. The plot consists of three vertically stacked panels sharing the same latent variable (theta / logit) x-axis:
Arguments
- model
A fitted
brmsfitobject from an ordinal IRT model (e.g.,family = acat) or a dichotomous model (family = bernoulli()).- item_var
An unquoted variable name identifying the item grouping variable in the model data. Default is
item.- person_var
An unquoted variable name identifying the person grouping variable in the model data. Default is
id.- robust
Logical. If
FALSE(the default), the histogram annotations use mean ± SD. IfTRUE, median ± MAD is used instead.- center
Logical. If
TRUE(the default), the scale is recentered so that the grand mean of all item threshold locations is zero, following the convention in frequentist Rasch analysis. Person estimates are shifted by the same constant. IfFALSE, the raw brms parameterisation is used.- sort_items
Character. How to order items on the y-axis of the bottom panel.
"data"(the default) preserves the order in which items first appear in the model data, with the first item at the top."location"sorts items by their mean threshold location (easiest at top, hardest at bottom).- bins
Integer. Number of bins for both histograms. Default is 30.
- prob
Numeric in \((0, 1)\). Width of the credible intervals for the item threshold whiskers. Default is 0.95.
- palette
An optional character vector of colors for the response categories. If
NULL(the default), theviridisdiscrete scale is used.- person_fill
Fill color for the person histogram. Default is
"#0072B2"(blue).- threshold_fill
Fill color for the threshold histogram. Default is
"#D55E00"(vermillion).- height_ratios
Numeric vector of length 3 specifying the relative heights of the top (person), middle (threshold), and bottom (dot-whisker) panels. Default is
c(3, 2, 5).
Details
Top: A histogram of person ability estimates, with a reference line for the mean (or median) and shading for ±1 SD (or ±1 MAD).
Middle: An inverted histogram of item threshold locations, with a reference line for the mean (or median) and shading for ±1 SD (or ±1 MAD), mirroring the top panel to visualise the overlap between person abilities and item difficulties.
Bottom: A dot-and-whisker plot of item thresholds by item, with credible intervals and color-coded response categories.
Together, the top and middle panels form a half-moon (or back-to-back histogram) display that makes it easy to assess whether the test is well-targeted to the sample.
Person estimates are obtained as the posterior means of
the person random effects from the fitted model via
ranef.
Item thresholds are extracted from the posterior draws.
For models with grouped thresholds (thres(gr = item)),
each item has its own set of threshold parameters. For models
with a single set of thresholds (e.g., dichotomous Rasch with
(1 | item)), the item random effects are subtracted from
the global thresholds to obtain item-specific locations.
When center = TRUE (the default), the grand mean of all
item threshold posterior means is computed and subtracted from
every threshold estimate, its credible interval bounds, and every
person estimate. This is a uniform translation of the entire
scale that preserves all relative distances and matches the
zero-centered item difficulty convention used in frequentist CML
estimation.
References
Wright, B. D. & Stone, M. H. (1979). Best Test Design. MESA Press.
Bürkner, P.-C. (2021). Bayesian Item Response Modeling in R with brms and Stan. Journal of Statistical Software, 100, 1–54. doi:10.18637/jss.v100.i05
See also
plot_ipf for item category probability curves,
ranef,
as_draws_df.
Examples
# \donttest{
library(brms)
library(dplyr)
library(tidyr)
library(tibble)
library(ggplot2)
library(patchwork)
# --- Partial Credit Model ---
df_pcm <- eRm::pcmdat2 %>%
mutate(across(everything(), ~ .x + 1)) %>%
rownames_to_column("id") %>%
pivot_longer(!id, names_to = "item", values_to = "response")
fit_pcm <- brm(
response | thres(gr = item) ~ 1 + (1 | id),
data = df_pcm,
family = acat,
chains = 4,
cores = 1, # use more cores if you have
iter = 500 # use at least 2000
)
#> Compiling Stan program...
#> Error in .fun(model_code = .x1): Boost not found; call install.packages('BH')
# Default: centered, mean ± SD, items in data order
plot_targeting(fit_pcm)
#> Error: object 'fit_pcm' not found
# Uncentered (raw brms parameterisation)
plot_targeting(fit_pcm, center = FALSE)
#> Error: object 'fit_pcm' not found
# Robust: median ± MAD, items sorted by location
plot_targeting(fit_pcm, robust = TRUE, sort_items = "location")
#> Error: object 'fit_pcm' not found
# --- Dichotomous Rasch Model ---
df_rm <- eRm::raschdat3 %>%
as.data.frame() %>%
rownames_to_column("id") %>%
pivot_longer(!id, names_to = "item", values_to = "response")
fit_rm <- brm(
response ~ 1 + (1 | item) + (1 | id),
data = df_rm,
family = bernoulli(),
chains = 4,
cores = 1, # use more cores if you have
iter = 500 # use at least 2000
)
#> Compiling Stan program...
#> Error in .fun(model_code = .x1): Boost not found; call install.packages('BH')
plot_targeting(fit_rm, sort_items = "location")
#> Error: object 'fit_rm' not found
# }