所以我有这个代码片段可以做它应该做的事情,但由于使用了for循环,它非常慢并且可能效率低下... 因为我在大文件上使用它会大大减慢我的脚本速度。
我猜R有一个内置函数,可以轻松完成我在for循环中所做的事情吗?
有没有人知道如何让它更快?
以下代码的作用:
检查矩阵中的某个位置是否存在字母字符(1)或是否是另一个字符(0)。然后将此信息保存在列表中。
基本上我需要继续的是字母字符矩阵的true / false。 然后我使用true / false列表来"重新编号矩阵元素" (以便不计算非字母字符)
供参考: 这是用于蛋白质序列比对,我希望所有氨基酸(字母字符)都被编号,但不是间隙(其他字符如" - "或"。") 。后来这使我能够特别指出氨基酸的位置并更容易分析我的巨大比对
如果需要澄清,请发表评论!
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]<-" "
}
}
}
答案 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;,但如果您使用apply
和cumsum
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
可能更有效,并将输出保持为矩阵而不是列表。