利用spearman相关性分析是构建微生物共现网络常用的方法,需要计算每一对OTU的相关系数r和显著性p值,并对r和p值进行筛选来构建微生物网络。但由于OTU table往往有成千上万行,用R自带的corr.test()函数计算非常费时,严重制约我们的分析速度。笔者在计算4000多行的OTU table时,往往需要数小时。我在之前的一篇博客中利用并行的方法对spearman相关系数的计算进行了并行化加速,极大地提高了计算的速度,可参考R语言并行计算spearman相关系数_道阻且长1994的博客-CSDN博客_r语言计算spearman。但我的思路其实是被corr.test()函数的计算方法给带偏了。PCA(主成分分析)在计算协方差矩阵时根本没有像corr.test()那样对OTU进行两两成对(pair-wise)地去计算(相当于套了两成for循环),而是充分利用R语言向量化计算的特性,以矩阵为单位进行求解。受此启发,我对快速计算spearman相关系数及其显著性(fdr方法矫正)进行了重写,可以在一分钟内算出4000多个OTU间的相关系数及其fdr矫正过的p值。
#otu_niche为行为sample,列为OTU的OTU table
fast_spearman_fdr <- function(otu_niche){
r <- cor(otu_niche,method="spearman")
n = nrow(otu_niche)
t <- (r * sqrt(n - 2))/sqrt(1 - r^2)
p <- -2 * expm1(pt(abs(t), (n - 2), log.p = TRUE))
p[upper.tri(p, diag = FALSE)] <- p.adjust(p[upper.tri(p,diag = FALSE)], "fdr")
p[lower.tri(p, diag = FALSE)] = t(p)[lower.tri(p, diag = FALSE)]
return(list(r=r,p=p))
}
感触真的很深,这还只是一个简单的spearman相关系数和p值的计算,不知道原理的话,用corr.test()计算要等数小时,知道原理后则能更灵活地修改和应用。以后在使用R语言的一些函数时不能简单地把它当一个黑箱,而是要充分了解背后计算的原理和方法。
测试数据和代码可参考: