Skip to contents

Detects the types of x and y, selects a suitable correlation method, and returns the estimate with its confidence interval and p-value.

Usage

smart_cor(
  x,
  y,
  x_type = NULL,
  y_type = NULL,
  method = NULL,
  assume_latent_normal = "auto",
  ordinal_threshold = 10,
  ignore_na = TRUE,
  conf_level = 0.95,
  bootstrap = "auto",
  n_boot = 500,
  n_perm = 500,
  seed = NULL,
  verbose = TRUE
)

Arguments

x, y

Vectors of the same length. May be numeric, factor, character, or logical.

x_type, y_type

Optional character strings ("continuous", "count", "binary", "ordinal", "categorical") to override automatic type detection.

method

Optional character string to force a specific method. One of "pearson", "spearman", "kendall", "phi", "tetrachoric", "yules_q", "polychoric", "polyserial", "cramers_v", "theils_u", "tschuprows_t", "gamma", "rank_biserial", or "point_biserial".

assume_latent_normal

"auto" (default), logical, or NULL. "auto" runs a likelihood-ratio chi-square test (via test_bivariate_normality()) and decides whether the data satisfies bivariate normality; a saturated 2 x 2 table defaults to the observed-scale method (phi). TRUE forces polychoric / polyserial / tetrachoric; FALSE forces Kendall's tau / Spearman / phi. NULL asks interactively (defaults to TRUE in non-interactive sessions).

ordinal_threshold

Integer passed to detect_type(). Default: 10.

ignore_na

Logical. If TRUE (default), rows with missing values in either x or y are silently removed (pairwise complete observations). If FALSE, the function errors when NA values are present.

conf_level

Numeric between 0 and 1. Confidence level for intervals. Default: 0.95.

bootstrap

Character or logical. Controls bootstrap inference: "auto" (default) bootstraps only when analytic CIs are unavailable; TRUE always replaces the analytic CI with a percentile-bootstrap CI; FALSE never bootstraps. P-values remain analytic (or permutation-based for Theil's U) under every setting.

n_boot

Integer. Number of bootstrap replications when bootstrapping. Default: 500.

n_perm

Integer. Number of shuffles for the permutation p-value of Theil's U. Default: 500.

seed

Optional integer seed for the bootstrap and permutation draws. The global .Random.seed is saved and restored around a seeded call, so the global RNG state is restored. Seeded results are reproducible across R sessions but do not match the Python package, whose numpy generator draws differently.

verbose

Logical. If TRUE (default), prints messages about the detection and selection process.

Value

An object of class "smartcor": a named list with elements estimate, method, method_label, x_type, y_type, n, n_complete, statistic, p.value, ci_lower, ci_upper, conf_level, ci_method, ci_source, p_method, null_hypothesis, p_interpretation, alternatives, and rationale. Has custom print.smartcor() and tidy.smartcor() methods.

Details

The method selection follows Harshvardhan, M. and Ranjan, P. (2026), "smartcor: Intelligent Correlation Method Selection for Mixed Variable Types" (arXiv:2607.22285, doi:10.48550/arXiv.2607.22285 ); the package vignettes (browseVignettes("smartcor")) cover the same material in more depth:

Variable typesDefault methodAlternative
Correlation methods (signed, from -1 to +1)
continuous + continuousPearsonSpearman (suggested, especially if nonlinear)
continuous + binaryPearson = point-biserial
binary + binaryPearson = phiTetrachoric (preferred, if latent normality holds)
continuous + ordinalSpearman/KendallPolyserial (preferred, if latent normality holds)
ordinal + ordinalKendall's tauPolychoric (preferred, if latent normality holds)
binary + ordinalRank-biserialSpearman
Association measures (unsigned, from 0 to 1)
continuous + categoricalCramer's V (binned)
binary + categoricalCramer's V
ordinal + categoricalCramer's V
categorical + categoricalCramer's VTheil's U, Tschuprow's T

Count variables are treated as numeric continuous variables, so each count combination follows the corresponding continuous row.

When assume_latent_normal = "auto" (the default), a likelihood-ratio chi-square test (test_bivariate_normality()) decides whether the data satisfies bivariate normality. A binary-binary pair is an exception: its 2 x 2 table is saturated (df = 0), the test has nothing to work with, and the data cannot support the latent-normality assumption, so smartcor reports phi. Tetrachoric remains available via assume_latent_normal = TRUE or method = "tetrachoric".

When a latent-variable estimator fails numerically (singular Hessian, sparse table), the function falls back to Kendall's tau or Spearman and the returned method, method_label, and rationale name the method actually used, not the one that failed.

One caveat on the point-biserial interval: it reuses the Fisher-z variance 1/(n - 3), which assumes bivariate normality; a binary margin cannot satisfy that exactly, so treat the interval as approximate.

Theil's U is asymmetric: method = "theils_u" computes U(y|x), the proportion of the entropy in y explained by x. Swap the arguments for the other direction. Its p-value comes from a permutation test (n_perm shuffles of y), not from the bootstrap.

Examples

path = system.file("extdata", "gss_2024_casestudy.csv", package = "smartcor")
gss = read.csv(path)

# Continuous and binary variables use point-biserial correlation.
smart_cor(gss$coninc, gss$sex, verbose = FALSE)
#> 
#> ── Smart Correlation ───────────────────────────────────────────────────────────
#> Estimate: -0.1008
#> Method: Point-Biserial Correlation (= Pearson)
#> Variables: gss$coninc ("continuous") × gss$sex ("binary")
#> N: 3000
#> p-value: < 0.001
#> Test: t-test on r (cor.test)
#> H0: rho_pb = 0
#> Small p-values (e.g., p < 0.05) indicate evidence against H0.
#> 95% CI: [-0.1361, -0.0652]
#> Source: Fisher z (cor.test); = Pearson
#> 
#> One variable is continuous and the other is binary. Point-biserial correlation
#> is mathematically identical to Pearson when the binary variable is coded 0/1.

# Two ordinal variables use Kendall's tau when latent normality is not assumed.
smart_cor(gss$degree, gss$happy,
          assume_latent_normal = FALSE, verbose = FALSE)
#> 
#> ── Smart Correlation ───────────────────────────────────────────────────────────
#> Estimate: -0.0795
#> Method: Kendall's Tau-b
#> Variables: gss$degree ("ordinal") × gss$happy ("ordinal")
#> N: 3000
#> p-value: < 0.001
#> Test: asymptotic normal (cor.test, exact = FALSE)
#> H0: tau = 0
#> Small p-values (e.g., p < 0.05) indicate evidence against H0.
#> 95% CI: [-0.1030, -0.0559]
#> Source: Fieller, Hartley, and Pearson (1957)
#> 
#> Both variables are ordinal. Kendall's tau selected (no latent normality
#> assumption; stable bias across distributions).
#> 
#>  Alternatives: "polychoric", "spearman", and "gamma" (pass `method = "..."` to use)

# Force a method when the analysis calls for it.
smart_cor(gss$coninc, gss$age, method = "spearman", verbose = FALSE)
#> 
#> ── Smart Correlation ───────────────────────────────────────────────────────────
#> Estimate: 0.0369
#> Method: Spearman Rank Correlation
#> Variables: gss$coninc ("continuous") × gss$age ("count")
#> N: 3000
#> p-value: 0.0432
#> Test: t approximation (cor.test, exact = FALSE)
#> H0: rho_S = 0
#> Small p-values (e.g., p < 0.05) indicate evidence against H0.
#> 95% CI: [0.0011, 0.0726]
#> Source: Bonett and Wright (2000)
#> 
#> Method selected by user: spearman