2014-12-04 55 views
-1

我正在循环一个名为geno.data的大字符矩阵。我基本上是一次循环矩阵的两列。它运行非常缓慢。在循环结束时,我计划将EIGENSTRAT_genofile导出为.txt文件。我在程序的其余部分使用Xa。我怎样才能让它更快?由于我如何加快我的R代码?

geno.data <- matrix(nrow = 313, ncol = 300000, c("a","c","g")) # large matrix 
Num_of_SNPs<-ncol(geno.data) /2 

compute_MAF<- function(j){ 
    loci<- NULL 
    loci<- table(as.vector(geno.data[,c(2*j-1,2*j)])) 
    total_alleles<- sum(loci) 
    loci<- loci/total_alleles 

    # major and minor allele frequencies for one locus 
    major_allele<- names(which.max(loci)) 
    minor_allele<- names(which.min(loci)) 

    return(cbind(major_allele, minor_allele)) 
} 

Xa <- matrix(NA, nrow = nrow(geno.data), ncol = Num_of_SNPs) 
EIGENSTRAT_genofile<-c() 

for (j in 1:Num_of_SNPs){ 
    allele<-compute_MAF(j) 
    X <- 1 * (geno.data[,c(2*j-1, 2*j)] == allele[2]) # minor allele 
    reference_allele_count <- rowSums(geno.data[,c(2*j-1,2*j)]==allele[1], na.rm=TRUE) 
    EIGENSTRAT_genofile<- rbind(EIGENSTRAT_genofile,reference_allele_count) 
    Xa[,j] <- X[,1] + X[,2] - 1 
} 
+0

查看doParallel包。如果你的机器上有多个内核,你可以显着提高速度。 – Jason 2014-12-04 06:24:40

回答

1

虽然有可能在你的代码做了改进,最大的瓶颈是表示:

EIGENSTRAT_genofile<- rbind(EIGENSTRAT_genofile,reference_allele_count) 

你应该总是避免在循环中不断增长的对象。相反,尝试在循环之前进行初始化列表:

EIGENSTRAT_genofile<-vector("list",Num_of_SNPs) 

在循环中,你可以指定reference_allele_countEIGENSTRAT_genofile元素:在循环后

EIGENSTRAT_genofile[[j]]<-reference_allele_count 

然后,到了最后,你rbind列表中的所有元素一起通过do.call

EIGENSTRAT_genofile<-do.call(rbind, EIGENSTRAT_genofile) 
+0

做到了。原始文件在远程服务器上运行超过5个小时。我做了你的更正,在我的笔记本上花了一分半钟。您是否看到其他瓶颈或改进措施可以让它运行得更快? – cooldood3490 2014-12-04 10:50:34

+0

在'compute_MAF'中,没有理由对表格进行规范化,因为您只是在寻找最小和最大值。然后在返回值中使用'c'而不是'cbind'。而不是一个列表(如我在我的回答中所建议的),你可以初始化一个矩阵(我没有检查你的代码,也不知道这是否可能)并填充循环中的每一行。这些不会像答案中的诀窍那样大幅改进,但仍值得一试。 – nicola 2014-12-04 11:28:52