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, orNULL."auto"runs a likelihood-ratio chi-square test (viatest_bivariate_normality()) and decides whether the data satisfies bivariate normality; a saturated 2 x 2 table defaults to the observed-scale method (phi).TRUEforces polychoric / polyserial / tetrachoric;FALSEforces Kendall's tau / Spearman / phi.NULLasks interactively (defaults toTRUEin non-interactive sessions).- ordinal_threshold
Integer passed to
detect_type(). Default:10.- ignore_na
Logical. If
TRUE(default), rows with missing values in eitherxoryare silently removed (pairwise complete observations). IfFALSE, the function errors whenNAvalues 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;TRUEalways replaces the analytic CI with a percentile-bootstrap CI;FALSEnever 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.seedis 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 types | Default method | Alternative |
| Correlation methods (signed, from -1 to +1) | ||
| continuous + continuous | Pearson | Spearman (suggested, especially if nonlinear) |
| continuous + binary | Pearson = point-biserial | – |
| binary + binary | Pearson = phi | Tetrachoric (preferred, if latent normality holds) |
| continuous + ordinal | Spearman/Kendall | Polyserial (preferred, if latent normality holds) |
| ordinal + ordinal | Kendall's tau | Polychoric (preferred, if latent normality holds) |
| binary + ordinal | Rank-biserial | Spearman |
| Association measures (unsigned, from 0 to 1) | ||
| continuous + categorical | Cramer's V (binned) | – |
| binary + categorical | Cramer's V | – |
| ordinal + categorical | Cramer's V | – |
| categorical + categorical | Cramer's V | Theil'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