2022-07-09学习构建orgdb库

以下内容全部来自于此文章https://www.jianshu.com/p/f2e4dbaae719作者:Bioinfo鱼

生信 | 构建物种的OrgDb

写在前面

  • 本文主要参考生信小白2018与多啦A梦的时光机的,但由于EggNOG(v5.0)数据库与eggnog-mapper(v2.1.3)更新后,修改了输出文件的格式,因此他们二人写的脚本会出现一些问题,但R学的好的话完全可以克服,我保留了他们的大部分源码并进行了debug,优化了一些步骤,供大家参考。
  • 注意:完成下面的步骤至少需要~40GB运行内存与~50GB的存储空间,因此没有服务器的同学不要轻易尝试

1. 使用eggnog-mapper生成注释文件

  • 以下代码在Linux中运行

1.1. 下载eggnog-mapper软件

  • conda上可以直接下载了 conda install eggnog-mapper
 conda install  eggnog-mapper

1.2. 下载EggNOG数据库

  • 下载链接:http://eggnog5.embl.de/download/
  • 请严格按照图片操作。
选择最新的文件下载

注意:一定要放到eggnog-mapper软件目录下的data文件夹中,使用conda装的放到类似的conda路径下面:其中dna为我的环境变量,在这个/site-packages文件夹中是没有/data文件夹的,我是自己创建的文件夹。

/home/data/t040331/anaconda3/envs/dna/lib/python3.10/data/

其中需要更改的就是你安装miniconda的路径以及conda环境的名称。因为我是安装python3环境中的,所以路径如上。

wget http://eggnog5.embl.de/download/emapperdb-5.0.2/eggnog.db.gz
wget http://eggnog5.embl.de/download/emapperdb-5.0.2/eggnog_proteins.dmnd.gz
###下载所需要的文件
下载这两个文件
  • 使用gunzip解压
gunzip eggnog.db.gz eggnog.proteins.dmnd.gz

1.3. 运行eggnog-mapper

注意:蛋白文件的中基因名必须要和你以后富集分析的基因名格式相同,如果不同,后面的操作都是徒劳,千万注意。

emapper.py -i Ahypogaea_530_v1.0.protein.fa -o Ahypogaea_530_v1.0 -d euk --cpu 40 --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

1.4.运行结果

运行结束后,eggnog-mapper会生成三个文件,以花生为例:

  • Ahypogaea_530_v1.0.hmm_hits: 记录每个用于搜索序列对应的所有的显著性的eggNOG Orthologous Groups(OG). 所有标记为"-"则表明该序列未找到可能的OG
    • Ahypogaea_530_v1.0.seed_orthologs: 记录每个用于搜索序列对的的最佳的OG,也就是Ahypogaea_530_v1.0.hmm_hits里选择得分最高的结果。之后会从eggNOG中提取更精细的直系同源关系(orthology relationships)
    • Ahypogaea_530_v1.0.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.5. 处理数据

  • 首先删掉【Ahypogaea_530_v1.0.emapper.annotations】开头与末尾没用的行和表头的#即可,然后使用awk提取需要的列
  • 重输出为【Ahypogaea_530_v1.0.annotations】
id=Ahypogaea_530_v1.0  #刚才的前缀
sed '/^##/d' ${id}.emapper.annotations| sed 's/#//g'| awk -vFS="\t" -vOFS="\t" '{print $1,$9,$10,$12}' > ${id}.annotations
  • 小插曲:在这里我生成的文件是“-Ahypogaea_530_v1.0.emapper.annotations”文件名多了一个‘-’所以在运行sed命令时被识别成了-A命令,所以一直报错,之后将‘-’删除后就正常了
  • 然后就可以使用【Ahypogaea_530_v1.0.annotations】开始在R中构建OrgDb了

2. 构建OrgDb

  • 以下代码在R中运行

2.1. 安装并导入所需R包

setwd("D:/桌面/KEGG/new_KEGG")
BiocManager::install("dplyr",force = TRUE)
BiocManager::install("stringr",force = TRUE)
BiocManager::install("jsonlite",force = TRUE)
BiocManager::install("AnnotationForge")
library(dplyr)
library(stringr)
library(jsonlite)
library(AnnotationForge)
options(stringsAsFactors = F)#设置一下options

2.2. 读入生成的annotations文件

emapper <- read.table("Ahypogaea_530_v1.0.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】空数据框进行填充。
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

  • 比如拟南芥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.38.0 ",  #版本,使用?makeOrgPackage,拉到最下面查看
               maintainer = "your name ",  #修改为你的名字和邮箱
               author = "your name ",  #修改为你的名字和邮箱
               outputDir = "D:/桌面/KEGG/new_KEGG",  #输出文件位置
               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.Ahypogaea.eg.db", repos=NULL, type="source")
library(org.Ahypogaea.eg.db)
# 查看所有列的信息
columns(org.Ahypogaea.eg.db)
# 查看所有基因
keys(org.Ahypogaea.eg.db)
# 查看特定基因的信息
# library(dplyr)
select(org.Ahypogaea.eg.db, keys = "arahy.Tifrunner.gnm1.ann1.K8W5NT.1", 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("gene_list.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.Ahypogaea.eg.db)
ego <- enrichGO(gene=gene_list,
                OrgDb=org.Ahypogaea.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 = "D:/桌面/KEGG/new_KEGG/ego_results.txt", quote = F)

你可能感兴趣的:(2022-07-09学习构建orgdb库)