我有一个大的稀疏矩阵,我需要将它关联起来,这对我来说是不可能的,因为:
bigstats
和bigmemory
,但我的R冻结了(使用Windows 10、8GB笔记本电脑)Matrix
包中没有相关函数 NB:我试图以'M'X + X'M - M'M'
的格式关联稀疏矩阵,这就是为什么我试图将稀疏矩阵分成两个或三个,并使用{{1 }}然后使用as.matrix()
进行关联,然后使用cor()
现在:
我想问一问是否有可能将稀疏矩阵分为两部分或三部分,转换为稠密矩阵,然后关联每个稠密矩阵,然后将两个或三个稠密矩阵绑定为一个,然后导出到文本文件。
考虑到稀疏矩阵的cbind()
和i
部分的大小相等且具有相同的p
,我可以使用什么函数将稀疏矩阵分为两个或三个?
dim
相关性输出将采用以下格式:
Formal class 'dgCMatrix' [package "Matrix"] with 7 slots
..@ i : int [1:73075722] ...
..@ p : int [1:73075722] 0 0 1 1 1 1 1 2 2 2 ...
..@ Dim : int [1:2] 500232 500232
..@ Dimnames:List of 2
.. ..$ : NULL
.. ..$ : NULL
..@ x : num [1:73075722] ...
..@ uplo : chr "L"
..@ factors : list()
答案 0 :(得分:1)
cor()
函数是一种有效计算所有列之间的pearson
相关性的方法。 cor
的效率很高,但是如果我们不介意效率下降,可以手动计算pearson
的相关性:
n_row <- nrow(res)
cor_mat <- Matrix(0L,n_row, ncol(res))
cMeans <- Matrix::colMeans(res)
for (i in seq_len(nrow(res)-1)){
x_delta = res[, i] - cMeans[i]
sum_x_delta_sq = sum(x_delta^2)
for (j in (i+1):nrow(res)){
y_delta = res[, j] - cMeans[j]
tmp <- sum(x_delta * y_delta) / sqrt((sum_x_delta_sq * sum(y_delta^2)))
if (abs(tmp) > 0.05) cor_mat[i, j] <- tmp
}
}
随着矩阵稀疏度的增加,我们可以通过将涉及非稀疏元素的操作和涉及稀疏元素的操作分离开来,使上述操作变得更加复杂,但性能更高:
n_row <- nrow(res)
cor_mat <- Matrix(0L,n_row, ncol(res))
cMeans <- Matrix::colMeans(res)
for (i in 1){
sp_i <- res[, i, drop = F]
i_s <- sp_i@i + 1
i_zero_delta = 0 - cMeans[i]
i_non_zero_delta = sp_i@x - cMeans[i]
sum_x_delta_sq = sum(c((n_row - length(i_s)) * i_zero_delta^2, i_non_zero_delta^2))
for (j in (i+1):nrow(res)){
sp_j <- res[, j, drop = F]
j_s <- sp_j@i + 1
j_zero_delta = 0L - cMeans[j]
j_non_zero_delta = sp_j@x - cMeans[j]
sum_y_delta_sq = sum(c((n_row - length(j_s)) * j_zero_delta^2, j_non_zero_delta^2))
common <- intersect(i_s, j_s)
only_i <- setdiff(i_s, j_s)
only_j <- setdiff(j_s, i_s)
none <- n_row - length(c(common, only_i, only_j))
numerator = 0
if (length(common) > 0) numerator = numerator + sum(i_non_zero_delta[match(common, i_s)] * j_non_zero_delta[match(common, j_s)])
if (length(only_i) > 0) numerator = numerator + j_zero_delta * sum(i_non_zero_delta[match(only_i, i_s)])
if (length(only_j) > 0) numerator = numerator + i_zero_delta * sum(j_non_zero_delta[match(only_j, j_s)])
if (length(none) > 0) numerator = numerator + i_zero_delta * j_zero_delta * none
tmp <- numerator / sqrt(sum_x_delta_sq * sum_y_delta_sq)
if (abs(tmp) > 0.05) cor_mat[i, j] <- tmp
}
}