转录组分析6——GO/KEGG富集分析

莎莎写于2020.5.2
这是5月坚持的第2天,要一直坚持写啊,加油!

image.png

差异基因的功能注释和富集分析:

• GO和KEGG富集分析
• 基因集富集分析
 MsigDB数据库
 GSEA分析
 GSVA分析

1.GO数据库官网:http://geneontology.org/

GO(gene ontology)是基因本体联合会(Gene OnotologyConsortium)所建立的数据库,旨在建立一个适用于各种物种的,堆积因和蛋白质功能进行限定和描述的,并能随着研究不断深入而更新的语言词汇标准。它是多种生物本体语言中的一种,提供了三层结构的系统定义方式,用于描述基因产物的功能。

  • 基因本体将涉及的基因和基因产物词汇分为三大类,发展了具有三级结构的标准
    语言(ontologies),涵盖生物学的三个方面:
    细胞组分(cellular component,CC):细胞的每个部分和细胞外环境,亚细
    胞结构、位置和大分子复合物,如核仁、端粒和识别起始的复合物等;
    分子功能 ( molecular function , MF ) : 可 以 描 述 为 分 子 水 平 的 活 性
    (activity),如催化(catalytic)或结合(binding)活性;
    生物过程(biological process,BP):生物学过程系指由一个或多个分子功能
    有序组合而产生的系列事件。其定义有广义和狭义之分,在词义上可以区分
    为泛指和特指。一般规律是,一个过程是由多个不同的步骤组成,分子功能
    的有序组合,达成更广的生物功能,如有丝分裂或嘌呤代谢等。
image.png

2.KEGG数据库官网: http://www.genome.jp/kegg/

image.png

image.png

(1)KEGG

rm(list = ls())
options(stringsAsFactors = F)

library(clusterProfiler)
library(org.Hs.eg.db)

# 读取3个软件的差异分析结果
load(file = "data/Step03-limma_voom_nrDEG.Rdata")
limma_DEG <- nrDEG
load(file = "data/Step03-DESeq2_nrDEG.Rdata")
DESeq2_DEG <- nrDEG
load(file = "data/Step03-edgeR_nrDEG.Rdata")
edgeR_DEG <- nrDEG

# 根据需要更改DEG的值
DEG <- limma_DEG
#### KEGG analysis 
#### 第一步,确定上下调基因
# 获得差异倍数阈值
logFC_cutoff <- with(DEG, mean( abs(log2FoldChange) ) + 2 * sd(abs(log2FoldChange)))
logFC_cutoff <- round(logFC_cutoff,2)
DEG$change = as.factor( ifelse( DEG$pvalue < 0.05 & abs(DEG$log2FoldChange) > logFC_cutoff,
                                  ifelse( DEG$log2FoldChange > logFC_cutoff , 'UP', 'DOWN' ), 'STABLE' ) )
table(DEG$change)
image.png
#### 第二步,从org.Hs.eg.db提取ENSG的ID 和GI号对应关系
keytypes(org.Hs.eg.db)
# 如果ENSG的ID具有小数点,用下面两句代码舍掉小数点
# library(stringr)
# rownames(DEG) <- str_sub(rownames(DEG), start = 1, end = 15)
DEG$ENSEMBL <- rownames(DEG)
# bitr in clusterProfiler
df <- bitr( rownames(DEG), fromType = "ENSEMBL", toType = c( "ENTREZID" ), OrgDb = org.Hs.eg.db )
head(df)
# 22.7% of input gene IDs are fail to map...
ID转换
#### 第三步,将GI号合并到DEG数据框内
f  <- 'data/Step05-DEG_ENTREZID_for_GSEA_GSVA.Rda'
if(!file.exists(f)){
  DEG$SYMBOL <- rownames(DEG)
  DEG <- merge(DEG, df, by='ENSEMBL')  #合并
  head(DEG)
  dim(DEG)
  # DEG数据会减少!
  save(DEG, file = "data/Step05-DEG_ENTREZID_for_GSEA_GSVA.Rda")
}

load("data/Step05-DEG_ENTREZID_for_GSEA_GSVA.Rda")
这一列被加到了数据框中
#### 第四步,提取上调和下调的GI集
gene_up <- DEG[ DEG$change == 'UP', 'ENTREZID' ] 
gene_down <- DEG[ DEG$change == 'DOWN', 'ENTREZID' ]
gene_diff <- c( gene_up, gene_down )
gene_all <- as.character(DEG[ ,'ENTREZID'] )

geneList <- DEG$log2FoldChange
names( geneList ) <- DEG$ENTREZID
geneList <- sort( geneList, decreasing = T )   #从大到小排序

## KEGG pathway analysis
f  <- 'data/Step05-enrichKEGG.Rdata'
if(!file.exists(f)){
  kk.up <- enrichKEGG(  gene          =  gene_up    ,
                        organism      =  'hsa'      ,
                        universe      =  gene_all   ,
                        pvalueCutoff  =  0.8        ,
                        qvalueCutoff  =  0.8        )
  kk.down <- enrichKEGG(gene          =  gene_down  ,
                        organism      =  'hsa'      ,
                        universe      =  gene_all   ,
                        pvalueCutoff  =  0.05       )
  
  save(kk.up,kk.down,file = "data/Step05-enrichKEGG.Rdata")
}

load(file = "data/Step05-enrichKEGG.Rdata")
head(kk.up)[ ,1:6 ]
head(kk.down)[ ,1:6 ]
image.png
library(ggplot2)

kegg_down_dt <- as.data.frame( kk.down )
kegg_up_dt <- as.data.frame( kk.up )
down_kegg <- kegg_down_dt[ kegg_down_dt$pvalue < 0.05, ]
down_kegg$group = -1
up_kegg <- kegg_up_dt[ kegg_up_dt$pvalue < 0.05, ]
up_kegg$group = 1
  
dat = rbind( up_kegg, down_kegg )
dat$pvalue = -log10( dat$pvalue )
dat$pvalue = dat$pvalue * dat$group
  
dat = dat[ order( dat$pvalue, decreasing = F ), ]
  
g_kegg <- ggplot( dat, aes(x = reorder( Description, order( pvalue, decreasing=F ) ), y = pvalue, fill = group)) + 
  geom_bar( stat = "identity" ) + 
  scale_fill_gradient( low = "blue", high = "red", guide = FALSE ) + 
  scale_x_discrete( name = "Pathway names" ) +
  scale_y_continuous( name = "log10P-value" ) +
  coord_flip() + theme_bw() + theme( plot.title = element_text( hjust = 0.5 ) ) +
  ggtitle( "Pathway Enrichment" ) 
print( g_kegg )
ggsave( g_kegg, filename = 'figures/Step05-kegg_up_down_anno.png' )
image.png

(2)GO

#### GO analysis 
# 做GO数据集超几何分布检验分析,
# 重点在结果的可视化及生物学意义的理解。

g_list=list(gene_up=gene_up,
           gene_down=gene_down,
           gene_diff=gene_diff)

f  <- 'data/Step05-go_enrich_results.Rdata'
if(!file.exists(f)){
 go_enrich_results <- lapply( g_list , function(gene) {
   lapply( c('BP','MF','CC') , function(ont) {
     cat(paste('Now process ',ont ))
     ego <- enrichGO(gene          = gene,
                     universe      = gene_all,
                     OrgDb         = org.Hs.eg.db,
                     ont           = ont ,
                     pAdjustMethod = "BH",
                     pvalueCutoff  = 0.99,
                     qvalueCutoff  = 0.99,
                     readable      = TRUE)
     
     print( head(ego) )
     return(ego)
   })
 })
 save(go_enrich_results,file = 'data/Step05-go_enrich_results.Rdata')
}

load(file = 'data/Step05-go_enrich_results.Rdata')
n1 <- c('gene_up','gene_down','gene_diff')
n2 <- c('BP','MF','CC') 
for (i in 1:3){
 for (j in 1:3){
   fn <- paste0('figures/Step05-GO_dotplot_',n1[i],'_',n2[j],'.png')
   cat(paste0(fn,'\n'))
   png(fn,res=150,width = 1080)
   print(dotplot(go_enrich_results[[i]][[j]]))
   dev.off()
 }
}
image.png

image.png

随便选了一张

3.GSEA官网:https://www.gsea-msigdb.org/gsea/index.jsp

image.png

image.png

image.png

GSEA与别的差异分析相比,它保留了一些差异并不显著但是功能显著的基因,包容性更强,他不需要进行差异分析,他的输入数据是基因集genelist(并不是单个基因)和基因差异表达情况(可以是前面分析好的logFc值)

MSigDB:收集基因集的数据库,有八大类基因集

• H: hallmark gene sets该类别包含了由多个已知的基因集构成的超基因集,每个H类别的
基因集都对应多个基础的其他类别的基因集。
• C1: positional gene sets该类别包含人类每条染色体上的不同cytoband区域对应的基因集合。根据不同染色体编号进行二级分类。
• C2:curated gene sets
• 该类别包含了已知数据库,文献和专家支持的基因集信息。
• C3 : motif gene sets该类别包含了miRNA靶基因和转录因子结合区域等基因集合。
• C4 : computational gene sets 计算机软件预测出来的基因集合,主要是和癌症相关的基因。
• C5 : GO gene sets该类别包含了Gene Ontology对应的基因集合
• C6 : oncogenic signatures该类别包含已知条件处理后基因表达量发生变化的基因。
• C7 : immunologic signatures该类别包含了免疫系统功能相关的基因集合。
http://software.broadinstitute.org/gsea/msigdb/genesets.jsp

image.png

下面R中实现GSEA的分析:

rm(list = ls())
library(GSEABase)
library(clusterProfiler)

load(file = "data/Step05-DEG_ENTREZID_for_GSEA_GSVA.Rda")
geneList <- DEG$log2FoldChange
names(geneList) <- DEG$ENTREZID   #对genelist赋值
geneList <- sort(geneList,decreasing = T)  #从大到小排序

## 如果存在之前分析后保存的结果文件,就不需要重复进行GSEA分析。
f <- 'data/Step06-gsea_results.Rdata'
#选择gmt文件(MigDB中的全部基因集)
d <- 'MsigDB/'
gmts <- list.files(d,pattern = 'all')
gmts
if(!file.exists(f)){
  gsea_results <- lapply(gmts, function(gmtfile){
    # gmtfile=gmts[2]
    geneset <- read.gmt(file.path(d,gmtfile)) 
    print(paste0('Now process the ',gmtfile))
    egmt <- GSEA(geneList, TERM2GENE=geneset, verbose=FALSE)
    head(egmt)
    return(egmt)
  })
  # 上面的代码耗时,所以保存结果到本地文件
  save(gsea_results,file = f)
}


load(file = f)
#提取gsea结果,熟悉这个对象
gsea_results_list<- lapply(gsea_results, function(x){
  cat(paste(dim(x@result)),'\n')
  x@result
})
gsea_results_df <- do.call(rbind, gsea_results_list)
gseaplot(gsea_results[[6]],geneSetID = 1) 
gseaplot(gsea_results[[6]], "PRC2_EZH2_UP.V1_UP")
gseaplot(gsea_results[[6]],geneSetID = 12) 
可以看到是富集在左端并且呈现上调趋势

4.GSVA

GSVA分析原理:
• 基因集变异分析(Gene Set Variation Analysis,GSVA),一种以非监督方式对一个简单群体评估通路活性变异的GSE方法。
• GSE基因集富集(gene set enrichment)方法通常被认为是一个生物信息学分析的终点,但是GSVA构成了一个构建以通路为中心的生物学模型的起点。

image.png
### 对 MigDB中的全部基因集 做GSVA分析。
## 还有ssGSEA, PGSEA

### 读取基因表达矩阵
rm(list = ls())
options(stringsAsFactors = F)
load(file = "data/Step01-airway2exprSet.Rdata")
dim(exprSet)
table(group_list)

library(limma)
library(edgeR)

dge <- DGEList(counts=exprSet)
dge <- calcNormFactors(dge)
logCPM <- cpm(dge, log=TRUE, prior.count=3)
logCPM[1:4,1:4]
  
X <- as.data.frame(logCPM)
## Molecular Signatures Database (MSigDb) 
d <- 'MSigDB'
gmts <- list.files(d,pattern = 'all')
gmts
library(ggplot2)
library(clusterProfiler)
library(org.Hs.eg.db)
library(GSVA) 
  
keytypes(org.Hs.eg.db)
# 如果ENSG的ID具有小数点,用下面两句代码舍掉小数点
# library(stringr)
# rownames(DEG) <- str_sub(rownames(DEG), start = 1, end = 15)
X$ENSEMBL <- rownames(X)
# bitr in clusterProfiler
df <- bitr( rownames(X), fromType = "ENSEMBL", toType = c( "ENTREZID" ), OrgDb = org.Hs.eg.db )
head(df)
df <- unique(df, by = "ENTREZID")
X <- merge(X, df, by='ENSEMBL')
head(X)
dim(X)
X <- cbind(X[ncol(X)], X[-c(1,ncol(X))])
X <- avereps(X, ID = X$ENTREZID)

rownames(X) <- X[,1]
exp <- X[,2:ncol(X)]

f  <- 'data/Step07-es_max.Rda'
if(!file.exists(f)){
  es_max <- lapply(gmts, function(gmtfile){ 
        #gmtfile=gmts[8];gmtfile
        geneset <- getGmt(file.path(d,gmtfile))  
        es.max <- gsva(exp, geneset, 
                       mx.diff=FALSE, verbose=FALSE, 
                       parallel.sz=1)
        return(es.max)
      })
  save(es_max, file = f)
}
adjPvalueCutoff <- 0.001
logFCcutoff <- log2(2)
f  <- 'data/Step07-gsva_msigdb.Rda'
if(!file.exists(f)){
  es_deg <- lapply(es_max, function(es.max){
    table(group_list)
    dim(es.max)
    design <- model.matrix(~0+factor(group_list))
    colnames(design)=levels(factor(group_list))
    rownames(design)=colnames(es.max)
    design
    library(limma)
    contrast.matrix<-makeContrasts(paste0(unique(group_list),collapse = "-"),
                                   levels = design)
    contrast.matrix<-makeContrasts("trt-untrt",
                                   levels = design)
    
    contrast.matrix ##这个矩阵声明,我们要把progres.组跟stable进行差异分析比较
    
    deg = function(es.max,design,contrast.matrix){
      ##step1
      fit <- lmFit(es.max,design)
      ##step2
      fit2 <- contrasts.fit(fit, contrast.matrix) 
      ##这一步很重要,大家可以自行看看效果
      
      fit2 <- eBayes(fit2)  ## default no trend !!!
      ##eBayes() with trend=TRUE
      ##step3
      res <- decideTests(fit2, p.value=adjPvalueCutoff)
      summary(res)
      tempOutput <- topTable(fit2, coef=1, n=Inf)
      nrDEG = na.omit(tempOutput) 
      #write.csv(nrDEG2,"limma_notrend.results.csv",quote = F)
      head(nrDEG)
      return(nrDEG)
    }
    
    re = deg(es.max,design,contrast.matrix)
    nrDEG=re
    head(nrDEG) 
    return(nrDEG)
  })
  
  
  gmts
  
  save(es_max,es_deg,file='data/Step07-gsva_msigdb.Rda')
}


load(file = f)
  
library(pheatmap)
lapply(1:length(es_deg), function(i){
    # i=2
    print(i)
    dat=es_max[[i]]
    df=es_deg[[i]]
    df=df[df$P.Value<0.01 & abs(df$logFC) > 0.3,]
    print(dim(df))
    if(nrow(df)>5){
      n=rownames(df)
      dat=dat[match(n,rownames(dat)),]
      ac=data.frame(g=group_list)
      rownames(ac)=colnames(dat)
      rownames(dat)=substring(rownames(dat),1,50)
      pheatmap::pheatmap(dat, 
                         fontsize_row = 8,height = 11,
                         annotation_col = ac,show_colnames = F,
                         filename = paste0('figures/Step07-gsva_',strsplit(gmts[i],'[.]')[[1]][1],'.png'))
      
  }
})
  
adjPvalueCutoff <- 0.001
logFCcutoff <- log2(2)
df <- do.call(rbind ,es_deg)
es_matrix <- do.call(rbind ,es_max)
df <- df[df$P.Value<0.01 & abs(df$logFC) > 0.5,]
write.csv(df,file = 'data/Step07-GSVA_DEG.csv')
最后得到的结果

你可能感兴趣的:(转录组分析6——GO/KEGG富集分析)