% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/item_cat_prob.R
\name{RMitemCatProb}
\alias{RMitemCatProb}
\title{Item Category Probability Curves}
\usage{
RMitemCatProb(
  data,
  item_labels = NULL,
  category_labels = NULL,
  theta_range = NULL,
  n_points = 200L,
  viridis_option = "D",
  viridis_end = 0.95,
  facet_ncol = NULL,
  label_wrap = 25L,
  line_width = 0.9,
  font = "sans",
  output = c("ggplot", "dataframe"),
  label_curves = c("legend", "path"),
  item = NULL,
  text_size = 4
)
}
\arguments{
\item{data}{A data.frame or matrix of item responses. Items must be
scored starting at 0 (non-negative integers). Missing values
(\code{NA}) are allowed --- the model fit handles them.}

\item{item_labels}{Optional character vector of descriptive item
labels (facet strip titles). Must be the same length as
\code{ncol(data)}. If \code{NULL} (the default), column names are used.}

\item{category_labels}{Optional character vector of labels for the
response categories (legend). Must be the same length as the
number of categories spanning from 0 to the maximum observed
value. If \code{NULL} (the default), numeric category values are used.}

\item{theta_range}{Numeric length 2. Range of the latent trait
\eqn{\theta} (logits) plotted along the x-axis. When \code{NULL}
(default) the range is \code{c(-4, 4)} for \code{label_curves = "legend"}
and a wider \code{c(-5, 5)} for \code{label_curves = "path"} --- the
wider range gives \code{geomtextpath} more horizontal room to place
per-curve labels at their peaks. Pass an explicit
\code{c(lo, hi)} to override.}

\item{n_points}{Integer. Number of evenly-spaced \eqn{\theta} values
at which the curves are evaluated. Default \code{200L}.}

\item{viridis_option}{Character. Viridis palette identifier. One of
\code{"A"} through \code{"H"}. Default \code{"D"} (viridis green).}

\item{viridis_end}{Numeric in (0, 1]. Upper end of the viridis
palette range; lower values keep the palette inside its mid-tones
(avoids the very bright yellow at \code{1.0}). Default \code{0.95}.}

\item{facet_ncol}{Optional integer. Number of columns in the facet
layout. Default \code{NULL} (\code{ggplot2::facet_wrap()} auto-layout).}

\item{label_wrap}{Integer. Characters per line for facet-strip
label wrapping. Default \code{25L}.}

\item{line_width}{Numeric. Line width for the probability curves.
Default \code{0.9}.}

\item{font}{Character. Font family for all text. Default \code{"sans"}.}

\item{output}{Character. Either \code{"ggplot"} (default) for a
\code{ggplot} object, or \code{"dataframe"} for the underlying long-format
probability table.}

\item{label_curves}{Character. How response categories are
identified. \code{"legend"} (default) draws lines and a separate
colour legend with one swatch per category --- the standard
multi-item presentation. \code{"path"} uses
\code{geomtextpath::geom_textpath()} to write each category's label
\emph{along} its own curve (a la classic IRT trace plots) and
suppresses the legend; valid for \strong{a single item at a time}
because narrow facets do not give path labels enough horizontal
room to render legibly. The model is still fit on the full
multi-item \code{data} (PCM thresholds require multi-item input for
CML estimation); the \code{item} argument then selects which item's
curves to plot. Requires the optional \code{geomtextpath} package.}

\item{item}{Character or integer. Used only when
\code{label_curves = "path"}. Either an item name (matching a column
in \code{data}) or a column index, identifying which item's category
curves to plot. Required for path mode.}

\item{text_size}{Numeric. Used only when \code{label_curves = "path"}.
Size of the path labels in mm. Default \code{4}.}
}
\value{
\itemize{
\item If \code{output = "ggplot"}: a \link[ggplot2:ggplot]{ggplot2::ggplot} object, one facet per
item.
\item If \code{output = "dataframe"}: a long-format data.frame with columns
\code{Item} (factor in column order), \code{Category} (integer), and
\code{Theta}, \code{Probability} (numeric), one row per item × category ×
theta gridpoint.
}
}
\description{
Plots model-implied response-category probability curves for each item
as a function of the latent trait \eqn{\theta}. Item parameters are
estimated by conditional maximum likelihood via \code{psychotools::pcmodel()}
(a dichotomous item is a 2-category PCM). Each item gets
its own facet panel, with one curve per response category coloured
from low to high using the viridis palette. Comparable in scope to
\code{eRm::plotICC()} and \code{mirt}'s trace plots, with a \code{ggplot2} /
viridis output and optional descriptive labels for items and
categories.
}
\details{
For each polytomous item \emph{i} with response categories
\eqn{0, 1, \ldots, K_i} and threshold parameters
\eqn{\delta_{i,1}, \ldots, \delta_{i,K_i}} (CML, \code{psychotools}),
the PCM category probability is

\deqn{P(X_i = k \mid \theta) = \frac{\exp(\sum_{j=1}^{k}
  (\theta - \delta_{i,j}))}{\sum_{k'=0}^{K_i} \exp(\sum_{j=1}^{k'}
  (\theta - \delta_{i,j}))},}

with the empty sum (when \eqn{k = 0}) taken as zero. For
dichotomous items the function fits a Rasch model and treats
the item difficulty \eqn{\delta_i = -\beta_i} as the single
threshold, recovering the standard two-category logistic ICC.

The colour mapping uses \code{scale_color_viridis_c()} against the
integer category value, so the natural ordering of response
categories is preserved visually --- low categories at one end of
the palette, high categories at the other. When \code{category_labels}
is provided, the legend uses those labels (e.g., "Never" /
"Sometimes" / "Often") while the colour mapping stays on the
integer category value.

Items with fewer response categories than the maximum (e.g., an
otherwise four-category scale with one three-category item)
contribute only the categories they actually have to their own
facet --- the y-axis still spans \eqn{[0, 1]}.
}
\examples{
\donttest{
if (requireNamespace("eRm", quietly = TRUE) &&
    requireNamespace("ggplot2", quietly = TRUE)) {
  data(pcmdat2, package = "eRm")

  # Default plot
  RMitemCatProb(pcmdat2)

  # Custom item and category labels
  RMitemCatProb(
    pcmdat2,
    item_labels     = c("Mood", "Sleep", "Appetite", "Energy"),
    category_labels = c("Never", "Sometimes", "Often")
  )

  # Underlying probability data
  df <- RMitemCatProb(pcmdat2, output = "dataframe")
  head(df)

  # Single-item plot with labels written along each curve
  # (classic IRT trace-plot style). Model is still fit on all four
  # items; `item` picks which one to plot.
  if (requireNamespace("geomtextpath", quietly = TRUE)) {
    RMitemCatProb(
      pcmdat2,
      category_labels = c("Never", "Sometimes", "Often"),
      label_curves    = "path",
      item            = "I1"
    )
  }
}
}

}
\seealso{
\code{\link[=RMitemICCPlot]{RMitemICCPlot()}} for conditional ICCs binned by total
score, \code{\link[=RMitemHierarchy]{RMitemHierarchy()}} for item threshold locations on the
logit scale.
}
