因工作需要,需要构建一个本地的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库。具体步骤是通过
- 如果是windows电脑可以在官网下载软件。如果是linux/mac电脑也可以使用conda进行下载
conda install blast
- 如果是windows的话,安装完之后,首先需要配置一下电脑环境。具体的可以参照官方教程或者其他的帖子。
- 构建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脚本。
后记
- 通过运行输出的结果只有能够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变量和一个结果变量。再把两个结果输出出来即可
- 关于R语言blast。有现成的一个R包:rBLAST。但是具体的机制也是调用system进行操作的。
- 今天使用的时候。碰到一个文件损坏的情况。这个没有在代码中考虑到。具体修改目前想到的是可以使用
purrr::safety
。但是没有尝试来做。
主要参考
[Doing local BLAST searches on sanger sequence data in R