生信 | 构建物种的OrgDb

写在前面

  • 本文主要参考生信小白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分析的时候需要背景文件,因此为了方便即可导出pathway2namepathway2gene
# 做一些常规格式化
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)
image.png

你可能感兴趣的:(生信 | 构建物种的OrgDb)