Learn R Programming

matrixCorr (version 0.12.3)

xi_corr: Pairwise Chatterjee Rank Correlation

Description

Computes the directed Chatterjee rank correlation coefficient for numeric vectors or for all directed column pairs of a numeric matrix/data frame. The matrix orientation is result[i, j] = xi(V_i, V_j), where V_i is the predictor/sorting variable and V_j is the response/ranked variable.

Usage

xi_corr(
  data,
  y = NULL,
  na_method = c("error", "pairwise", "complete"),
  ci = FALSE,
  conf_level = 0.95,
  ci_method = c("auto", "dette_kroll", "n_choose_m"),
  bootstrap_reps = 999L,
  m = NULL,
  large_sample_cutoff = 1000L,
  bias_correction = c("none", "upper_bound"),
  tie_method = c("random", "first"),
  seed = NULL,
  n_threads = getOption("matrixCorr.threads", 1L),
  output = c("matrix", "sparse", "edge_list"),
  threshold = 0,
  diag = TRUE,
  ...
)

# S3 method for chatterjee_xi print( x, digits = 4, n = NULL, topn = NULL, max_vars = NULL, width = NULL, ci_digits = 3, show_ci = NULL, ... )

# S3 method for chatterjee_xi_scalar print(x, digits = 4, ci_digits = 4, ...)

# S3 method for chatterjee_xi_scalar summary(object, digits = 4, ci_digits = 4, ...)

# S3 method for summary.chatterjee_xi_scalar print(x, digits = NULL, ci_digits = NULL, ...)

Value

A directed numeric matrix where the (i, j)-th element is Chatterjee's \(\xi\) from the i-th numeric column to the j-th numeric column. The dense matrix inherits from c("corr_matrix", "chatterjee_xi", "corr_result", "matrix"). When ci = TRUE, the object also carries a ci attribute with elements est, lwr.ci, upr.ci, conf.level, ci.method, se, m, and bootstrap_reps. When pairwise-complete evaluation is used, pairwise sample sizes are stored in attr(x, "diagnostics")$n_complete. In two-vector mode, a numeric scalar is returned; when ci = TRUE, it carries confidence-interval attributes.

Arguments

data

A numeric matrix or a data frame with at least two numeric columns, or a numeric predictor vector when y is supplied. All non-numeric columns will be excluded in matrix/data-frame mode. Each retained column must have at least two non-missing values.

y

Optional numeric response vector for two-vector mode. When supplied, xi_corr(data, y) estimates \(\xi(data, y)\), where data is the sorting/predictor variable and y is the response/ranked variable.

na_method

Character scalar controlling missing-data handling. "error" rejects missing, NaN, and infinite values. "pairwise" recomputes each directed pair on its own pairwise complete-case overlap. This is permissive, but different directed entries may be based on different rows. "complete" performs listwise deletion once across the retained numeric columns and then computes all directed entries on the same complete sample.

ci

Logical (default FALSE). If TRUE, attach m-out-of-n bootstrap confidence intervals for the directed Chatterjee estimates. In two-vector mode the scalar estimate carries a ci attribute.

conf_level

Confidence level used when ci = TRUE. Default is 0.95.

ci_method

Confidence interval method:

  • "auto" (default): use "dette_kroll" when the pair-specific complete-case sample size is less than or equal to large_sample_cutoff, and "n_choose_m" for larger samples.

  • "dette_kroll": m-out-of-n variance estimation followed by a normal interval, following Dette and Kroll.

  • "n_choose_m": non-parametric m-out-of-n basic interval based on the centred and scaled bootstrap statistic, following the large-sample n-choose-m approach used by Dalitz, Arning and Goebbels.

bootstrap_reps

Number of m-out-of-n bootstrap replicates used when ci = TRUE. Larger values reduce Monte Carlo noise but increase runtime.

m

Optional subsample size for the m-out-of-n bootstrap. If NULL, method-specific defaults are used: floor(sqrt(n)) for "dette_kroll" and round(2 * sqrt(n)) for "n_choose_m", each bounded to [2, n - 1].

large_sample_cutoff

For ci_method = "auto", use "n_choose_m" when pair-specific n_complete is greater than this cutoff; otherwise use "dette_kroll".

bias_correction

Finite-sample normalisation:

  • "none" (default): return Chatterjee's original finite-sample statistic without rescaling. This reproduces the estimator as originally defined; its sample maximum is below one for finite continuous samples.

  • "upper_bound": divide by the raw finite-sample upper-bound estimate \(\xi_n(Y,Y)\) and return \(\max(-1, \xi_n(X,Y) / \xi_n(Y,Y))\). Use this option when you want the bias-reduced version proposed by Dalitz, Arning and Goebbels (2024); it is not the default.

tie_method

How ties in the sorting variable \(X\) are broken:

  • "random" (default): randomly permute observations within tied \(X\) groups, matching Chatterjee's random tie-breaking definition.

  • "first": preserve stable input order within tied \(X\) groups, useful for deterministic diagnostics and reproducible comparisons.

seed

Optional positive integer seed for reproducible tie breaking and bootstrap resampling.

n_threads

Integer \(\geq 1\). Number of OpenMP threads. Defaults to getOption("matrixCorr.threads", 1L). Random tie breaking and confidence-interval paths are evaluated serially to preserve R RNG semantics.

output

Output representation for the computed directed estimates.

  • "matrix" (default): full dense directed matrix; best when you need matrix algebra, heatmaps, or full compatibility with existing code.

  • "sparse": sparse matrix from Matrix containing retained directed entries; useful when thresholding leaves relatively few values.

  • "edge_list": long-form data frame with columns row, col, and value; convenient for filtering, joins, and graph/network workflows. Because \(\xi(X,Y)\) is directed, both directions are represented when retained.

threshold

Non-negative absolute-value filter for non-matrix outputs: keep entries with abs(value) >= threshold. Use threshold > 0 when you want only stronger directed associations with output = "sparse" or "edge_list". Must be 0 when output = "matrix".

diag

Logical; whether to include diagonal entries in "sparse" and "edge_list" outputs.

...

Compatibility arguments. The deprecated check_na alias is accepted.

x

An object of class chatterjee_xi.

digits

Integer; number of decimal places to print.

n

Optional row threshold for compact preview output.

topn

Optional number of leading/trailing rows to show when truncated.

max_vars

Optional maximum number of visible columns; NULL derives this from console width.

width

Optional display width; defaults to getOption("width").

ci_digits

Integer; digits for confidence limits.

show_ci

One of "yes" or "no".

object

An object of class chatterjee_xi_scalar.

Author

Thiago de Paula Oliveira

Details

Let \((X_k,Y_k), k=1,\ldots,n\), be complete paired observations. Chatterjee's rank correlation is directed: \(\xi(X,Y)\) measures how well \(Y\) is functionally determined by \(X\). It is not a symmetric association measure, so in matrix mode $$\mathrm{result}_{ij} = \xi(X_{\cdot i}, X_{\cdot j})$$ need not equal \(\mathrm{result}_{ji}\). The row variable is always the sorting/predictor variable and the column variable is the response/ranked variable.

For a given directed pair, observations are sorted by \(X\). Let \(r_i\) be the number of response values \(Y_j \le Y_i\), and let \(l_i\) be the number of response values \(Y_j \ge Y_i\), evaluated for the \(i\)-th observation in sorted-by-\(X\) order. The tied-response finite-sample estimator is $$ \xi_n = 1 - \frac{n \sum_{i=1}^{n-1} |r_{i+1} - r_i|} {2 \sum_{i=1}^n l_i (n - l_i)}. $$ If all response values are equal, the denominator is zero and the estimate is NA. When there are no ties in \(Y\), this reduces to the familiar rank-difference expression $$ \xi_n = 1 - \frac{3 \sum_{i=1}^{n-1}|r_{i+1}-r_i|}{n^2 - 1}. $$ The default bias_correction = "none" returns Chatterjee's original finite-sample estimator. This raw statistic is not forced to attain one under perfect deterministic dependence. In continuous data without ties, its finite-sample upper bound is $$ \xi_{\max} = \xi_n(Y,Y) = \frac{n - 2}{n + 1}. $$ For example, when \(n = 20\), the largest possible raw value is \(18 / 21 \approx 0.857\). This is a property of the estimator rather than an implementation error. Use bias_correction = "upper_bound" when you want the bias-reduced Dalitz-Arning-Goebbels normalisation, which rescales by \(\xi_n(Y,Y)\).

Ties in the sorting variable \(X\) are handled before computing adjacent rank differences. Chatterjee's definition uses random tie breaking, provided here by tie_method = "random". For reproducible diagnostics or when the input order should define tied-\(X\) ordering, use tie_method = "first". Ties in the response variable \(Y\) are handled by the general \(r_i,l_i\) formula above and do not require random tie breaking.

Confidence intervals. The ordinary n-out-of-n bootstrap is not used for Chatterjee's coefficient. Both available intervals use m-out-of-n subsampling without replacement, consistent with the bootstrap family considered for Chatterjee's rank correlation. With ci_method = "dette_kroll", subsamples of size \(m\) are drawn without replacement and the limiting standard deviation is estimated as $$\widehat{\sigma} = \sqrt{m}\,\mathrm{sd}(\xi_m^*).$$ The reported interval is the normal interval $$ \xi_n \pm z_{1-\alpha/2}\widehat{\sigma}/\sqrt{n}, \quad \alpha = 1-\texttt{conf\_level}. $$ If m = NULL, this method uses \(m=\lfloor\sqrt{n}\rfloor\), bounded to \([2,n-1]\).

With ci_method = "n_choose_m", subsamples are also drawn without replacement, but the interval is obtained by inverting the empirical quantiles of the centred and scaled statistic $$T^* = \sqrt{m}(\xi_m^* - \xi_n).$$ If \(q_{\alpha/2}\) and \(q_{1-\alpha/2}\) are the bootstrap quantiles, the basic m-out-of-n limits are $$ \xi_n - q_{1-\alpha/2}/\sqrt{n} \quad\text{and}\quad \xi_n - q_{\alpha/2}/\sqrt{n}. $$ If finite Monte Carlo quantiles fall entirely on one side of zero, the inversion is anchored at zero so that the reported interval contains the observed estimate; the bounds are not clipped to the population parameter range. If m = NULL, this method uses \(m=\mathrm{round}(2\sqrt{n})\), bounded to \([2,n-1]\), following the implementation rule used by Dalitz, Arning and Goebbels.

Which CI method should be used? The Dette-Kroll interval is the more conservative default for small to moderate complete-case sample sizes in this implementation, because it uses the m-out-of-n bootstrap only to estimate a normal-approximation standard error. The non-parametric n-choose-m interval is useful for larger samples when a direct m-out-of-n bootstrap interval is preferred, but Dalitz, Arning and Goebbels report that this interval may need fairly large \(n\) to approach nominal coverage in some settings. Therefore ci_method = "auto" uses "dette_kroll" when pair-specific n_complete <= large_sample_cutoff and "n_choose_m" when n_complete > large_sample_cutoff. Increase bootstrap_reps for final analyses to reduce Monte Carlo error, and consider setting m explicitly when a study protocol requires a fixed subsample size.

Computation. For complete finite matrices without confidence intervals, the C++ backend precomputes each column's sorting order and response ranks and reuses them across directed pairs. This costs \(O(p\,n\log n + p^2 n)\) time and \(O(pn + p^2)\) memory. Pairwise missing-data evaluation and bootstrap confidence intervals recompute on the relevant complete-case samples and are correspondingly more expensive.

References

Chatterjee, S. (2021). A New Coefficient of Correlation. Journal of the American Statistical Association, 116, 2009-2022.

Dette, H. and Kroll, M. (2025). A simple bootstrap for Chatterjee's rank correlation. Biometrika, 112(1), asae045. tools:::Rd_expr_doi("10.1093/biomet/asae045").

Lin, Z. and Han, F. (2025). Limit theorems of Chatterjee's rank correlation. arXiv:2204.08031v4. tools:::Rd_expr_doi("10.48550/arXiv.2204.08031").

Dalitz, C., Arning, J. and Goebbels, S. (2024). A Simple Bias Reduction for Chatterjee's Correlation.

Examples

Run this code
## Example 1: independence versus functional dependence
## Chatterjee's xi targets whether Y is determined by X.
set.seed(1)
n <- 300
x <- runif(n, -1, 1)
y_independent <- rnorm(n)
y_function <- sin(2 * pi * x)
c(
  independent = xi_corr(x, y_independent, tie_method = "first"),
  functional = xi_corr(x, y_function, tie_method = "first")
)

## Example 2: non-monotone functional dependence is directed
## x determines x^2, but x^2 does not determine the sign of x.
## The reverse raw finite-sample estimate can therefore be much smaller,
## and may be negative when sorted response ranks oscillate strongly.
x <- seq(-1, 1, length.out = 300)
y <- x^2
c(
  xi_x_to_y = xi_corr(x, y, tie_method = "first"),
  xi_y_to_x = xi_corr(y, x, tie_method = "first")
)

## Example 3: the raw finite-sample diagonal is not forced to one
## With n = 20 and no ties, the raw finite-sample maximum is 18 / 21.
## Use the Dalitz et al. upper-bound normalisation for the bias-reduced scale.
z <- 1:20
c(
  raw = xi_corr(z, z, tie_method = "first"),
  upper_bound = xi_corr(
    z, z,
    tie_method = "first",
    bias_correction = "upper_bound"
  )
)

## Example 4: directed matrix workflow
X <- cbind(
  x = x,
  square = x^2,
  sine = sin(2 * pi * x),
  noise = rnorm(length(x))
)
xi <- xi_corr(X, tie_method = "first")
print(xi, digits = 3)
summary(xi)
estimate(xi)
tidy(xi)

## Example 5: Dette-Kroll bootstrap interval for a moderate sample
# \donttest{
xi_ci <- xi_corr(
  X[, c("x", "sine")],
  ci = TRUE,
  ci_method = "dette_kroll",
  bootstrap_reps = 49,
  seed = 1,
  tie_method = "first"
)
summary(xi_ci)
ci(xi_ci)
confint(xi_ci)
plot(xi_ci)
# }

## Example 6: n-choose-m interval for larger samples
# \donttest{
set.seed(2)
x_large <- runif(1200, -1, 1)
y_large <- sin(2 * pi * x_large) + rnorm(1200, sd = 0.2)
xi_corr(
  x_large,
  y_large,
  ci = TRUE,
  ci_method = "n_choose_m",
  bootstrap_reps = 99,
  seed = 2,
  tie_method = "first"
)
# }

Run the code above in your browser using DataLab