rmcorr: Repeated-Measures Correlation (rmcorr)

View source: R/rmcorr.R

rmcorrR Documentation

Repeated-Measures Correlation (rmcorr)

Description

Computes repeated-measures correlation for two or more continuous responses observed repeatedly within subjects. Supply a data.frame plus column names, or pass the response matrix/data frame and subject vector directly. The repeated observations are indexed only by subject, thus no explicit time variable is modeled, and the method targets a common within-subject linear association after removing subject-specific means.

Usage

rmcorr(
  data = NULL,
  response,
  subject,
  na_method = c("error", "pairwise"),
  conf_level = 0.95,
  n_threads = getOption("matrixCorr.threads", 1L),
  keep_data = FALSE,
  verbose = FALSE,
  ...
)

Arguments

data

Optional data.frame/matrix containing the repeated-measures dataset.

response

Either:

  • a character vector of at least two column names in data, or

  • a numeric matrix/data frame with at least two columns.

If exactly two responses are supplied, the function returns a pairwise repeated-measures correlation object of class "rmcorr". If three or more responses are supplied, a symmetric matrix of class "rmcorr_matrix" is returned.

subject

Subject identifier (factor/character/integer/numeric) or a single character string naming the subject column in data.

na_method

Character scalar controlling missing-data handling. "error" rejects missing values in the selected response columns or subject. "pairwise" uses pairwise complete cases and drops subjects with fewer than two complete pairs for the specific contrast.

conf_level

Confidence level used for Wald confidence intervals on the repeated-measures correlation (default 0.95).

n_threads

Integer \ge 1. Number of OpenMP threads used by the C++ backend in matrix mode. Defaults to getOption("matrixCorr.threads", 1L).

keep_data

Logical (default FALSE). If TRUE, returned objects retain a compact copy of the numeric response matrix plus encoded subject identifiers. For pairwise fits this enables plot() to reconstruct subject-level fitted lines lazily; for matrix outputs it also allows view_rmcorr_shiny() to rebuild pairwise scatterplots from the returned object alone.

verbose

Logical; if TRUE, prints a short note about the thread count used in matrix mode.

...

Deprecated compatibility aliases. The legacy check_na argument is still accepted here temporarily.

Details

Repeated-measures correlation estimates the common within-subject linear association between two variables measured repeatedly on the same subjects. It differs from agreement methods such as Lin's CCC or Bland-Altman analysis because those target concordance or interchangeability, whereas repeated-measures correlation targets the strength of the subject-centred association.

For subject i = 1,\ldots,S and repeated observations j = 1,\ldots,n_i, let x_{ij} and y_{ij} denote the two responses. Define subject-specific means

\bar x_i = \frac{1}{n_i}\sum_{j=1}^{n_i} x_{ij}, \qquad \bar y_i = \frac{1}{n_i}\sum_{j=1}^{n_i} y_{ij}.

The repeated-measures correlation uses within-subject centred values

x^\ast_{ij} = x_{ij} - \bar x_i, \qquad y^\ast_{ij} = y_{ij} - \bar y_i

and computes

r_{\mathrm{rm}} = \frac{\sum_i \sum_j x^\ast_{ij} y^\ast_{ij}} {\sqrt{\left(\sum_i \sum_j {x^\ast_{ij}}^2\right) \left(\sum_i \sum_j {y^\ast_{ij}}^2\right)}}.

Equivalently, this is the correlation implied by an ANCOVA model with a common slope and subject-specific intercepts:

y_{ij} = \alpha_i + \beta x_{ij} + \varepsilon_{ij}.

The returned slope is

\hat\beta = \frac{\sum_i \sum_j x^\ast_{ij} y^\ast_{ij}} {\sum_i \sum_j {x^\ast_{ij}}^2},

and the subject-specific fitted intercepts are \hat\alpha_i = \bar y_i - \hat\beta \bar x_i. Residual degrees of freedom are N - S - 1, where N = \sum_i n_i after filtering to complete observations and retaining only subjects with at least two repeated pairs.

Confidence intervals are computed with a Fisher z-transformation of r_{\mathrm{rm}} and then back-transformed to the correlation scale. In matrix mode, the same estimator is applied to every pair of selected response columns.

Value

Either a "rmcorr" object (exactly two responses) or a "rmcorr_matrix" object (pairwise results when \ge3 responses).

If "rmcorr" (exactly two responses), outputs include:

  • estimate; repeated-measures correlation estimate.

  • p_value; two-sided p-value for the common within-subject slope.

  • lwr, upr; confidence interval limits for estimate.

  • slope; common within-subject slope.

  • df; residual degrees of freedom N - S - 1.

  • n_obs; number of complete observations retained after dropping subjects with fewer than two repeated pairs.

  • n_subjects; number of contributing subjects.

  • responses; names of the fitted response variables.

  • compatibility aliases r, conf_int, and based.on are reconstructed on access without duplicate storage.

  • when keep_data = TRUE, compact source data are retained so plot() can lazily reconstruct data_long, intercepts, and fitted lines; these are otherwise not stored.

If "rmcorr_matrix" (\ge3 responses), outputs are:

  • a symmetric numeric matrix of pairwise repeated-measures correlations.

  • attributes method, description, and package = "matrixCorr".

  • diagnostics; a list with square matrices for slope, p_value, df, n_complete, n_subjects, conf_low, and conf_high, plus scalar conf_level.

Author(s)

Thiago de Paula Oliveira

References

Bakdash, J. Z., & Marusich, L. R. (2017). Repeated Measures Correlation. Frontiers in Psychology, 8, 456. \Sexpr[results=rd]{tools:::Rd_expr_doi("10.3389/fpsyg.2017.00456")}

Examples

set.seed(2026)
n_subjects <- 20
n_rep <- 4
subject <- rep(seq_len(n_subjects), each = n_rep)
subj_eff_x <- rnorm(n_subjects, sd = 1.5)
subj_eff_y <- rnorm(n_subjects, sd = 2.0)
within_signal <- rnorm(n_subjects * n_rep)

dat <- data.frame(
  subject = subject,
  x = subj_eff_x[subject] + within_signal + rnorm(n_subjects * n_rep, sd = 0.2),
  y = subj_eff_y[subject] + 0.8 * within_signal + rnorm(n_subjects * n_rep, sd = 0.3),
  z = subj_eff_y[subject] - 0.4 * within_signal + rnorm(n_subjects * n_rep, sd = 0.4)
)

fit_xy <- rmcorr(dat, response = c("x", "y"), subject = "subject", keep_data = TRUE)
print(fit_xy)
summary(fit_xy)
plot(fit_xy)

fit_mat <- rmcorr(dat, response = c("x", "y", "z"), subject = "subject")
print(fit_mat, digits = 3)
summary(fit_mat)
plot(fit_mat)

if (interactive() && requireNamespace("shiny", quietly = TRUE)) {
  fit_mat_view <- rmcorr(
    dat,
    response = c("x", "y", "z"),
    subject = "subject",
    keep_data = TRUE
  )
  view_rmcorr_shiny(fit_mat_view)
}

matrixCorr documentation built on April 18, 2026, 5:06 p.m.