(六)R语言生物序列比对——Needleman-Wunsch全局比对算法

实现原理与代码

生物序列全局比对的主要目的是发现两个序列之间的相似度,从而估测二者的进化联系或相似功能。Needleman-Wunsch全局比对算法用到了动态规划(Dynamic Programming)的原理。它的主要工作流程见下图:
NW
在介绍具体算法前,我们先要定义一个得分矩阵。得分矩阵的目的是告诉程序某两个碱基配对的得分:

match <- 2
mismatch <- -1
gap <- -2

scoreMat <- matrix(misMatch, 5, 5)
dimnames(scoreMat) <- c(c("A", "T", "C", "G", ""), c("A", "T", "C", "G", ""))
diag(scoreMat) <- match
scoreMat[5,] <- gap
scoreMat[,5] <- gap
#scoreMat如下
#   A  T  C  G  
#A  2 -1 -1 -1 -2
#T -1  2 -1 -1 -2
#C -1 -1  2 -1 -2
#G -1 -1 -1  2 -2
#  -2 -2 -2 -2 -2

在决定好得分后,程序会把两个需要比对的序列分别作为一个新矩阵的列和行标题。接着,矩阵的[1, 1]元素初始值设置为0。接下来,矩阵的第一行和第一列的值设置为misMatch*行/列号(在上图所示的矩阵中错误配对惩罚为-2)。接下来程序会从[2,2]开始遍历元素。在使用DP算法填满整个表后,会进行回溯,获得具体的匹配序列。
假设 a i , j a_{i, j} ai,j为含需要对比序列的矩阵,其中元素的值的计算如下:
a [ i , j ] = m a x { a [ i − 1 , j − 1 ] + s c o r e M a t [ s e q 1 [ i − 1 ] , s e q 2 [ j − 1 ] ] a [ i , j − 1 ] + s c o r e M a t [ 5 , 5 ] a [ i − 1 , j ] + s c o r e M a t [ 5 , 5 ] a[i, j] = max\begin{cases} a[i-1, j-1]+scoreMat[seq1[i-1],seq2[j-1]]\\ a[i, j-1]+scoreMat[5, 5]\\ a[i-1, j]+scoreMat[5, 5] \end{cases} a[i,j]=maxa[i1,j1]+scoreMat[seq1[i1],seq2[j1]]a[i,j1]+scoreMat[5,5]a[i1,j]+scoreMat[5,5]
其中第一行 s c o r e M a t [ s e q 1 [ i − 1 ] , s e q 2 [ j − 1 ] ] scoreMat[seq1[i-1],seq2[j-1]] scoreMat[seq1[i1],seq2[j1]]的值为该元素对应碱基的得分,第二行与第三行中的 s c o r e M a t [ 5 , 5 ] scoreMat[5, 5] scoreMat[5,5]代表gap
该部分代码实现如下所示:

alignmat <- matrix(0, length(seq1)+1, length(seq2)+1)
alignmat[,1] <- seq(0, gap*length(seq1), gap)
alignmat[1,] <- seq(0, gap*length(seq2), gap)
dimnames(alignmat) <- list(c("",seq1), c("",seq2)) #在每个序列前加入一个空字符
  
for(i in 2:nrow(alignmat)){
    
     #因为[1,1]被填了,从[2,2]开始
  for(j in 2:ncol(alignmat)){
    
    
    alignmat[i,j] <- max(alignmat[i-1,j-1]+scoreMat[seq1[i-1],seq2[j-1]],
    					alignmat[i-1,j]+scoreMat[5,5],
    					alignmat[i,j-1]+scoreMat[5,5])
  }
}

我们用序列GAATTCGATTA,我们就获得了一个如下所示的alignmat
alignmat
在获得表后,我们要从最右下角的元素进行回溯,即顺着它的源头一直到最左上角的元素。如在上图中,最右下角的元素5是通过其左上角的6+mismatch=6-1=5计算而来的;表的[3,4]这一元素可能来自于其左方的4+gap=4-2=2,或者是来自于其左上角的0+match=0+2=2,所以会有两条可以考虑的回溯路径。可以选择全部保留,但一般来说是按照在DP中的优先度保留一个,在我们的代码中即左上>上>左。在进行回溯的过程中会记录回溯路径,并根据路径将两条序列显示出来,gap用-表示。在R语言中的回溯比较复杂,需要提前创建一个新矩阵储存对应位置元素由哪个元素计算而来。

全部代码

由于该算法经过多次优化,笔者将不自行设计。请从该链接下载使用的代码,提取码:ngw8,文件原名为pairAlign.R,因为敏感词被屏蔽了,使用时请改回原名。以下的代码介绍的主要是使用方法:

install.packages("BiocManager") #调用包
BiocManager::install() #[a/s/n]输入a下载全部附属包
BiocManager::install("Biostrings") #install biostrings
suppressMessages(library(Biostrings)) #我们要用的得分矩阵要调用这个包

source("pairAlign.R") #无法载入的话使用完整文件路径
pairAlign("GATTACCTAGA", "GAATTCTTG", 
		nucleotideSubstitutionMatrix(2,-1), 
		gapOpening = -2, gapExtension = -2, type = "global")
		#前两个参数为需要比对的序列,蛋白质和DNA序列都可以
		#第三个参数为用到的得分矩阵。DNA可以用nucleotideSubstitutionMatrix,蛋白质可以用"BLOSUM50"
			#nucleotideSubstitutionMatrix(2,-1)定义了match得分为2,mismatch得分为-1
		#第四和第五个参数为gap的惩罚。默认的是开gap和延长gap的惩罚相同,但实际上开gap的惩罚应大于延伸gap的惩罚,因为现实中序列出现断裂的可能远小于两个断裂序列间距边远的可能
		#最后的type是序列比对的方法。这里用的是Needleman-Wunsch全局比对,"local"就是下次要讲的Smith Waterman局部比对

运行结果如下:
result
由于生成的结果是list类型,可以用访问列表的方式获得单独结果,具体请参考我的博客

结束语

在生物信息学中,获得两个的全局序列比对结果能够帮助我们推测两序列的相似度/同源性。下篇博客将会介绍Smith Waterman全局比对算法,敬请期待!

猜你喜欢

转载自blog.csdn.net/EricFrenzy/article/details/119676572
今日推荐