双序列比对的多路径回溯
这是双序列比对的多路径回溯的R语言实现,用类似linux系统中给用户赋权限的方法记录来源方向,感觉比列表储存来源方向好。
#处理字符串的包
library(stringr)
#用到的变量
#d:direction.
#记录来源的方向:1代表从上面来,2代表从左上来,4代表从左边来
d <- c(1, 2, 4)
seq1 <- c("AATGCTC")
seq2 <- c("ACGTGCT")
#匹配加5分
Match <- c(5)
#错配减10分
MisM <- c(-10)
#空位减3分
Gap <- c(-3)
myfun <- function(seq1, seq2, Gap, Match, MisM, d){
#将字符串转为向量
seq1 <- strsplit(seq1, "")[[1]]
seq2 <- strsplit(seq2, "")[[1]]
#初始化得分矩阵和方向矩阵
AlignM <- matrix(0, nrow = length(seq1)+1, ncol = length(seq2)+1,
dimnames = list(c("0", seq1), c("0", seq2)))
path <- matrix(0, nrow = length(seq1)+1, ncol = length(seq2)+1,
dimnames = list(c("0", seq1), c("0", seq2)))
for(i in 2:nrow(AlignM)){
AlignM[i, 1] <- AlignM[i-1, 1] + Gap
path[i, 1] <- d[1]
}
for(i in 2:ncol(AlignM)){
AlignM[1, i] <- AlignM[1, i-1] + Gap
path[1, i] <- d[3]
}
#算得分矩阵和方向矩阵
for(i in 2:nrow(AlignM)){
for(j in 2:ncol(AlignM)){
if(rownames(AlignM)[i] == colnames(AlignM)[j]){
s <- Match
}
else{
s <- MisM
}
v <- c(AlignM[i-1, j] + Gap, AlignM[i-1, j-1] + s,
AlignM[i, j-1] + Gap)
score <- max(v)
AlignM[i, j] <- score
index <- which(v == score)
#将代表不同方向来源的值相加
for(z in index){
path[i, j] <- path[i, j] + d[z]
}
}
}
return(list(AlignM, path))
}
#回溯
mypath <- function(path){
seq1 <- rownames(path)
seq2 <- colnames(path)
#p:匹配模式
p <- list(0)
#从最右下角的值开始回溯
p <- back(seq1, seq2, path, length(seq1), length(seq2), p)
p[[1]] <- NULL
return(p)
}
#x和y记录当前位置
back <- function(seq1, seq2, path, x, y, p){
#回溯得一种匹配模式,将其加入p
if(x == 1 & y == 1){
#将最开头的“0”改为“-”
seq1 <- str_c(c("-", seq1[2:length(seq1)]), collapse = "")
seq2 <- str_c(c("-", seq2[2:length(seq2)]), collapse = "")
p[[length(lengths(p))+1]] <- rbind(seq1, seq2)
}
else{
#来源有上方
if(path[x, y] == 1 || path[x, y] == 3 || path[x, y] == 5){
seq_m1 <- seq1
seq_m2 <- seq2
#在seq2的y+1位置插入“-”
for(i in length(seq_m2):min((y+1), length(seq_m2))){
seq_m2[i+1] <- seq_m2[i]
}
seq_m2[y+1] <- "-"
p <- back(seq_m1, seq_m2, path, x - 1, y, p)
}
#来源有左上方
if(path[x, y] == 2 || path[x, y] == 3 || path[x, y] == 6){
seq_m1 <- seq1
seq_m2 <- seq2
p <- back(seq_m1, seq_m2, path, x - 1, y - 1, p)
}
#来源有左方
if(path[x, y] == 4 || path[x, y] == 5 || path[x, y] == 6){
seq_m1 <- seq1
seq_m2 <- seq2
#在seq1的x+1位置插入“-”
for(i in length(seq_m1):min((x+1), length(seq_m1))){
seq_m1[i+1] <- seq_m1[i]
}
seq_m1[x+1] <- "-"
p <- back(seq_m1, seq_m2, path, x, y - 1, p)
}
}
#因为用了递归的方式,所以p更新后要传给上一层
return(p)
}
result <- myfun(seq1, seq2, Gap, Match, MisM, d)
p <- mypath(result[[2]])
print(p)