[ZHUHAI_Biotrainee]实战_GEO分析

下面对“GSE78179”进行GEO实战分析

第一部分 读入

1、读入数据

options(stringsAsFactors = F)    #命令:不要把字符串自动转化成因子
library(GEOquery)
eSet <- getGEO("GSE78179", 
               destdir = '.',   #destdir下载到哪里,'.'当前目录
               getGPL = F)

解释:
destdir下载到哪里,'.'当前目录
Q:得到的eSet是一个大list,怎样从中提取表达矩阵? A:用 exprs()读取

2、将eSet内的六组芯片表达读出来(此时的eSet为list)

class(eSet)
length(eSet)
class(eSet[[1]])  
exp <- exprs(eSet[[1]])
pd <- pData(eSet[[1]])
save(pd,exp,file = "step1output.Rdata")

注意:
①当读入进eSet之后,我们需要查看平台(GPL)eSet[[1]]@annotation,因为后期芯片和包为一一对应,方便ID转换
eSet中含有很多的信息,如exprs、pdata、assayData等,eSet是包含很多相关数据的一个集合包
pData为查看临床信息

第二部分 设置分组信息

①查看dat的格式,非常规整。连续三个为肿瘤,连续三个为健康,所以我们可以用group_list=c(rep("Control",times=3),rep("treat",times=3))自己加上分组信息
②这一步是对输入的数据进行修整,为后续作PCA,heaatmap,volcano等图做准备。

class(pd)
dim(pd)
colnames(pd)

group_list=c(rep("Control",times=3),rep("treat",times=3))  
group_list    
save(group_list,file = "step2output.Rdata")

class(pd)

exp[1:4,1:4]   #之前exp为矩阵
dat=as.data.frame(t(exp))    #这一步是将行与列发生了转换
dim(exp)
dim(dat)
dat=cbind(dat,group_list)

第三部分 PCA作图

library(FactoMineR)
library(factoextra)
dat.pca <- PCA(dat[,-ncol(dat)], graph = FALSE)

fviz_pca_ind(dat.pca,
             geom.ind = "point", 
             col.ind = dat$group_list, 
             palette = c("#00AFBB", "#E7B800"),
             addEllipses = TRUE, 
             legend.title = "Groups")

出个PCA图see

PCA

如果你不理解,咱们再看一个:
PCA

说明:
①以上两个PCA图是一样的,需要我们理解的是:
我们做PCA数据的输入文件是dat.pca,而dat.pca是在dat的基础上添加了一列分组信息,所以得到的PCA图中每一个pouint代表一个sample 正如你在图二看到的这样。
②关于PCA的输入数据,注意A-C:
A、PCA作图的输入数据为PCA格式,这一步得到的是dat.pca,是一个list
B、如果要得到dat.pca,可以查看PCA函数。参照函数dat.pca <- PCA(dat[,-ncol(dat)], graph = FALSE)
C、PCA的输入数据为数值型,而经过上一步的数据处理,dat的数据类型为data.frame,并且最后一列为字符串型,所以要将dat的最后一列删除变为数值型。
———————————————————————————————————————

总结制图PCA流程

利用GEO得到eSet[一个大list]

expre提取表达矩阵exp

exp为matrix,转为data.frame(为后续的PCA输入文件)

加分组信息(group_list),在制图PCA命令中添加分组信息,制备差异分组可视化

制作PCA的标准数据形式

制PCA~

———————————————————————————————————————

第四部分 热图

1、做基因方差并挑选差异大的基因(tail()

cg=names(tail(sort(apply(exp,1,sd)),1000)) 
library(pheatmap)
pheatmap(exp[cg,],
         show_colnames = F,
         show_rownames = F) 

Resullt:


heatmap1

该结果显示的热图,差异并不明显。所以需要做归一化处理。

2、理解归一化:
①数据归一化包括数据的中心化和数据的标准化
②归一化化就是要把你需要处理的数据经过处理后(通过某种算法)限制在你需要的一定范围内。首先归一化是为了后面数据处理的方便,其次是保证程序运行时收敛加快;一般选择的数据的范围落在[0,1]之间
②‘A、数据的中心化
所谓数据的中心化是指数据集中的各项数据减去数据集的均值。
例如有数据集1, 2, 3, 6, 3,其均值为3,那么中心化之后的数据集为1-3,2-3,3-3,6-3,3-3,即:-2,-1,0,3,0
B、数据的标准化
所谓数据的标准化是指中心化之后的数据在除以数据集的标准差,即数据集中的各项数据减去数据集的均值再除以数据集的标准差。
例如有数据集1, 2, 3, 6, 3,其均值为3,其标准差为1.87,那么标准化之后的数据集为(1-3)/1.87,(2-3)/1.87,(3-3)/1.87,(6-3)/1.87,(3-3)/1.87,即:-1.069,-0.535,0,1.604,0
③数据中心化和标准化的意义是一样的,为了消除量纲对数据结构的影响。在R语言中可以使用scale方法来对数据进行中心化和标准化。

经验之谈:如果在做运行的过程中,发现前后的代码都一样,只是因为未命名而导致结果出现偏差,请将未命名的一组赋值即可

cg=names(tail(sort(apply(exp,1,sd)),1000)) 
library(pheatmap)
pheatmap(exp[cg,],
         show_colnames = F,
         show_rownames = F) 
n=t(scale(t(exp[cg,])))   #t代表转置,并且转置后的数据类型为matrix
thr=1.5
n[n>thr]=thr
n[n< -thr]= -thr
n[1:4,1:4]
pheatmap(n,show_colnames =F,show_rownames = F)

说明:
thr代表Through hole reflow,这里表示为表达量的范围在1与-1之间 正如thr=1
3、出图(heatmap)
Result:

heatmap2

[注意细节]如果改变thr的值,如thr=2,则result为:
heatmap2

4、加注释分组(annotation_col

ac=data.frame(group=group_list)
rownames(ac)=colnames(n) 
pheatmap(n,show_colnames =F,show_rownames = F,
         annotation_col=ac)

[注意]注释分组ac的内容包括样本号以及group信息
——————————————————————————————————————

绘制热图总结:

对基因求sd

挑选差异大的基因(选择tail())

绘制热图(绘制热图的输入数据为matrix

——————————————————————————————————————

第五部分 箱图

给箱图加分组注释信息

table(group_list)

boxplot(exp[1,]~group_list) 

Result:


boxplot_group list

第六部分 火山图

  library(ggpubr)
  df=data.frame(gene=g,group=group_list)
  p <- ggboxplot(df, x = "group", y = "gene",
                 color = "group", palette = "jco",
                 add = "jitter")
  #  Add p-value
  p + stat_compare_means(label.y = 8)
}


bp(exp[1,])  

Result:


library(limma)
design=model.matrix(~factor(group_list))
fit=lmFit(exp,design)
fit=eBayes(fit)
deg=topTable(fit,coef=2,number = Inf)
head(deg)
deg$logFC <- -(deg$logFC)
bp(exp[rownames(deg)[1],])  ##
bp(exp[rownames(deg)[2],])
library(dplyr)
deg <- mutate(deg,probe_id=rownames(deg)) 

此处要将deg添加一列probe_id,以备后续做基因转换ID

library(HsAgilentDesign026652.db)
#library(hugene10sttranscriptcluster.db)
ls("package:HsAgilentDesign026652.db") 
ids <- toTable(HsAgilentDesign026652SYMBOL)  
head(ids)

注意:
①不同的GPL,会选择不同的包。
②查询GPL有两种方法:A、eSet[[1]]@annotation B、eSet[[1]]
③id转换,查找芯片平台对应的包的网址为:http://www.bio-info-trainee.com/1399.html

ids:


ids

deg:


deg

根据id与deg的共同一列probe_id 将两者合并。

deg <- inner_join(deg,ids,by="probe_id") 
head(deg)

开始绘制火山图的输入数据文件。在上一步的操作中,已经成功匹配出probe_id以及symbol,接下来要根据logFC、p.value对基因匹配up或down。最后,将deg与匹配出的stable、up、down进行合并,进行基因ID转换,因为火山图要以logFC为横坐标,p.value为纵坐标。所以输入文件中必然存在相关信息,输入数据文件完毕。

logFC_t=2
change=ifelse(deg$P.Value>0.01,'stable', 
              ifelse( deg$logFC >logFC_t,'up', 
                      ifelse( deg$logFC < -logFC_t,'down','stable') )
)

deg <- mutate(deg,change)
head(deg)
table(deg$change)
library(ggplot2)
library(clusterProfiler)
library(org.Hs.eg.db)
s2e <- bitr(unique(deg$symbol), fromType = "SYMBOL",    #unique(deg$symbol)去重复
            toType = c( "ENTREZID"),
            OrgDb = org.Hs.eg.db)   #ID转换函数:bitr ,这个步骤会损失一些基因。
head(s2e)
head(deg)
deg <- inner_join(deg,s2e,by=c("symbol"="SYMBOL"))

head(deg)
save(group_list,deg,file = "step4output.Rdata")

绘制火山图


plot(deg$logFC,-log10(deg$P.Value))

Result:


火山图

如你所见,这个火山图很丑。
接下来,对火山图进行修饰与整理:

library(dplyr)
dat <- mutate(deg,v=-log10(P.Value))
head(dat)

library(ggplot2)
ggplot(dat,aes(logFC,v))+
  geom_point()   #aes映射

library(ggpubr)

ggscatter(dat, x = "logFC", y = "v")
ggscatter(dat, x = "logFC", y = "v",size = 0.5)
table(dat$change)

ggscatter(dat, x = "logFC", y = "v",size=0.5,color = "change",palette = c("#FF6347", "#0A0A0A", "#87CEFA"))

Result:


火山图

—————————————————————————————————————

绘制火山图总结:

①制作出符合绘制火山图的输入文件(包含logFC、p.value、基因ID)

②选值方面:设定logFC,P值的大小,从而选择合适的stable、up、down基因

③关于火山图的相关修饰查看帮助文档即可

④绘制火山图

—————————————————————————————————————
关于理解火山图推荐web:
http://www.360doc.com/content/17/0730/23/45852776_675457183.shtml

第七部分 GO、KEGG分析

if(T){
  library(clusterProfiler)
  gene_up= deg[deg$change == 'up','ENTREZID'] 
  gene_down=deg[deg$change == 'down','ENTREZID'] 
  gene_diff=c(gene_up,gene_down)
  gene_all = deg[,'ENTREZID']
  kk.up <- enrichKEGG(gene         = gene_up,
                      organism     = 'hsa',
                      universe     = gene_all,
                      pvalueCutoff = 0.9,
                      qvalueCutoff =0.9)        #核心为 enrichKEGG()
  head(kk.up)[,1:6]
  dim(kk.up)
  kk.down <- enrichKEGG(gene         =  gene_down,
                        organism     = 'hsa',
                        universe     = gene_all,
                        pvalueCutoff = 0.9,
                        qvalueCutoff =0.9)   #qvalueCutoff=1/0.9:所有的富集结果都拿出来
  head(kk.down)[,1:6]
  dim(kk.down)
  kk.diff <- enrichKEGG(gene         = gene_diff,
                        organism     = 'hsa',
                        pvalueCutoff = 0.05)
  head(kk.diff)[,1:6]
  
  class(kk.diff)
  #提取出数据框
  kegg_diff_dt <- kk.diff@result
  
  #根据pvalue来选,用于可视化
  down_kegg <- kk.down@result %>%
    filter(pvalue<0.01) %>%
    mutate(group=-1)
  
  up_kegg <- kk.up@result %>%
    filter(pvalue<0.01) %>%
    mutate(group=1)
  
  #可视化走起
  kegg_plot <- function(up_kegg,down_kegg){
    dat=rbind(up_kegg,down_kegg)
    colnames(dat)
    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 ="-log10Pvalue") +
      coord_flip() + 
      theme_bw()+
      theme(plot.title = element_text(hjust = 0.5))+
      ggtitle("Pathway Enrichment") 
  }
  
  g_kegg <- kegg_plot(up_kegg,down_kegg)
  g_kegg
  
  ggsave(g_kegg,filename = 'kegg_up_down.png')
  
}

#gsea作kegg富集分析
if(F){
  data(geneList, package="DOSE")
  head(geneList)
  length(geneList)
  names(geneList)
  boxplot(geneList)
  boxplot(deg$logFC)
  
  geneList=deg$logFC
  names(geneList)=deg$ENTREZID
  geneList=sort(geneList,decreasing = T)
  
  kk_gse <- gseKEGG(geneList     = geneList,
                    organism     = 'hsa',
                    nPerm        = 1000,
                    minGSSize    = 120,
                    pvalueCutoff = 0.9,
                    verbose      = FALSE)
  head(kk_gse)[,1:6]
  gseaplot(kk_gse, geneSetID = rownames(kk_gse[1,]))
  
  down_kegg<-kk_gse[kk_gse$pvalue<0.05 & kk_gse$enrichmentScore < 0,];down_kegg$group=-1
  up_kegg<-kk_gse[kk_gse$pvalue<0.05 & kk_gse$enrichmentScore > 0,];up_kegg$group=1
  
  g_kegg=kegg_plot(up_kegg,down_kegg)
  print(g_kegg)
  ggsave(g_kegg,filename ='kegg_up_down_gsea.png')
  
}
### 2.GO database analysis 

#go富集分析--耗费时间灰常长,很正常
if(F){
  library(clusterProfiler)
  #输入数据
  gene_up= deg[deg$change == 'up','ENTREZID'] 
  gene_down=deg[deg$change == 'down','ENTREZID'] 
  gene_diff=c(gene_up,gene_down)
  head(deg)
  #**GO分析三大块**
  #以下步骤耗时很长,实际运行时注意把if后面的括号里F改成T
  
  if(F){
    #细胞组分
    ego_CC <- enrichGO(gene = gene_diff,
                       OrgDb= org.Hs.eg.db,
                       ont = "CC",
                       pAdjustMethod = "BH",
                       minGSSize = 1,
                       pvalueCutoff = 0.01,
                       qvalueCutoff = 0.01,
                       readable = TRUE)
    #生物过程
    ego_BP <- enrichGO(gene = gene_diff,
                       OrgDb= org.Hs.eg.db,
                       ont = "BP",
                       pAdjustMethod = "BH",
                       minGSSize = 1,
                       pvalueCutoff = 0.01,
                       qvalueCutoff = 0.01,
                       readable = TRUE)
    #分子功能:
    ego_MF <- enrichGO(gene = gene_diff,
                       OrgDb= org.Hs.eg.db,
                       ont = "MF",
                       pAdjustMethod = "BH",
                       minGSSize = 1,
                       pvalueCutoff = 0.01,
                       qvalueCutoff = 0.01,
                       readable = TRUE)
    save(ego_CC,ego_BP,ego_MF,file = "ego_GPL6244.Rdata")
  }
load(file = "ego_GPL6244.Rdata")
  #**作图**
  #第一种,条带图,按p值从小到大排序
  barplot(ego_CC, showCategory=20,title="EnrichmentGO_CC")
  barplot(ego_BP, showCategory=20,title="EnrichmentGO_BP")
  #如果运行了没出图,就dev.new()
  #第二种,点图,按富集数从大到小的
  dotplot(ego_CC,title="EnrichmentGO_BP_dot")
  
  #保存
  pdf(file = "dotplot_GPL6244.pdf")
  dotplot(ego_CC,title="EnrichmentGO_BP_dot")
  dev.off()
}
#进阶方法,用循环来实现
if(F){
  {
    g_list=list(gene_up=gene_up,
                gene_down=gene_down,
                gene_diff=gene_diff)
    
    if(T){
      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 = 'go_enrich_results.Rdata')
      
    }
    
    
    load(file = '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('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()
      }
    }
  }
}

——————————————————————————————————————

总结GEO分析流程:

总结代码流程:

你可能感兴趣的:([ZHUHAI_Biotrainee]实战_GEO分析)