% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/bicor.R
\name{bicor}
\alias{bicor}
\alias{diag.bicor}
\alias{print.bicor}
\alias{plot.bicor}
\alias{summary.bicor}
\alias{print.summary.bicor}
\title{Biweight mid-correlation (bicor)}
\usage{
bicor(
  data,
  na_method = c("error", "pairwise", "complete"),
  ci = FALSE,
  conf_level = 0.95,
  n_threads = getOption("matrixCorr.threads", 1L),
  output = c("matrix", "sparse", "edge_list"),
  threshold = 0,
  diag = TRUE,
  c_const = 9,
  max_p_outliers = 1,
  pearson_fallback = c("hybrid", "none", "all"),
  mad_consistent = FALSE,
  w = NULL,
  sparse_threshold = NULL
)

diag.bicor(x, ...)

\method{print}{bicor}(
  x,
  digits = 4,
  n = NULL,
  topn = NULL,
  max_vars = NULL,
  width = NULL,
  ci_digits = 3,
  show_ci = NULL,
  na_print = "NA",
  ...
)

\method{plot}{bicor}(
  x,
  title = "Biweight mid-correlation heatmap",
  reorder = c("none", "hclust"),
  triangle = c("full", "lower", "upper"),
  low_color = "indianred1",
  mid_color = "white",
  high_color = "steelblue1",
  value_text_size = 3,
  ci_text_size = 2.5,
  show_value = TRUE,
  na_fill = "grey90",
  ...
)

\method{summary}{bicor}(
  object,
  n = NULL,
  topn = NULL,
  max_vars = NULL,
  width = NULL,
  ci_digits = 3,
  p_digits = 4,
  show_ci = NULL,
  ...
)

\method{print}{summary.bicor}(
  x,
  digits = NULL,
  n = NULL,
  topn = NULL,
  max_vars = NULL,
  width = NULL,
  show_ci = NULL,
  ...
)
}
\arguments{
\item{data}{A numeric matrix or a data frame containing numeric columns.
Factors, logicals and common time classes are dropped in the data-frame
path. Missing values are not allowed unless \code{na_method = "pairwise"}.}

\item{na_method}{Character scalar controlling missing-data handling.
\code{"error"} rejects missing, \code{NaN}, and infinite values.
\code{"pairwise"} recomputes each estimate on its own pairwise
complete-case overlap. This is permissive, but different matrix entries
may be based on different rows. \code{"complete"} performs listwise
deletion once across the retained numeric columns and then computes the
estimator on the common complete sample.}

\item{ci}{Logical (default \code{FALSE}). If \code{TRUE}, attach approximate
Fisher-z confidence intervals for the off-diagonal biweight
mid-correlations. This confidence interval is provided as an additional
large-sample approximation.}

\item{conf_level}{Confidence level used when \code{ci = TRUE}. Default is
\code{0.95}.}

\item{n_threads}{Integer \eqn{\geq 1}. Number of OpenMP threads. Defaults to
\code{getOption("matrixCorr.threads", 1L)}.}

\item{output}{Output representation for the computed estimates.
\itemize{
\item \code{"matrix"} (default): full dense matrix; best when you need
matrix algebra, dense heatmaps, or full compatibility with existing code.
\item \code{"sparse"}: sparse matrix from \pkg{Matrix} containing only
retained entries; best when many values are dropped by thresholding.
\item \code{"edge_list"}: long-form data frame with columns
\code{row}, \code{col}, \code{value}; convenient for filtering, joins,
and network-style workflows.
}}

\item{threshold}{Non-negative absolute-value filter for non-matrix outputs:
keep entries with \code{abs(value) >= threshold}. Use
\code{threshold > 0} when you want only stronger associations (typically
with \code{output = "sparse"} or \code{"edge_list"}). Keep
\code{threshold = 0} to retain all values. Must be \code{0} when
\code{output = "matrix"}.}

\item{diag}{Logical; whether to include diagonal entries in
\code{"sparse"} and \code{"edge_list"} outputs.}

\item{c_const}{Positive numeric. Tukey biweight tuning constant applied to the
\emph{raw} MAD; default \code{9} (Langfelder & Horvath's convention).}

\item{max_p_outliers}{Numeric in \code{(0, 1]}. Optional cap on the maximum
proportion of outliers \emph{on each side}; if \code{< 1}, side-specific
rescaling maps those quantiles to \code{|u|=1}. Use \code{1} to disable.}

\item{pearson_fallback}{Character scalar indicating the fallback policy.
One of:
\itemize{
\item \code{"hybrid"} (default): if a column has MAD = 0, that column
uses Pearson standardisation, yielding a hybrid correlation.
\item \code{"none"}: return \code{NA} if a column has MAD = 0 or becomes
degenerate after weighting.
\item \code{"all"}: force ordinary Pearson for all columns.
}}

\item{mad_consistent}{Logical; if \code{TRUE}, use the normal-consistent MAD
(\code{MAD_raw * 1.4826}) in the bicor weights. Default \code{FALSE} to
match Langfelder & Horvath (2012).}

\item{w}{Optional non-negative numeric vector of length \code{nrow(data)}
giving \emph{row weights}. When supplied, weighted medians/MADs are used
and Tukey weights are multiplied by \code{w} before normalisation.}

\item{sparse_threshold}{Optional numeric \eqn{\geq 0}. If supplied, sets
entries with \code{|r| < sparse_threshold} to 0 and returns a sparse
\code{"ddiMatrix"} (requires \pkg{Matrix}).}

\item{x}{An object of class \code{summary.bicor}.}

\item{...}{Additional arguments passed to \code{ggplot2::theme()} or other layers.}

\item{digits}{Integer; number of decimal places used for the matrix.}

\item{n}{Optional row threshold for compact preview output.}

\item{topn}{Optional number of leading/trailing rows to show when truncated.}

\item{max_vars}{Optional maximum number of visible columns; \code{NULL} derives this
from console width.}

\item{width}{Optional display width; defaults to \code{getOption("width")}.}

\item{ci_digits}{Integer; digits for bicor confidence limits in the pairwise
summary.}

\item{show_ci}{One of \code{"yes"} or \code{"no"}.}

\item{na_print}{Character; how to display missing values.}

\item{title}{Plot title. Default is \code{"Biweight mid-correlation heatmap"}.}

\item{reorder}{Character; one of \code{"none"} (default) or \code{"hclust"}.
If \code{"hclust"}, variables are reordered by complete-linkage clustering
on the distance \eqn{d = 1 - r}, after replacing \code{NA} by 0 for
clustering purposes only.}

\item{triangle}{One of \code{"full"} (default), \code{"lower"}, or \code{"upper"}
to display the full matrix or a single triangle.}

\item{low_color, mid_color, high_color}{Colours for the gradient in
\code{scale_fill_gradient2}. Defaults are \code{"indianred1"},
\code{"white"}, \code{"steelblue1"}.}

\item{value_text_size}{Numeric; font size for cell labels. Set to \code{NULL}
to suppress labels (recommended for large matrices).}

\item{ci_text_size}{Text size for confidence-interval labels in the heatmap.}

\item{show_value}{Logical; if \code{TRUE} (default), overlay numeric values
on the heatmap tiles.}

\item{na_fill}{Fill colour for \code{NA} cells. Default \code{"grey90"}.}

\item{object}{An object of class \code{bicor}.}

\item{p_digits}{Integer; digits for bicor p-values in the pairwise summary.}
}
\value{
A symmetric correlation matrix with class \code{bicor}
(or a \code{dgCMatrix} if \code{sparse_threshold} is used), with attributes:
\code{method = "biweight_mid_correlation"}, \code{description},
and \code{package = "matrixCorr"}. Downstream code should be prepared to
handle either a dense numeric matrix or a sparse \code{dgCMatrix}. When
\code{ci = TRUE}, the object also carries a \code{ci} attribute with
elements \code{est}, \code{lwr.ci}, \code{upr.ci}, \code{conf.level}, and
\code{ci.method}, together with an \code{inference} attribute containing
the standard large-sample summary matrices \code{estimate},
\code{statistic}, \code{p_value}, \code{Z}, and \code{n_obs}. Pairwise
complete-case counts are stored in \code{attr(x, "diagnostics")$n_complete}.
Internally, all medians/MADs, Tukey weights, optional pairwise-NA handling,
and OpenMP loops are implemented in the C++ helpers
(\code{bicor_*_cpp()}), so the R wrapper mostly validates arguments and
dispatches to the appropriate backend.

Invisibly returns \code{x}.

A \code{ggplot} object.
}
\description{
Computes pairwise biweight mid-correlations for numeric data. Bicor is a
robust, Pearson-like correlation that down-weights outliers and heavy-tailed
observations. Optional large-sample confidence intervals are available as a
derived feature.
}
\details{
For a column \eqn{x = (x_a)_{a=1}^m}, let \eqn{\mathrm{med}(x)} be the median and
\eqn{\mathrm{MAD}(x) = \mathrm{med}(|x - \mathrm{med}(x)|)} the (raw) median
absolute deviation. If \code{mad_consistent = TRUE}, the consistent scale
\eqn{\mathrm{MAD}^\star(x) = 1.4826\,\mathrm{MAD}(x)} is used. With tuning constant
\eqn{c>0}, define
\deqn{u_a = \frac{x_a - \mathrm{med}(x)}{c\,\mathrm{MAD}^{(\star)}(x)}.}
The Tukey biweight gives per-observation weights
\deqn{w_a = (1 - u_a^2)^2\,\mathbf{1}\{|u_a| < 1\}.}
Robust standardisation of a column is
\deqn{\tilde x_a =
\frac{(x_a - \mathrm{med}(x))\,w_a}{
      \sqrt{\sum_{b=1}^m \big[(x_b - \mathrm{med}(x))\,w_b\big]^2}}.}
For two columns \eqn{x,y}, the biweight mid-correlation is
\deqn{\mathrm{bicor}(x,y) = \sum_{a=1}^m \tilde x_a\,\tilde y_a \in [-1,1].}

\strong{Capping the maximum proportion of outliers (\code{max_p_outliers}).}
If \code{max_p_outliers < 1}, let \eqn{q_L = Q_x(\text{max\_p\_outliers})} and
\eqn{q_U = Q_x(1-\text{max\_p\_outliers})} be the lower/upper quantiles of \eqn{x}.
If the corresponding \eqn{|u|} at either quantile exceeds 1, \eqn{u} is rescaled
\emph{separately} on the negative and positive sides so that those quantiles land at
\eqn{|u|=1}. This guarantees that all observations between the two quantiles receive
positive weight. Note the bound applies per side, so up to \eqn{2\,\text{max\_p\_outliers}}
of observations can be treated as outliers overall.

\strong{Fallback when for zero MAD / degeneracy (\code{pearson_fallback}).}
If a column has \eqn{\mathrm{MAD}=0} or the robust denominator becomes zero,
the following rules apply:
\itemize{
\item \code{"none"} when correlations involving that column are \code{NA} (diagonal
remains 1).
\item \code{"hybrid"} when only the affected column switches to Pearson standardisation
\eqn{\bar x_a = (x_a - \overline{x}) / \sqrt{\sum_b (x_b - \overline{x})^2}},
yielding the hybrid correlation
\deqn{\mathrm{bicor}_{\mathrm{hyb}}(x,y) = \sum_a \bar x_a\,\tilde y_a,}
with the other column still robust-standardised.
\item \code{"all"} when all columns use ordinary Pearson standardisation; the result
equals \code{stats::cor(..., method="pearson")} when the NA policy matches.
}

\strong{Handling missing values (\code{na_method}).}
\itemize{
\item \code{"error"} (default): inputs must be finite; this yields a symmetric,
positive semidefinite (PSD) matrix since \eqn{R = \tilde X^\top \tilde X}.
\item \code{"pairwise"}: each \eqn{R_{jk}} is computed on the intersection of
rows where both columns are finite. Pairs with fewer than 5 overlapping
rows return \code{NA} (guarding against instability). Pairwise deletion can
break PSD, as in the Pearson case.
}

\strong{Row weights (\code{w}).}
When \code{w} is supplied (non-negative, length \eqn{m}), the weighted median
\eqn{\mathrm{med}_w(x)} and weighted MAD
\eqn{\mathrm{MAD}_w(x) = \mathrm{med}_w(|x - \mathrm{med}_w(x)|)} are used to form
\eqn{u}. The Tukey weights are then multiplied by the observation weights prior
to normalisation:
\deqn{\tilde x_a =
\frac{(x_a - \mathrm{med}_w(x))\,w_a\,w^{(\mathrm{obs})}_a}{
      \sqrt{\sum_b \big[(x_b - \mathrm{med}_w(x))\,w_b\,w^{(\mathrm{obs})}_b\big]^2}},}
where \eqn{w^{(\mathrm{obs})}_a \ge 0} are the user-supplied row weights and \eqn{w_a}
are the Tukey biweights built from the weighted median/MAD. Weighted pairwise
behaves analogously on each column pair's overlap.

\strong{MAD choice (\code{mad_consistent}).}
Setting \code{mad_consistent = TRUE} multiplies the raw MAD by 1.4826 inside
\eqn{u}. Equivalently, it uses an effective tuning constant
\eqn{c^\star = c \times 1.4826}. The default \code{FALSE} reproduces the convention
in Langfelder & Horvath (2012).

\strong{Optional sparsification (\code{sparse_threshold}).}
If provided, entries with \eqn{|r| < \text{sparse\_threshold}} are set to 0 and the
result is returned as a \code{"ddiMatrix"} (diagonal is forced to 1). This is a
post-processing step that does not alter the per-pair estimates.

\strong{Computation and threads.}
Columns are robust-standardised in parallel and the matrix is formed as
\eqn{R = \tilde X^\top \tilde X}. \code{n_threads} selects the number of OpenMP
threads; by default it uses \code{getOption("matrixCorr.threads", 1L)}.

\strong{Large-sample inference.}
For a pairwise estimate \eqn{r} computed from \eqn{n_{jk}} observed rows, the
standard large-sample summaries use
\deqn{
Z_{jk} = \frac{1}{2}\log\!\left(\frac{1 + r}{1 - r}\right)\sqrt{n_{jk} - 2}
}
and
\deqn{
T_{jk} = \sqrt{n_{jk} - 2}\;\frac{|r|}{\sqrt{1-r^2}}.
}
The reported p-value is the two-sided Student-\eqn{t} tail probability with
\eqn{n_{jk}-2} degrees of freedom. When \code{ci = TRUE}, the package also
reports an approximate Fisher-z confidence interval obtained from
\deqn{
z_{jk} = \operatorname{atanh}(r), \qquad
\operatorname{SE}(z_{jk}) = \frac{1}{\sqrt{n_{jk}-3}},
}
followed by back-transformation with \code{tanh()}. Confidence intervals are currently available only for dense,
unweighted outputs.

\strong{Basic properties.}
\eqn{\mathrm{bicor}(a x + b,\; c y + d) = \mathrm{sign}(ac)\,\mathrm{bicor}(x,y)}.
With no missing data (and with per-column hybrid/robust standardisation), the
output is symmetric and PSD. As with Pearson, affine equivariance does not hold
for the associated biweight midcovariance.
}
\examples{
set.seed(1)
X <- matrix(rnorm(2000 * 40), 2000, 40)
R <- bicor(X, c_const = 9, max_p_outliers = 1,
                       pearson_fallback = "hybrid")
print(attr(R, "method"))
summary(R)
R_ci <- bicor(X[, 1:5], ci = TRUE)
summary(R_ci)
estimate(R_ci)
tidy(R_ci)
ci(R_ci)
confint(R_ci)

# Interactive viewing (requires shiny)
if (interactive() && requireNamespace("shiny", quietly = TRUE)) {
  view_corr_shiny(R)
}

}
\references{
Langfelder, P. & Horvath, S. (2012).
Fast R Functions for Robust Correlations and Hierarchical Clustering.
Journal of Statistical Software, 46(11), 1-17. \doi{10.18637/jss.v046.i11}
}
\author{
Thiago de Paula Oliveira
}
