【问题标题】:How to make my loop run faster in R?如何让我的循环在 R 中运行得更快?
【发布时间】:2014-11-24 15:32:17
【问题描述】:

我正在使用一个函数从多个 HWE 卡方检验中获取 p 值。我正在循环一个名为geno.data 的大矩阵,它是(313 行 x 355232 列)来执行此操作。我基本上是逐行循环矩阵的两列。它运行得很慢。我怎样才能让它更快?谢谢

library(genetics)
geno.data<-matrix(c("a","c"), nrow=313,ncol=355232)
Num_of_SNPs<-ncol(geno.data) /2
alleles<- vector(length = nrow(geno.data))
HWE_pvalues<-vector(length = Num_of_SNPs)
j<- 1

for (count in 1:Num_of_SNPs){
    for (i in 1:nrow(geno.data)){
        alleles[i]<- levels(genotype(paste(geno.data[i,c(2*j -1, 2*j)], collapse = "/")))
    }
    g2 <- genotype(alleles)
    HWE_pvalues[count]<-HWE.chisq(g2)[3]
    j = j + 2
}

【问题讨论】:

  • 所以你在做choose(355232, 2) chisq 测试?你碰巧知道fortran吗?
  • @rawr 我不知道 fortran。我正在使用 R 包中的函数进行卡方检验。这是针对我的问题的。

标签: r performance loops


【解决方案1】:

首先,请注意发布的代码将导致索引越界错误,因为在主循环的 Num_of_SNPs 迭代之后,您的 j 值将是 ncol(geno.data)-1 并且您正在访问列 @ 987654324@ 和2*j。我假设您希望可以删除列 2*count-12*countj

向量化对于编写快速的 R 代码非常重要。在您的代码中,您调用 paste 函数 313 次,每次传递长度为 1 的向量。在 R 中调用 paste 一次传递长度为 313 的向量要快得多。这里是 main 的原始和向量化内部for 循环:

# Original
get.pval1 <- function(count) {
  for (i in 1:nrow(geno.data)){
    alleles[i]<- levels(genotype(paste(geno.data[i,c(2*count -1, 2*count)], collapse = "/")))
  }
  g2 <- genotype(alleles)
  HWE.chisq(g2)[3]
}

# Vectorized
get.pval2 <- function(count) {
  g2 <- genotype(paste0(geno.data[,2*count-1], "/", geno.data[,2*count]))
  HWE.chisq(g2)[3]
}

我们从矢量化中获得了大约 20 倍的加速:

library(microbenchmark)
all.equal(get.pval1(1), get.pval2(1))
# [1] TRUE
microbenchmark(get.pval1(1), get.pval2(1))
# Unit: milliseconds
#          expr       min        lq      mean    median        uq       max neval
#  get.pval1(1) 299.24079 304.37386 323.28321 307.78947 313.97311 482.32384   100
#  get.pval2(1)  14.23288  14.64717  15.80856  15.11013  16.38012  36.04724   100

使用矢量化代码,您的代码应该在大约 177616*.01580856 = 2807.853 秒或大约 45 分钟内完成(原始代码需要 16 小时)。如果这对您来说仍然不够快,那么我鼓励您查看 R 中的 parallel 包。mcmapply 应该为您提供很好的加速,因为外部 for 循环的每次迭代都是独立的.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-17
    • 1970-01-01
    相关资源
    最近更新 更多