% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/brms_globalfit.R
\name{plot_residual_pca}
\alias{plot_residual_pca}
\title{Residual PCA Contrast Plot for Bayesian IRT Models}
\usage{
plot_residual_pca(
  model,
  item_var = item,
  person_var = id,
  center = TRUE,
  prob = 0.95,
  ndraws_use = NULL,
  style = c("both", "density", "crosshair"),
  density_alpha = 0.3,
  density_bins = 6,
  density_palette = NULL,
  label_items = TRUE,
  point_size = 2.5,
  point_color = "#0072B2"
)
}
\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{center}{Logical. If \code{TRUE} (the default), item
locations are mean-centered to zero, matching the convention
used in \code{\link{plot_targeting}}.}

\item{prob}{Numeric in \eqn{(0, 1)}. Width of the credible
intervals for both loading and location whiskers. Default is
0.95.}

\item{ndraws_use}{Optional positive integer. Number of posterior
draws to use. If \code{NULL} (the default), up to 500 draws
are used.}

\item{style}{Character. Visual style for displaying uncertainty.
\code{"density"} (the default) overlays filled 2D density
contours per item computed from the draw-level location and
loading values, showing the full joint posterior uncertainty.
\code{"crosshair"} shows point estimates with horizontal and
vertical credible interval bars.
\code{"both"} displays density contours with crosshairs on top.}

\item{density_alpha}{Numeric in \eqn{[0, 1]}. Maximum opacity
of the density contours when \code{style} is \code{"density"}
or \code{"both"}. Default is 0.3.}

\item{density_bins}{Integer. Number of contour bins for
\code{\link[ggplot2]{geom_density_2d_filled}}. Default is 6.}

\item{density_palette}{An optional character vector of colors for
the density contour fills (from low to high density). If
\code{NULL} (the default), a blue sequential ramp is used. The
length should match \code{density_bins}; the lowest
(background) level is always transparent.}

\item{label_items}{Logical. If \code{TRUE} (the default), item
names are displayed next to points.}

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

\item{point_color}{Color for the item points and error bars.
Default is \code{"#0072B2"}.}
}
\value{
A list with three elements:
\describe{
\item{plot}{A \code{\link[ggplot2]{ggplot}} object showing item
loadings on the first residual contrast (y-axis) versus item
locations (x-axis).}
\item{data}{A \code{\link[tibble]{tibble}} with columns:
\code{item}, \code{location} (posterior mean item location),
\code{location_lower}, \code{location_upper} (location CI),
\code{loading} (posterior mean loading on first contrast),
\code{loading_lower}, \code{loading_upper} (loading CI).}
\item{eigenvalue}{A \code{\link[tibble]{tibble}} with columns:
\code{eigenvalue_obs} (posterior mean observed eigenvalue),
\code{eigenvalue_rep} (posterior mean replicated eigenvalue),
\code{eigenvalue_diff} (posterior mean difference),
\code{ppp} (posterior predictive p-value),
\code{var_explained_obs}, \code{var_explained_rep} (posterior
mean proportions of residual variance explained).}
}
}
\description{
Assesses dimensionality of Bayesian IRT models by performing a
principal component analysis (PCA) of standardized residuals for
each posterior draw. The item loadings on the first residual
contrast are plotted against item locations, with posterior
uncertainty displayed as 2D density contours, crosshairs, or
both. A posterior predictive p-value for the first-contrast
eigenvalue tests whether the observed residual structure exceeds
what the model predicts under unidimensionality.
}
\details{
The procedure for each posterior draw \eqn{s} is:

\enumerate{
\item Obtain category probabilities from
\code{\link[brms]{posterior_epred}}. Compute expected values
\eqn{E^{(s)}_{vi}} and variances \eqn{Var^{(s)}_{vi}}.
\item Compute standardized residuals for observed data:
\deqn{z^{obs(s)}_{vi} = \frac{X_{vi} - E^{(s)}_{vi}}
      {\sqrt{Var^{(s)}_{vi}}}}
\item Generate replicated data \eqn{Y^{rep(s)}} from
\code{\link[brms]{posterior_predict}} and compute standardized
residuals:
\deqn{z^{rep(s)}_{vi} = \frac{Y^{rep(s)}_{vi} -
      E^{(s)}_{vi}}{\sqrt{Var^{(s)}_{vi}}}}
\item Reshape both sets of residuals into person \eqn{\times}
item matrices and perform SVD on each.
\item Extract the first-contrast eigenvalue and item loadings
from both observed and replicated SVDs.
\item Compare eigenvalues across draws: the posterior predictive
p-value \code{ppp = mean(eigenvalue_obs > eigenvalue_rep)}
tests whether the observed residual structure is stronger than
what the model produces under its own assumptions.
}

When \code{style = "density"} or \code{style = "both"}, the
draw-level (location, loading) pairs for each item are used to
construct filled 2D kernel density contours via
\code{\link[ggplot2]{geom_density_2d_filled}}. The lowest
contour level (outside all contours) is set to transparent so
the white panel background shows through. Higher density regions
use progressively darker fills.

Item loadings are aligned across draws using majority-sign
alignment to resolve the sign indeterminacy of eigenvectors.
}
\examples{
\dontrun{
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  = 4,
  iter   = 2000
)

# 2D density contours (default)
result <- plot_residual_pca(fit_pcm)
result$plot

# Crosshair style
result_c <- plot_residual_pca(fit_pcm, style = "crosshair")
result_c$plot

# Both combined
result_b <- plot_residual_pca(fit_pcm, style = "both")
result_b$plot

# Custom warm palette
result_w <- plot_residual_pca(
  fit_pcm,
  density_palette = c("#FEE8C8", "#FDBB84", "#E34A33",
                      "#B30000", "#7F0000", "#4A0000"),
  point_color = "#B30000"
)
result_w$plot
}

}
\references{
Smith, E. V. (2002). Detecting and evaluating the impact of
multidimensionality using item fit statistics and principal
component analysis of residuals. \emph{Journal of Applied
Measurement}, \emph{3}, 205--231.

Bürkner, P.-C. (2021). Bayesian Item Response Modeling in R with
brms and Stan. \emph{Journal of Statistical Software}, \emph{100},
1--54. \doi{10.18637/jss.v100.i05}
}
\seealso{
\code{\link{plot_targeting}} for person-item maps,
\code{\link{plot_ipf}} for item category probability curves,
\code{\link{q3_statistic}} for Q3 residual correlations (another
local dependence / dimensionality diagnostic).
}
