12.1 创建和运行一个脚本
12.1.1 问题
你想要创建和运行一个脚本。
12.1.2 方案
R 脚本通常是以 .R
为文件拓展名的纯文本文件。因此创建R脚本可以是任意的文本编辑器,R 最佳的集成开发环境是 RStudio,它开源并有免费的桌面版本和服务器版本发布,推荐读者下载、安装和使用。
在类 Unix 系统中,除了编辑器,我们还可以使用终端命令。例如,创建一个输出 Hello world!
的 R 脚本。
echo 'cat("Hello world!")' > test.R
运行 R 脚本可以在 R 控制台使用 source()
函数。
source("test.R", print.eval = TRUE)
#> Hello world!
也可以在终端中使用 RScript
执行。
RScript test.R
#> Using library: /Users/wsx/R_library
#> 载入需要的程辑包:pacman
#> Hello world!
12.1.3 案例:计算细菌基因组核心蛋白相似性
- 应用场景
细菌分类学研究中,需要借助基因组水平的相似度来界定是否属于新物种,是否是一个未发现的新属水平或者新科水平,乃至更高的分类学单元(界/门/纲/目/科/属/种)。
在基因组的核酸水平研究中,有诸如 dDDH(数字化 DNA 分子杂交)、核苷酸平均相似度(Average Nucleotide Identity,ANI)等指标来界定是否属于新物种;而在基因组蛋白质水平相类似的指标较少,比如氨基酸平均相似度(Average Amino acid Identity,AAI)和保守蛋白比率(percentage of conserved proteins,POCP)等。
- 简要过程
两两比对细菌基因组的蛋白序列,互为参考数据库进行 blastp 比对(A 作数据库,B 查询;B 作数据库,A 查询),数据筛选的标准是:一致度大于 40%,查询片段的长度大于原片段长度的 50%,e 值小于 1e-5。
- 参考文献
Qin, Q. L., Xie, B. B., Zhang, X. Y., Chen, X. L., Zhou, B. C., Zhou, J., … & Zhang, Y. Z. (2014). A proposed genus boundary for the prokaryotes based on genomic insights. Journal of bacteriology, 196(12), 2210-2215.
以下 R 脚本都是在 windows 操作平台上进行的。
# 下载所分析的基因组数据(蛋白序列)
# 存放于 Rawdata 文件夹中
if (!dir.exists('Rawdata')) {
dir.create('Rawdata')
}
# 示例-1: Pseudomonas aeruginosa
# ftp://ftp.ncbi.nlm.nih.gov/genomes/all/GCF/000/006/765/GCF_000006765.1_ASM676v1/GCF_000006765.1_ASM676v1_protein.faa.gz
# 示例-2: Acinetobacter baumannii
# ftp://ftp.ncbi.nlm.nih.gov/genomes/all/GCF/000/746/645/GCF_000746645.1_ASM74664v1/GCF_000746645.1_ASM74664v1_protein.faa.gz
# 使用 R.utils 中的 gunzip 解压缩
library(R.utils)
download.file("ftp://ftp.ncbi.nlm.nih.gov/genomes/all/GCF/000/006/765/GCF_000006765.1_ASM676v1/GCF_000006765.1_ASM676v1_protein.faa.gz",
destfile = "Rawdata/Pseudomonas_aeruginosa.faa.gz")
gunzip("Rawdata/Pseudomonas_aeruginosa.faa.gz")
download.file("ftp://ftp.ncbi.nlm.nih.gov/genomes/all/GCF/000/746/645/GCF_000746645.1_ASM74664v1/GCF_000746645.1_ASM74664v1_protein.faa.gz",
destfile = "Rawdata/Acinetobacter_baumannii.faa.gz")
gunzip("Rawdata/Acinetobacter_baumannii.faa.gz")
# 使用 dbplyr 对数据框中的某列去重复
library(dbplyr)
# 使用 seqinr 格式化 fasta 格式的序列
library(seqinr)
# 检查存放中间过程文件的文件夹是否存在
if (!dir.exists('Database')) {
dir.create('Database')
}
if (!dir.exists('Result')) {
dir.create('Result')
}
# 获取所有待分析基因组文件名
genome.files <- list.files('Rawdata')
# 对所有的待分析基因组建库
for (gn in genome.files) {
header.file <- strsplit(gn,'.',fixed = T)[[1]][1]
commond.makedb <- paste0('diamond.exe makedb --in Rawdata/',
gn, ' --db Database/', header.file)
system(commond.makedb)
}
# 获取多基因组的两两比对的组合数据集
genome.comn <- combn(genome.files,2)
# 计算核心蛋白相似性的骨架命令
blast.comm1 <- 'diamond.exe blastp -q Rawdata/'
blast.comm2 <- ' -d Database/'
blast.comm3 <- ' -e 1e-5 --id 40 -o Result/'
# 建立新变量,保存运算结果
pocp.vector <- c()
for (i in (1:dim(genome.comn)[2]) ) {
a.genome <- genome.comn[,i][1]
b.genome <- genome.comn[,i][2]
a.header <- strsplit(a.genome,'.',fixed = T)[[1]][1]
b.header <- strsplit(b.genome,'.',fixed = T)[[1]][1]
a.genome.seq <- read.fasta(paste0('Rawdata/', a.genome),'AA')
b.genome.seq <- read.fasta(paste0('Rawdata/', b.genome),'AA')
a.total <- length(a.genome.seq)
b.total <- length(b.genome.seq)
str(a.genome.seq)
str(b.genome.seq)
a.seq.list <- names(a.genome.seq)
b.seq.list <- names(b.genome.seq)
a.seq.length <- c()
for (nm in a.seq.list) {
tmp.len <- length(a.genome.seq[[which(a.seq.list == nm)]])
a.seq.length <- append(a.seq.length, tmp.len)
}
b.seq.length <- c()
for (nm in b.seq.list) {
tmp.len <- length(b.genome.seq[[which(b.seq.list == nm)]])
b.seq.length <- append(b.seq.length, tmp.len)
}
a.seq.df <- data.frame(a.seq.list, a.seq.length)
colnames(a.seq.df) <- c('V1','length')
b.seq.df <- data.frame(b.seq.list, b.seq.length)
colnames(b.seq.df) <- c('V1','length')
print(paste0('-- Blasting: ',a.header,' - VS - ',b.header))
# 「正向」-- A 为查询,B 为参考数据库
result.forward <- paste0(a.header,'_VS_',b.header,'.tab')
system(paste0(blast.comm1, a.genome,
blast.comm2, b.header,
blast.comm3, result.forward))
df.forward <- read.table(paste0('Result/',result.forward),
header = F,sep = '\t',
stringsAsFactors = F)
df.forward <- df.forward %>% distinct(V1,.keep_all = T)
df.forward <- merge(df.forward, a.seq.df, by = 'V1', all.x = T)
df.forward$align <- df.forward$V4 / df.forward$length
df.forward <- df.forward[which(df.forward$V3 > 40 & df.forward$align > 0.5 & df.forward$V11 < 1e-5),]
C1 <- dim(df.forward)[1]
# 「反向」-- B 为查询,A 为参考数据库
result.backward <- paste0(b.header,'_VS_',a.header,'.tab')
system(paste0(blast.comm1, b.genome,
blast.comm2, a.header,
blast.comm3, result.backward))
df.backward <- read.table(paste0('Result/',result.backward),
header = F,sep = '\t',
stringsAsFactors = F)
df.backward <- df.backward %>% distinct(V1,.keep_all = T)
df.backward <- merge(df.backward, b.seq.df, by = 'V1', all.x = T)
df.backward$align <- df.backward$V4 / df.backward$length
df.backward <- df.backward[which(df.backward$V3 > 40 & df.backward$align > 0.5 & df.backward$V11 < 1e-5),]
C2 <- dim(df.backward)[1]
pocp <- (C1 + C2)/(a.total + b.total)
pocp.vector <- append(pocp.vector, paste0(a.header,'\t',b.header,'\t',pocp))
print(paste0('-- Pair blast done: ',a.header,' - VS - ',b.header))
print(paste0('-- The POCP : ', pocp))
print('----------------------------------')
}
write(pocp.vector, 'resultPOCP.txt')
# 删除分析过程中的冗余文件
unlink("Database", recursive = TRUE)
unlink("Result", recursive = TRUE)
# 重新创建新文件夹
dir.create('Database')
dir.create('Result')
12.1.3.1 提示
更多关于 POCP 计算的相关技巧,请点击这里阅读。