离线blast构建及运行——基于R

因工作需要,需要构建一个本地的blast库,同时需要自动的提取ab1测序文件的序列进行blast。这里就记录一下具体的代码。

下载和hcv相关的所有病毒序列

ncbi::taxonomy数据库记录了所有物种的相关信息。我们使用rentrez::entrez_search检索相关信息。通过entrez_link来或者相关物种的所有序列ID。通过entrez_fetch来获得fasta序列

library(rentrez)
hcv <- entrez_search(db = "taxonomy", term = "hcv")
hcvnul <- entrez_link(dbfrom = "taxonomy", id = hcv$ids, db = "nucleotide")
###序列ID在hcvnul的ID下
id <- hcvnul$links$taxonomy_nuccore
head(id)
###由于API下载的时候如果记录太多会中断,所以构建循环
n <- 200 #每次读入的记录数量
hcvgenome <- c()
for (i in seq(1, length(id), n)) {
  res <- entrez_fetch(db = "nucleotide", id = id[i : (i + n - 1)], rettype = "fasta")
  hcvgenome <- paste(hcvgenome, res, collapse = "")
}
write.table(hcvgenome, "hcv.fa", quote = F, row.names = F, col.names = F)

构建离线blast下载库

使用ncbi的blast软件来进行离线的blast操作。进行操作之前需要先构建离线的blast库。使用makeblastdb构建离线blast库。具体步骤是通过

  1. 如果是windows电脑可以在官网下载软件。如果是linux/mac电脑也可以使用conda进行下载
conda install blast
  1. 如果是windows的话,安装完之后,首先需要配置一下电脑环境。具体的可以参照官方教程或者其他的帖子。
  2. 构建blast数据库。使用 makeblastdb构建离线的数据库。
makeblastdb -in hcv.fa -dbtype nucl -out hcv

这样就构建了一个离线的blast库。其实就是形成了一个三个以hcv开头的文件。分别是hcv.nin; hcv.nhr以及hcv.nsq。这样如果要在别的电脑上用。直接拷贝过去就行

读取abi文件

在R语言当中我们可以通过sangeseqR包来读取abi文件序列。通过system2调用系统命令,也就是blastn命令。具体代码如下。

PS:如果是windows系统的话,需要在system2运行的时候制定blastn的具体位置。如果是linux则不用。

## 基本设置及加载相应的包
options(stringsAsFactors = F)
library(tidyverse)
library(sangerseqR)
## 获得相关文件夹下的abi文件名
file <- Sys.glob("*.ab1")
## blastn基础设置
blastn = "E:/localblast/bin/blastn.exe"
blast_db = "E:/localblast/HCVdb/hcv"
input = "E:/localblast/query.fa"
format = 6
colnames <- c("qseqid", "sseqid", "pident",
              "length", "mismatch", "gapopen",
              "qstart", "qend", "sstart", "send",
              "evalue", "bitscore")
## 批量blast
### 同时取文件名中间几位当作文件的ID
### 取结果的前30输出
res <- map(file, function(seq){
    seq1 <- read.abif(seq)
    homosangerseq <- sangerseq(seq1)
    fasta1 <- primarySeq(homosangerseq, string = TRUE)
    id <- stringr::str_sub(seq, -10,-5)
    len <- stringr::str_count(fasta1, "[A-Z]")
    queryfa <- paste0(">",seq,"\n", fasta1)
    write.table(fasta1, "query.fa", quote = F, row.names = F, col.names = F)
    blast_out <- system2(command = blastn, 
                         args = c("-db", blast_db, 
                                  "-task megablast",
                                  "-query", input, 
                                  "-outfmt", format),
                         wait = TRUE,
                         stdout = TRUE) %>%
        as_tibble() %>% 
        separate(col = value, 
                 into = colnames,
                 sep = "\t",
                 convert = TRUE)
    blast_out %>% mutate(id = id) %>% filter(sseqid %in% str_subset(blast_out$sseqid, "subtype")) %>% 
        select(id, 2, 3:12) %>% arrange(id, desc(pident)) %>%
        group_by(id) %>% dplyr::slice(1:30)
    
})
res <- do.call(bind_rows, res)
write.csv(res, "E:/localblast/result.csv", row.names = F)

最后保存成R脚本。mac在命令行输入

Rscript script.R就可以运行

如果是windows如果想要运行脚本需要先创建一个.bat文件。具体的可以参照:一键运行R脚本。

后记

  1. 通过运行输出的结果只有能够blast到的结果。如果没有blast到的没有输出。这个后来也写了一个比较麻烦的结果小脚本来处理这个问题(肯定有简单的方法。只是我没想到)。
result <- map2(res, file, function(dat, seq){
    if(nrow(dat) == 0) {
        result <- stringr::str_sub(seq, -10, -5)
    }else {
        result <- dat
    }
    return(result)
})
ress <- data.frame()
error <- c()
for(i in 1:length(file)){
    if(is.vector(result[[i]])){
        error <- c(error, result[[i]])
    }else {
        ress <- rbind(ress, result[[i]])
    }
}
write.table(error, "error.txt", col.names = F, row.names = F, quote = F)
write.csv(ress, "result.csv", col.names = F)

通过这样。可以得到一个error变量和一个结果变量。再把两个结果输出出来即可

  1. 关于R语言blast。有现成的一个R包:rBLAST。但是具体的机制也是调用system进行操作的。
  2. 今天使用的时候。碰到一个文件损坏的情况。这个没有在代码中考虑到。具体修改目前想到的是可以使用purrr::safety。但是没有尝试来做。

主要参考

[Doing local BLAST searches on sanger sequence data in R

你可能感兴趣的:(离线blast构建及运行——基于R)