R - 使其更快:检查字符的矩阵位置并将信息放入列表(0/1)

时间:2016-08-26 10:44:48

标签: r list for-loop matrix

所以我有这个代码片段可以做它应该做的事情,但由于使用了for循环,它非常慢并且可能效率低下... 因为我在大文件上使用它会大大减慢我的脚本速度。

我猜R有一个内置函数,可以轻松完成我在for循环中所做的事情吗?

有没有人知道如何让它更快?

以下代码的作用:

检查矩阵中的某个位置是否存在字母字符(1)或是否是另一个字符(0)。然后将此信息保存在列表中。

基本上我需要继续的是字母字符矩阵的true / false。 然后我使用true / false列表来"重新编号矩阵元素" (以便不计算非字母字符)

更新:

我的意思是什么 "重新编号矩阵元素": 蛋白质序列总是编号,因此长度为560的蛋白质在其序列中具有560个氨基酸。我对序列进行比对,它们的长度不相同(A:560个氨基酸,B:600个氨基酸),比对会引入序列不匹配的缺口。我的矩阵是一个对齐,因此有间隙(非字母字符,通常" - ")为了能够在对齐中解决序列A的位置100,我需要重新编号对齐,以便只有& #34;非缺口位置"有一个数字,然后解决该位置。否则,如果我打印对齐的位置100,它将不是我的序列A的位置100。

供参考: 这是用于蛋白质序列比对,我希望所有氨基酸(字母字符)都被编号,但不是间隙(其他字符如" - "或"。") 。后来这使我能够特别指出氨基酸的位置并更容易分析我的巨大比对

如果需要澄清,请发表评论!

 MSAmatrix<-matrix(c("A","-","B", "-", "C","A","D","B", "-", "C","A","-","B", "F", "C","A","D",".", "-", "C"), nrow=4, byrow=TRUE)

 letters<-list()
 lettersrenumbered<-list()
 referencesequence<-1
 # for whatever reason I am initialising the lists wrong and they need to be filled with 1 element before I can use them in the next loops...
 for(i in 1:dim(MSAmatrix)[1]) {
 letters[[i]]<-1313
 lettersrenumbered[[i]]<-1313
 }
 # get info if position is an alphabet character or not
 for(i in 1:dim(MSAmatrix)[1]) {
     for(j in 1:dim(MSAmatrix)[2]) {
         if(grepl("[a-zA-Z]",MSAmatrix[i,])[j]){
            letters[[i]][j]<-1  
         }
         else{  
            letters[[i]][j]<-0
        }
     }
 }

 #renumber all the sequences so that only the alphabet characters get a number
 for(i in 1:dim(MSAmatrix)[1]) {
     count<-0
     for(j in 1:dim(MSAmatrix)[2]) {
         if(letters[[i]][j]==1){
            count<-count+1
            lettersrenumbered[[i]][j]<-count    
         }
         else{
            lettersrenumbered[[i]][j]<-" "  
         }
     }
 }

2 个答案:

答案 0 :(得分:1)

在我的机器上,以下速度比您的方法快20倍:

创建一个相同尺寸的矩阵,但都是假的

X <- matrix(rep(FALSE, 20), nrow = 4, byrow = TRUE)

如果MSAmatrix是大写字母,请将其标记为TRUE

X[MSAmatrix %in% LETTERS] <- TRUE

你可以通过直接创建矩阵来提高速度(30%),尽管可能有点难以确保它是正确的。也就是说,只需:

matrix(MSAmatrix %in% LETTERS, nrow = 4, byrow = FALSE)

目前尚不清楚您的意思是&#34;重新编号矩阵元素&#34;,但如果您使用applycumsum

apply(X, 2, cumsum)
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    0    1    0    1
[2,]    2    1    2    0    2
[3,]    3    1    3    1    3
[4,]    4    2    3    1    4

我认为你接近你的意图。

答案 1 :(得分:0)

一般来说,当你对整个向量而不是单个元素执行操作时,R是最快的,所以你可以将grep分开并写出来:

MSAmatrix<-matrix(c("A","-","B", "-", "C","A","D","B", "-", "C","A","-","B", "F", "C","A","D",".", "-", "C"), nrow=4, byrow=TRUE)
isChar <- matrix(grepl("[a-zA-Z]",MSAmatrix), nrow=nrow(MSAmatrix))

获取显示哪些元素是字符的矩阵。下一步是按行进行创建列表,因此lapply是一个有用的起点。这可以通过以下方式完成:

formatRow <- function(i){
  retval <- cumsum(isChar[i,])
  retval[!isChar] <- ""
  retval
}

lapply(1:nrow(MSAmatrix), formatRow)

对于每一行,函数使用cumsum来计算行中到目前为止的trues数,然后用“”覆盖不对应于字母的那些,将整个向量转换为字符。

根据您对输出的其他操作,使用apply而不是lapply可能更有效,并将输出保持为矩阵而不是列表。