% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/martin_lof.R
\name{RMdimMartinLofResiduals}
\alias{RMdimMartinLofResiduals}
\title{Standardised Residuals from the Joint Subscore Distribution}
\usage{
RMdimMartinLofResiduals(
  data,
  partition,
  output = c("kable", "dataframe", "ggplot"),
  flag_threshold = 2,
  color_by = c("residual", "n"),
  color_limits = NULL,
  min_expected = NULL
)
}
\arguments{
\item{data}{A data.frame or matrix of item responses (0-based,
non-negative integers). Rows with any \code{NA} are dropped.}

\item{partition}{Same format as in \code{\link{RMdimMartinLof}}: a list of
item-name/index vectors, or a length-\code{ncol(data)} vector of group
labels. Each subscale must contain at least 2 items.}

\item{output}{Character. \code{"kable"} (default) for a 2-D pipe-format
residual table when D = 2 (long-format kable when D > 2), \code{"dataframe"}
for the underlying long-format data.frame, or \code{"ggplot"} for a
diverging-fill heatmap (with \code{facet_wrap} over \code{t3} for D = 3, error
for D > 3).}

\item{flag_threshold}{Numeric. Cells with \verb{|residual| > flag_threshold}
are flagged: marked as \verb{**bold**} in the kable, shown in the \code{flagged}
column of the dataframe. Default \code{2}.}

\item{color_by}{Character. For \code{output = "ggplot"}, what the tile fill
colour encodes. \code{"residual"} (default) -- diverging red-white-blue scale
centred at 0, the most directly diagnostic. \code{"n"} -- sequential blue
scale on the observed cell count, useful for spotting whether
large-magnitude residuals are driven by sparse cells. Either way, the
numeric residual is printed inside each cell.}

\item{color_limits}{Numeric length-2 vector or \code{NULL}. Caps the colour
scale for \code{output = "ggplot"}. Default \code{c(-5, 5)} when
\code{color_by = "residual"} (sparse-cell residuals from
\code{(o-e)/sqrt(n*p*(1-p))} can be enormous when expected counts are tiny;
capping the scale stops outliers from compressing the rest of the
plot). The unclipped residual values still appear as cell labels.
\code{NULL} for \code{color_by = "n"}, which uses the natural data range.}

\item{min_expected}{Numeric or \code{NULL}. If set, cells with \code{expected < min_expected} have their residual set to \code{NA} (they appear grey in the
heatmap and are not flagged). Default \code{NULL} (no filtering). Setting
\code{min_expected = 1} (or \code{5}) is the analogue of the Cochran rule for
sparse-cell chi-square contributions and removes residuals whose
asymptotic standard normal approximation is unreliable.}
}
\value{
\itemize{
\item \code{output = "kable"}: a \code{knitr_kable} object. For D = 2, a wide table
with rows = \code{t1}, columns = \code{t2}, cells = standardised residual
(\verb{**bold**} if flagged, em-dash if NA). For D > 2, long-format with
one row per cell.
\item \code{output = "dataframe"}: a long-format data.frame with columns \code{t1},
..., \code{tD}, \code{total}, \code{observed}, \code{expected}, \code{residual}, \code{flagged}.
\item \code{output = "ggplot"}: a \code{geom_tile()} heatmap (D = 2 or 3 only).
}
}
\description{
Diagnostic accompanying \code{\link{RMdimMartinLof}}: per-cell standardised
residuals from the joint distribution of subscores under unidimensionality
(Christensen, Bjorner, Kreiner, & Petersen, 2002, eq. 13). Useful for
identifying \emph{where} a partition deviates from the unidimensional null
rather than just whether it does (which \code{RMdimMartinLof()} answers).
}
\details{
For each cell of the joint subscore table (indexed by
\eqn{(t_1, \ldots, t_D)}), the conditional probability under H0 given the
total score \eqn{t = \sum_d t_d} is
\deqn{p(t_1, \ldots, t_D \mid t) = \prod_d \gamma^{(d)}_{t_d} / \gamma_t,}
the expected count is \eqn{e = n_t \cdot p}, and the residual is
\eqn{(o - e) / \sqrt{n_t \cdot p \cdot (1 - p)}}. CML estimates from the
unidimensional model are used for the \eqn{\gamma}-functions.

Reading the table (D = 2): under the unidimensional null, residuals
should be patternless and roughly N(0, 1). Multidimensionality with
positively correlated dimensions typically shows up as \strong{positive}
residuals at the corners of each antidiagonal (high \code{t1} + low \code{t2},
low \code{t1} + high \code{t2}) and \strong{negative} residuals near the antidiagonal
centre (matched subscores). Negatively correlated dimensions show
positive residuals at the table corners (high/low and low/high) and
negative residuals at high/high and low/low. See Christensen et al.
(2002, section7) for a worked example.

Cells where the total score has no observed cases (\code{n_t = 0}) are
uninformative and are dropped from the output.
}
\examples{
\donttest{
set.seed(1)
dat <- as.data.frame(matrix(sample(0:1, 400 * 8, replace = TRUE),
                            nrow = 400, ncol = 8))
colnames(dat) <- paste0("I", 1:8)

# Wide kable table for D = 2
RMdimMartinLofResiduals(dat,
                     partition = list(c("I1","I2","I3","I4"),
                                      c("I5","I6","I7","I8")))

# Heatmap
if (requireNamespace("ggplot2", quietly = TRUE)) {
  RMdimMartinLofResiduals(dat,
                       partition = c(1,1,1,1,2,2,2,2),
                       output = "ggplot")
}

# Underlying data.frame for custom analysis
df <- RMdimMartinLofResiduals(dat,
                           partition = c(1,1,1,1,2,2,2,2),
                           output = "dataframe")
df[df$flagged, ]
}
}
\references{
Christensen, K. B., Bjorner, J. B., Kreiner, S., & Petersen, J. H. (2002).
Testing unidimensionality in polytomous Rasch models. \emph{Psychometrika,
67}(4), 563-574. \doi{10.1007/BF02295132}
}
\seealso{
\code{\link{RMdimMartinLof}}
}
