我有一个名为 assay_name 的大型(稀疏)矩阵,具有 m 列和 n 行。我有第二个大(稀疏)矩阵 term 与 n 列和 p 行。我想计算一个矩阵 assay_term 与 m 列和 p 行.
对于assay_name中的每一列m(例如m1)我看是否有一个非零元素n(例如n1),然后将该值
assay_name[n1,m1]
与term term[,n1]
的相应列 (n1)。这给了我一个 term 的加权行。之后我计算所有加权行的行和形成term,这将成为assay_term的相应行。
这些是两个稀疏矩阵的维数:
assay_name
22620 x 21574 sparse Matrix of class "dgCMatrix", with 74651618 entries
term
22712 x 22620 sparse Matrix of class "dgCMatrix", with 1898915 entries
一列 m1 的基本方法已经很长时间了:
system.time(a<-sapply(row.name(assay_name)[which(assay_name[,1] != 0)], function(y) {
as.numeric(assay_name[y,1])*term[,y]
}))
380.9
所以只是表演
assay_term<-sapply(colnames(assay_name),function(x){
rowSums(do.call(cbind,(row.name(assay_name)[which(assay_name[,x] != 0)], function(y) {
as.numeric(assay_name[y,x])*term[,y]
}))))
}
至少需要21574*380.9s = 95.1d,这是不可行的
在 ChatGPT 的帮助下,我得出了以下解决方案:
# Set up parallel backend
library(doParallel)
ncores <- detectCores()
registerDoParallel(ncores)
# Define function to be applied in parallel
assay_term <- foreach(x = colnames(assay_name), .combine = cbind) %dopar% {
rowSums(do.call(cbind,sapply(row.name(assay_name)[which(assay_name[,x] != 0)], function(y) {
as.numeric(assay_name[y,x])*term[,y]
}))))
}
# Clean up parallel backend
stopCluster(cl)
这将开始计算,但它会在大约 10 分钟后因超过 RAM 限制(120 GB)而崩溃。你知道如何更有效地执行计算或存储中间产品吗?
随着输入问题 ChatGPT 建议:
assay_term <- t(apply(assay_name, 2, function(col){
weighted_term <- term[,col[which(col != 0)]]
rowSums(weighted_term * col[which(col != 0)])
}))
这很快,但我不确定它是否正确。