Compute correlations from matrix-like input and return a sparse matrix. Pearson cross-products remain sparse and correlations are evaluated in column blocks so block-local working memory is bounded independently of the full output dimensions.
Usage
sparse_cor(
x,
y = NULL,
method = c("pearson", "spearman", "kendall"),
allow_neg = TRUE,
remove_na = TRUE,
remove_inf = TRUE,
threshold = 0,
block_size = 256L,
max_dense_bytes = Inf,
max_output_entries = Inf,
...
)Arguments
- x
A numeric matrix or sparse
Matrixwith observations in rows.- y
An optional numeric matrix or sparse
Matrixwith the same number of rows asx.- method
Correlation coefficient:
"pearson","spearman", or"kendall".- allow_neg
Logical. Whether to allow negative values or set them to 0.
- remove_na
Logical. Whether to replace NA values with 0.
- remove_inf
Logical. Whether to replace infinite values with 0.
- threshold
Non-negative absolute correlation threshold. Values with absolute magnitude below this threshold are omitted from the sparse output.
- block_size
Maximum number of target columns in each Pearson working block. The effective size may be reduced to honor
max_dense_bytes.- max_dense_bytes
Maximum estimated bytes allowed for block-local Pearson working arrays or dense rank-correlation arrays. The default is
Inffor backward compatibility. Supply a finite value to enable this guard.- max_output_entries
Maximum number of stored values allowed in the sparse result. The default,
Inf, preserves the historical unbounded output behavior; set a finite value to fail before returning an output that exceeds the workflow's storage budget.- ...
Other arguments passed to
stats::cor()for Spearman and Kendall correlations.
Details
Pearson input and cross-products remain sparse. Centering, scaling, and
thresholding are fused in a column-block scan rather than materializing a
dense correlation block. The final sparse result can nevertheless contain
up to ncol(x) * ncol(y) stored values when threshold = 0; use threshold
and max_output_entries to make this boundary explicit.
Spearman and Kendall correlation require ranking and currently densify the
input and full correlation result. Their estimated peak working size is
checked against max_dense_bytes before conversion.
Examples
m1 <- simulate_sparse_matrix(
500, 100
)
m2 <- simulate_sparse_matrix(
500, 100,
seed = 2025
)
a <- sparse_cor(m1)
b <- sparse_cor(m1, m2)
c <- as_matrix(
cor(as_matrix(m1)),
return_sparse = TRUE
)
d <- as_matrix(
cor(as_matrix(m1), as_matrix(m2)),
return_sparse = TRUE
)
a[1:5, 1:5]
#> 5 x 5 sparse Matrix of class "dsCMatrix"
#> col_1 col_2 col_3 col_4 col_5
#> col_1 1.00000000 0.03982146 0.03290085 -0.02022058 0.00827069
#> col_2 0.03982146 1.00000000 -0.04172518 -0.00276169 -0.03594182
#> col_3 0.03290085 -0.04172518 1.00000000 0.03481704 -0.03144989
#> col_4 -0.02022058 -0.00276169 0.03481704 1.00000000 -0.05034769
#> col_5 0.00827069 -0.03594182 -0.03144989 -0.05034769 1.00000000
c[1:5, 1:5]
#> 5 x 5 sparse Matrix of class "dsCMatrix"
#> col_1 col_2 col_3 col_4 col_5
#> col_1 1.00000000 0.03982146 0.03290085 -0.02022058 0.00827069
#> col_2 0.03982146 1.00000000 -0.04172518 -0.00276169 -0.03594182
#> col_3 0.03290085 -0.04172518 1.00000000 0.03481704 -0.03144989
#> col_4 -0.02022058 -0.00276169 0.03481704 1.00000000 -0.05034769
#> col_5 0.00827069 -0.03594182 -0.03144989 -0.05034769 1.00000000
all.equal(a, c)
#> [1] "Attributes: < Component “i”: Numeric: lengths (5046, 5050) differ >"
#> [2] "Attributes: < Component “p”: Mean relative difference: 0.0008776063 >"
#> [3] "Attributes: < Component “x”: Numeric: lengths (5046, 5050) differ >"
b[1:5, 1:5]
#> 5 x 5 sparse Matrix of class "dgCMatrix"
#> col_1 col_2 col_3 col_4 col_5
#> col_1 0.003888632 -0.036322389 0.03054830 0.04990672 0.053832055
#> col_2 -0.042598718 -0.044702907 0.05688602 -0.02310432 0.007310609
#> col_3 -0.003132754 -0.041963945 -0.04085159 -0.03183016 -0.028050257
#> col_4 0.045648545 0.009914274 0.01685729 0.03317848 -0.045443563
#> col_5 -0.048082595 -0.050457664 0.04350114 -0.05551273 -0.051113224
d[1:5, 1:5]
#> 5 x 5 sparse Matrix of class "dgCMatrix"
#> col_1 col_2 col_3 col_4 col_5
#> col_1 0.003888632 -0.036322389 0.03054830 0.04990672 0.053832055
#> col_2 -0.042598718 -0.044702907 0.05688602 -0.02310432 0.007310609
#> col_3 -0.003132754 -0.041963945 -0.04085159 -0.03183016 -0.028050257
#> col_4 0.045648545 0.009914274 0.01685729 0.03317848 -0.045443563
#> col_5 -0.048082595 -0.050457664 0.04350114 -0.05551273 -0.051113224
all.equal(b, d)
#> [1] "Attributes: < Component “i”: Numeric: lengths (9997, 10000) differ >"
#> [2] "Attributes: < Component “p”: Mean relative difference: 0.000311165 >"
#> [3] "Attributes: < Component “x”: Numeric: lengths (9997, 10000) differ >"
m1[sample(1:500, 10)] <- NA
m2[sample(1:500, 10)] <- NA
sparse_cor(m1, m2)[1:5, 1:5]
#> 5 x 5 sparse Matrix of class "dgCMatrix"
#> col_1 col_2 col_3 col_4 col_5
#> col_1 . . . . .
#> col_2 . -0.044702907 0.05688602 -0.02310432 0.007310609
#> col_3 . -0.041963945 -0.04085159 -0.03183016 -0.028050257
#> col_4 . 0.009914274 0.01685729 0.03317848 -0.045443563
#> col_5 . -0.050457664 0.04350114 -0.05551273 -0.051113224
system.time(
sparse_cor(m1)
)
#> user system elapsed
#> 0.003 0.000 0.002
system.time(
cor(as_matrix(m1))
)
#> user system elapsed
#> 0.007 0.000 0.006
system.time(
sparse_cor(m1, m2)
)
#> user system elapsed
#> 0.002 0.000 0.002
system.time(
cor(as_matrix(m1), as_matrix(m2))
)
#> user system elapsed
#> 0.013 0.000 0.013