双序列比对的多路径回溯

双序列比对的多路径回溯

这是双序列比对的多路径回溯的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)

你可能感兴趣的:(双序列比对的多路径回溯)