% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/cicc_plot.R
\name{plot_icc}
\alias{plot_icc}
\title{Item Characteristic Curves with Class Intervals}
\usage{
plot_icc(
  model,
  item_var = item,
  person_var = id,
  items = NULL,
  n_intervals = 5,
  theta_range = c(-4, 4),
  n_points = 200,
  center = TRUE,
  prob = 0.95,
  ncol = NULL,
  line_size = 0.8,
  ribbon_alpha = 0.3,
  point_size = 2.5,
  dif_var = NULL,
  dif_data = NULL,
  dif_labels = NULL,
  dif_stats = TRUE,
  min_n = 5,
  palette = NULL
)
}
\arguments{
\item{model}{A fitted \code{\link[brms]{brmsfit}} object from
an ordinal IRT model (e.g., \code{family = acat}) or a
dichotomous model (\code{family = bernoulli()}).}

\item{item_var}{An unquoted variable name identifying the item
grouping variable in the model data. Default is \code{item}.}

\item{person_var}{An unquoted variable name identifying the
person grouping variable in the model data. Default is
\code{id}.}

\item{items}{An optional character vector of item names to plot.
If \code{NULL} (the default), all items are plotted.}

\item{n_intervals}{Integer. The number of class intervals into
which persons are binned along the sum score. Default is 5.}

\item{theta_range}{A numeric vector of length 2 specifying the
range of theta for the expected curve. Default is
\code{c(-4, 4)}.}

\item{n_points}{Integer. Number of evenly spaced theta values
for computing the expected curve. Default is 200.}

\item{center}{Logical. If \code{TRUE} (the default), the scale
is recentered so the grand mean of item thresholds = 0,
consistent with \code{\link{plot_targeting}}.}

\item{prob}{Numeric in \eqn{(0, 1)}. Width of the credible
interval ribbon around the expected curve. Default is 0.95.}

\item{ncol}{Integer. Number of columns in the faceted layout.
If \code{NULL}, chosen automatically.}

\item{line_size}{Numeric. Line width for the expected curve.
Default is 0.8.}

\item{ribbon_alpha}{Numeric in \eqn{[0, 1]}. Transparency of
the credible interval ribbon. Default is 0.3.}

\item{point_size}{Numeric. Size of observed score points.
Default is 2.5.}

\item{dif_var}{An optional unquoted variable name for a grouping
variable to assess DIF visually. If supplied, observed scores
are computed separately per group and coloured accordingly.}

\item{dif_data}{An optional data frame containing the DIF
variable. Required when \code{dif_var} is specified and the
variable was not part of the model formula (since brms drops
unused variables from \code{model$data}). Must have the same
rows and row order as the original model data.}

\item{dif_labels}{An optional character vector of labels for
the DIF groups. If \code{NULL}, factor levels are used.}

\item{dif_stats}{Logical. If \code{TRUE} (the default when
\code{dif_var} is specified), the partial gamma coefficient
for each item is annotated in the plot panel. The partial
gamma measures the strength of DIF, stratified by total score.}

\item{min_n}{Integer. Minimum number of persons required in a
class interval for the observed mean to be plotted. Intervals
with fewer persons are dropped to avoid unstable estimates.
Default is 5.}

\item{palette}{An optional character vector of colors. If
\code{NULL}, viridis colors are used.}
}
\value{
A \code{\link[ggplot2]{ggplot}} object.
}
\description{
Plots Item Characteristic Curves (ICCs) for Bayesian Rasch-family
models fitted with \pkg{brms}. Each item panel shows the
model-expected item score curve (with a credible interval ribbon)
overlaid with observed average item scores computed within class
intervals. Optionally, observed scores can be split by a grouping
variable to visually assess differential item functioning (DIF).
}
\details{
This is the Bayesian analogue of \code{ICCplot()} from the
\pkg{iarm} package, using the class interval method.

\strong{Expected curve:} For each item, the expected item score
\eqn{E_i(\theta)} is computed for a dense grid of theta values
using the posterior draws of item thresholds. For the adjacent
category (PCM/acat) family:
\deqn{E_i(\theta) = \sum_{c=0}^{K} c \cdot P_{ic}(\theta)}
where \eqn{P_{ic}} are the category probabilities. For
dichotomous items, \eqn{E_i(\theta) = P_i(\theta)}.

The posterior mean of \eqn{E_i(\theta)} is plotted as a line,
with a credible interval ribbon showing the \code{prob} interval
across posterior draws.

\strong{Class intervals:} Following the approach in
\code{iarm::ICCplot()}, persons are binned into class intervals
by their ordinal \emph{sum score} (the sufficient statistic in
Rasch models), not by their EAP theta estimate. Within each
interval, the mean observed item response is computed and
plotted at the theta value corresponding to the mean sum score
in that interval, obtained by inverting the posterior-mean
expected total score function. Persons with extreme sum scores
(0 and maximum) are excluded from the class intervals, as their
theta positions cannot be estimated.

\strong{Uncertainty around observed points:} For each class
interval, the standard error of the mean observed response is
computed and displayed as error bars showing \eqn{\pm 1.96} SE.
These reflect sampling variability of the observed mean within
each bin.

\strong{DIF overlay:} When \code{dif_var} is specified, observed
scores are computed separately for each level of the DIF
variable, producing group-specific points connected by lines.
Deviations between groups that track alongside each other (but
offset from the expected curve) suggest uniform DIF. Crossing
group lines suggest non-uniform DIF.

\strong{Partial gamma:} When \code{dif_stats = TRUE} (default
when DIF is requested), the Goodman-Kruskal partial gamma
coefficient is displayed in each item panel. This measures the
ordinal association between item response and DIF group,
stratified by total score. Values near 0 indicate no DIF;
values near \eqn{\pm 1} indicate strong DIF. The computation
reuses the concordant/discordant pair counting algorithm from
\code{\link{gk_gamma}}.
}
\examples{
\donttest{
library(brms)
library(dplyr)
library(tidyr)
library(tibble)
library(ggplot2)

# --- 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 = 2, iter = 1000 # use more iter and cores
)

# Basic ICC plot with 5 class intervals
plot_icc(fit_pcm)

# Select specific items, more intervals
plot_icc(fit_pcm, items = c("I1", "I2"), n_intervals = 5)

# With DIF overlay and partial gamma annotation

# same dataset, adding a `gender` DIF variable
df_pcm <- eRm::pcmdat2 \%>\%
  mutate(across(everything(), ~ .x + 1)) \%>\%
  rownames_to_column("id") \%>\%
  mutate(gender = sample(c("M", "F"), nrow(.), TRUE)) \%>\% 
  pivot_longer(!c(id,gender), names_to = "item", values_to = "response")
  
plot_icc(fit_pcm, dif_var = gender, dif_data = df_pcm,
         dif_labels = c("Female", "Male"), n_intervals = 5)
}

}
\seealso{
\code{\link{plot_ipf}} for category probability curves,
\code{\link{plot_targeting}} for person-item maps,
\code{\link{dif_statistic}} for formal Bayesian DIF testing,
\code{\link{gk_gamma}} for the underlying gamma algorithm.
}
