写在前面
- 本文主要参考生信小白2018与多啦A梦的时光机的,但由于EggNOG(v5.0)数据库与eggnog-mapper(v2.1.3)更新后,修改了输出文件的格式,因此他们二人写的脚本会出现一些问题,但R学的好的话完全可以克服,我保留了他们的大部分源码并进行了debug,优化了一些步骤,供大家参考。
注意:完成下面的步骤至少需要~40GB运行内存与~50GB的存储空间,因此没有服务器的同学不要轻易尝试
当然,如果你无论如何也构建不成功可以和我koukou466478340,注意:并非无偿哈
1. 使用eggnog-mapper生成注释文件
- 以下代码在Linux中运行
1.1. 下载eggnog-mapper软件
- 进入你想存放的文件夹下下载。由于eggnog-mapper只托管在GitHub上,所以使用git下载,而不能用wget或pip或conda下载,托管到GitHub上的好处就是下载之后就是文件夹,不用解压、编译之类的操作。
2022年3月27日更新:conda上可以直接下载了 conda install -c bioconda eggnog-mapper
2022年10月3日更新:pip上可以直接下载了 pip install eggnog-mapper
git clone https://github.com/jhcepas/eggnog-mapper.git
1.2. 下载EggNOG数据库
- 下载链接:http://eggnog5.embl.de/download/
- 请严格按照图片操作。
-
注意:一定要放到eggnog-mapper软件目录下的data文件夹中,使用conda装的放到类似的conda路径下面
/root/miniconda3/envs/python3/lib/python3.7/site-packages/data
;其中需要更改的就是你安装miniconda的路径以及conda环境的名称。因为我是安装在root/目录下面,python3环境中的,所以路径如上。
使用gunzip解压
gunzip eggnog.db.gz eggnog.proteins.dmnd.gz
1.3. 将eggnog-mapper文件夹添加至环境变量【conda装的可忽略】
- 注意:将路径修改为你自己的
echo 'export PATH=/public/user/software/eggnog-mapper:$PATH' >> ~/.bashrc
source ~/.bashrc
1.4. 配置eggnog-mapper的运行环境(可省略)
- 因为eggnog-mapper是运行在python3(>v3.7)环境下的软件,可以先使用conda建一个python3(教程)的环境,其实我们做生信的,常备不同的环境是很必要的
conda create -n python3 python=3.7.8 -y
activate python3
1.5. 运行eggnog-mapper
注意:蛋白文件的中基因名必须要和你以后富集分析的基因名格式相同,如果不同,后面的操作都是徒劳,千万注意。
emapper.py -i mm39.pep.fa -o mm39 -d euk --cpu 10 --dbmem
-
-i
:输入的蛋白组序列文件,请自行下载你物种的pep序列文件,并将其中的ID换为你常用的ID,不然到时候根据ID富集不到也就白忙活了。 -
-o
:输出文件的前缀,后缀会自动补充为.emapper.annotations -
-m
:默认就是diamond,因此不用指定。 -
--dbmem
:将数据库全部存入运行内存,极大提高运行速度,但特别吃运存,大约要45GB的运行空间。 -
--cpu
:使用的线程数 -
--override
:可以覆盖原有的文件,多次尝试的时候可以加上 -
-d
: 比对数据库的类型,作者给了euk(真核), bact(细菌), arch(古菌)三大类。虽然大类更全,但有顾虑就是植物动物微生物乱匹配,因此推荐使用--tax_scope
--tax_scope
: 有以下参数可以选择。
如小鼠可选Eukaryota下面的Chordata(脊椎动物),即emapper.py -i mm39.pep.fa -o mm39 --tax_scope Chordata
如拟南芥可选Eukaryota下面的Viridiplantae(绿色植物),即emapper.py -i tair.pep.fa -o tair --tax_scope Viridiplantae
再比如想选择多个,那么就把他们写入到文件中,然后入读,即emapper.py -i tair.pep.fa -o tair --tax_scope ./example.txt
更多分类也可以查看该目录下的文件:/root/softwear/eggnog-mapper-master/eggnogmapper/annotation/tax_scopes
Eukaryota | Bacteria | Bacteria | Bacteria | Archaea |
---|---|---|---|---|
Arthropoda | Acidimicrobiia | Oceanospirillales | Gammaproteobacteria | Archaeoglobi |
Nematoda | Acidithiobacillales | Opitutae | Gemmatimonadetes | Crenarchaeota |
Chordata | Aeromonadales | Pasteurellales | Planctomycetes | Halobacteria |
Ascomycota | Bacilli | Rhodocyclales | Tenericutes | Methanobacteria |
Basidiomycota | Bacteroidetes | Rhodospirillales | Verrucomicrobia | Methanococci |
Bilateria | Bdellovibrionales | Rickettsiales | Acidobacteria | Methanomicrobia |
Coccidia | Caulobacterales | Rubrobacteria | Aquificae | Thaumarchaeota |
Aconoidasida | Chlorobi | Sphingomonadales | Deferribacteres | Thermococci |
Peronosporales | Chloroflexia | Thermomicrobia | Fusobacteria | Thermoplasmata |
Pythiales | Chromatiales | Thiotrichales | Nitrospirae | Euryarchaeota |
Apicomplexa | Clostridia | Verrucomicrobiae | Proteobacteria | - |
Bacillariophyta | Coriobacteriia | Vibrionales | Spirochaetes | - |
Chlorophyta | Cyanobacteria | Xanthomonadales | Synergistetes | - |
Ciliophora | Dehalococcoidia | Acidobacteriia | Thermodesulfobacteria | - |
Fungi | Erysipelotrichia | Actinobacteria | Thermotogae | - |
Kinetoplastida | Hydrogenophilales | Alphaproteobacteria | - | - |
Metazoa | Legionellales | Betaproteobacteria | - | - |
Streptophyta | Methylococcales | Chlamydiae | - | - |
Amoebozoa | Negativicutes | Chloroflexi | - | - |
Opisthokonta | Neisseriales | Deinococcus-Thermus | - | - |
Viridiplantae | Nitrosomonadales | Firmicutes | - | - |
1.6. 漫长的等待
- 根据pep序列文件的大小所需要的时间不同,我用小鼠的6万条序列,估计用了5个小时左右,当然加入
--dbmem
的时间在20分钟左右。这点时间,你可以大致阅读下面的内容。
1.7. 运行结果
- 运行结束后,eggnog-mapper会生成三个文件,以小鼠mm39为例:
-
mm39.emapper.hmm_hits
: 记录每个用于搜索序列对应的所有的显著性的eggNOG Orthologous Groups(OG). 所有标记为"-"则表明该序列未找到可能的OG -
mm39.emapper.seed_orthologs
: 记录每个用于搜索序列对的的最佳的OG,也就是mm39.emapper.hmm_hits里选择得分最高的结果。之后会从eggNOG中提取更精细的直系同源关系(orthology relationships) -
mm39.emapper.annotations:
该文件提供了最终的注释结果,也是我们后续构建OrgDb的文件
它一共有21列,列名如下: - query:检索的基因名或者其他ID,就是提供蛋白组序列文件中的ID,所以这个ID和以后做GO/KEGG分析的ID要相同,不然就没办法做了,已经说了好多次了。
- seed_ortholog
- evalue
- score
- eggNOG_OGs
- max_annot_lvl
- COG_category
- Description
- Preferred_name:预测的基因名,特别类似AP2有含义的基因名,可以直接在NCBI 的 Gene数据库中查看,一般是其他物种确定了功能的基因名
- GOs:推测的GO的词条
- EC
- KEGG_ko:推测的KEGG KO词条
- KEGG_Pathway:该条目显示的是K中包含的Ko以及map,没用,后面我们会自己生成
- KEGG_Module
- KEGG_Reaction
- KEGG_rclass
- BRITE
- KEGG_TC
- CAZy
- BiGG_Reaction:BiGG
- PFAMs
1.8. 处理数据
- 首先删掉【mm39.emapper.annotations】开头与末尾没用的行和表头的#即可,然后使用awk提取需要的列
重输出为【mm39.annotations】
id=mm39 #刚才的前缀
sed '/^##/d' ${id}.emapper.annotations| sed 's/#//g'| awk -vFS="\t" -vOFS="\t" '{print $1,$9,$10,$12}' > ${id}.annotations
- 然后就可以使用【mm39.annotations】开始在R中构建OrgDb了
2. 构建OrgDb
- 以下代码在R中运行
2.1. 安装并导入所需R包
#install.packages("")
library(dplyr)
library(stringr)
library(jsonlite)
library(AnnotationForge)
#顺手设置一下options
options(stringsAsFactors = F)
2.2. 读入生成的annotations文件
emapper <- read.table("mm39.annotations", header=TRUE, sep = "\t",quote = "")
#将空值替换为NA,方便后续使用na.omit()函数提出没有注释到的行
emapper[emapper==""]<-NA
2.3. 提取GO信息
- 把emapper中的【query】列、【Preferred_name】列【GOs】列提取出来(其中【%>%】相当于linux中的管道符【|】)
# library(dplyr)
gene_info <- emapper %>% dplyr::select(GID = query, GENENAME = Preferred_name) %>% na.omit()
gos <- emapper %>% dplyr::select(query, GOs) %>% na.omit()
- 构建一个空的【gene2go】数据框,为后面填充数据用
gene2go = data.frame(GID = character(),
GO = character(),
EVIDENCE = character())
- 对【gene2go】空数据框进行填充。
# library(stringr)
gos_list <- function(x){
the_gos <- str_split(x[2], ",", simplify = FALSE)[[1]]
df_temp <- data.frame(GID = rep(x[1], length(the_gos)),
GO = the_gos,
EVIDENCE = rep("IEA", length(the_gos)))
return(df_temp)
}
gene2gol <- apply(as.matrix(gos),1,gos_list)
gene2gol_df <- do.call(rbind.data.frame, gene2gol)
gene2go <- gene2gol_df
gene2go$GO[gene2go$GO=="-"]<-NA
gene2go<-na.omit(gene2go)
- 循环的作用简单来说就单行变多行,举例如下:
# query1 GO:XXXXXX1
#query1 GO:XXXXXX1,GO:XXXXXX2,GO:XXXXXX3 => query1 GO:XXXXXX2
# query1 GO:XXXXXX3
2.4. 同理,提取KEGG信息
- 把emapper中的query列、KEGG_ko列提取出来
gene2ko <- emapper %>% dplyr::select(GID = query, Ko = KEGG_ko)
gene2ko$Ko[gene2ko$Ko=="-"]<-NA
gene2ko<-na.omit(gene2ko)
gene2kol <- apply(as.matrix(gene2ko),1,gos_list)
gene2kol_df <- do.call(rbind.data.frame, gene2kol)
gene2ko <- gene2kol_df[,1:2]
colnames(gene2ko) <- c("GID","Ko")
gene2ko$Ko <- gsub("ko:","",gene2ko$Ko)
- 下载KO的json文件并【放到当前文件夹下】,下载地址:https://www.genome.jp/kegg-bin/get_htext?ko00001
- 定义函数,不用管是啥直接跑,其中只用到了下载的【ko00001.json】文件,所以可以放心跑
# library(jsonlite)
# 下面的json = "ko00001.json",如果你下载到其他地方,记得加上路径
update_kegg <- function(json = "ko00001.json") {
pathway2name <- tibble(Pathway = character(), Name = character())
ko2pathway <- tibble(Ko = character(), Pathway = character())
kegg <- fromJSON(json)
for (a in seq_along(kegg[["children"]][["children"]])) {
A <- kegg[["children"]][["name"]][[a]]
for (b in seq_along(kegg[["children"]][["children"]][[a]][["children"]])) {
B <- kegg[["children"]][["children"]][[a]][["name"]][[b]]
for (c in seq_along(kegg[["children"]][["children"]][[a]][["children"]][[b]][["children"]])) {
pathway_info <- kegg[["children"]][["children"]][[a]][["children"]][[b]][["name"]][[c]]
pathway_id <- str_match(pathway_info, "ko[0-9]{5}")[1]
pathway_name <- str_replace(pathway_info, " \\[PATH:ko[0-9]{5}\\]", "") %>% str_replace("[0-9]{5} ", "")
pathway2name <- rbind(pathway2name, tibble(Pathway = pathway_id, Name = pathway_name))
kos_info <- kegg[["children"]][["children"]][[a]][["children"]][[b]][["children"]][[c]][["name"]]
kos <- str_match(kos_info, "K[0-9]*")[,1]
ko2pathway <- rbind(ko2pathway, tibble(Ko = kos, Pathway = rep(pathway_id, length(kos))))}}}
save(pathway2name, ko2pathway, file = "kegg_info.RData")}
# 调用函数后在本地创建kegg_info.RData文件,以后只需要载入 "kegg_info.RData"即可
update_kegg()
# 载入kegg_info.RData文件
load(file = "kegg_info.RData")
- 根据gene2ko中的Ko信息将ko2pathway中的Pathway列提取出来
gene2pathway <- gene2ko %>% left_join(ko2pathway, by = "Ko") %>% dplyr::select(GID, Pathway) %>% na.omit()
2.5. 获取物种信息
- 首先在NCBI上查询你物种的相关信息,网址:https://www.ncbi.nlm.nih.gov/taxonomy
- 比如说小鼠Mus musculus
tax_id = "10090"
genus = "Mus"
species = "musculus"
- 或者人Homo sapiens
# tax_id = "9606"
# genus = "Homo"
# species = "sapiens"
- 又或者拟南芥Arabidopsis thaliana
# tax_id = "3702"
# genus = "Arabidopsis"
# species = "thaliana"
其实,都可以随便填写,不会影响建库结果,只会影响你输出文件的名字,像个性化输出名字就自定义
可以去重,以防万一,或者等下面报错提示去重再去跑代码也行。原理是,
makeOrgPackage
不允许有重复的行,因此需要删除,除了gene2pathway
可能有重复的行,其他几乎不可能有重复的情况。
# gene2go <- unique(gene2go)
# gene2go <- gene2go[!duplicated(gene2go),]
# gene2ko <- gene2ko[!duplicated(gene2ko),]
# gene2pathway <- gene2pathway[!duplicated(gene2pathway),]
# gene_info <- gene_info[!duplicated(gene_info),]
2.6. 构建OrgDb
- 开始构建
makeOrgPackage(gene_info=gene_info,
go=gene2go,
ko=gene2ko,
pathway=gene2pathway,
version="1.34.1", #版本,使用?makeOrgPackage,拉到最下面查看
maintainer = "your name <邮箱>", #修改为你的名字和邮箱
author = "your name <邮箱>", #修改为你的名字和邮箱
outputDir = ".", #输出文件位置
tax_id=tax_id, #你在NCBI上查并定义的id
genus=genus, #你在NCBI上查并定义的属名
species=species, #你在NCBI上查并定义的种名
goTable="go")
- 构建成功后会在当前路径下生成一个【文件夹】,名字形如【org.XXX.eg.db】(其中XXX的构成为你定义的genus的大写首字母+species名,如小鼠是Mmusculus,人是Hsapiens,拟南芥是Athaliana)
3. 导入OrgDb库
install.packages("./org.Mmusculus.eg.db", repos=NULL)
library(org.Mmusculus.eg.db)
# 查看所有列的信息
columns(org.Mmusculus.eg.db)
# 查看所有基因
keys(org.Mmusculus.eg.db)
# 查看特定基因的信息
# library(dplyr)
select(org.Mmusculus.eg.db, keys = "CW07G09620", columns = c("GO"))
4. 导出背景文件
- 因为我们在后面进行kegg分析的时候需要背景文件,因此为了方便即可导出
pathway2name
和pathway2gene
# 做一些常规格式化
pathway2name$Name <- gsub(" \\[BR:ko[0-9]{5}\\]", "",pathway2name$Name)
pathway2name<- na.omit(pathway2name)
pathway2gene <-gene2pathway[, c("Pathway","GID")]
# 输出
write.table(pathway2name,file = "./pathway2name", sep = "\t", quote = F, row.names = F)
write.table(pathway2gene,file = "./pathway2gene", sep = "\t", quote = F, row.names = F)
5. 使用clusterProfiler富集分析
5.1 KEGG富集分析(不需要OrgDB)
library(clusterProfiler)
# 每次只需导入下面两个文件即可
pathway2gene <- read.table("./pathway2gene",header = T,sep = "\t")
pathway2name <- read.table("./pathway2name",header = T,sep = "\t")
# 导入你鉴定到的差异基因列表,并转化为向量
gene <- read.csv("/root/total_diff_gene.csv")
gene_list <- gene[,1]
# KEGG pathway 富集
ekp <- enricher(gene_list,
TERM2GENE = pathway2gene,
TERM2NAME = pathway2name,
pvalueCutoff = 1, # 表示全部保留,可以设为0.05作为阈值
qvalueCutoff = 1, # 表示全部保留,可以设为0.05作为阈值
pAdjustMethod = "BH",
minGSSize = 1)
dotplot(ekp)
5.2 GO富集分析(需要OrgDB)
library(org.Mmusculus.eg.db)
ego <- enrichGO(gene=gene_list,
OrgDb=org.Mmusculus.eg.db,
keyType="GID",
ont="ALL", #CC/BP/MF可选
qvalueCutoff = 0.05,
pvalueCutoff =0.05)
dotplot(ego)
# 无论是ekp还是ego都可以选择将数据导出,然后可以自己使用ggplot画
ego_results<-as.data.frame(ego)
write.table(ego_results, file = "./ego_results.txt", quote = F)