萌新学完GEO课程复现SCI文章差异基因的热图

文章标题是:Tinagl1 Suppresses Triple-Negative Breast Cancer Progression and Metastasis by Simultaneously Inhibiting Integrin/FAK and EGFR Signaling .

菜鸟一枚,所以现在只是复现这篇文章里的B图;C图里的通路GO/KEGG注释及A图中的GSEA下回分解🙃 (感觉任重而道远)

从文章中,我们找到GSE号

All microarray data generated in this study have been deposited as a superseries at the NCBI Gene Expression Omnibus with the accession code GSE99507, and can be accessed at https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE99507.

点开,看到如下分组,这里面的分组信息先留个悬念

<从下面开始,跟着老大的哔哩哔哩GEO挖掘视频一步一步走>

1. 现在我们需要找到这个GSE号对应的GPL平台,然后找到这个GPL平台所对应的注释R包

老大GEO视频中一闪而过的文章是:从GEO数据库下载得到表达矩阵 一文就够

现在我们需要通这个GPL平台找到对应的注释R包然后找到下面这个包装函数的板块,截图如下:

图片中是老大已经包装好的函数,我们这次要下载的GSE号是99507,因此在R里代码框输入下面即可,如图:

得到当前GSE号所对应的芯片平台,如下图:即GPL17077.

这个时候,我们需要非常熟悉这个对象哦

我们也可以在GEO网站上看到平台信息是这样的,截图如下

接下来,因此我们可以去老大的搜集贴找对应关系,参考老大的这篇文章:(16)芯片探针与基因的对应关系-生信菜鸟团博客2周年精选文章集,截图如下:

从以上列表中,用GPL17077去找对应的注释包,发现没有。(老大已经总结地很全了,但是依然有些GPL平台是没有注释包或者是有我们没有找到。)

而老大GEO视频里的GPL平台其实是有注释R包的,就是下图中的这个hgu95av2.db,视频中老大从R语言20练习题里有关于ID转换的代码,如下图:

总之,现在的GPL17077平台现在并没有对应的注释R包,当然更不是视频中的这个hgu95av2.db了。为了能继续跟着按照老大视频中讲的继续做,我去Google搜索,用的是前面在GEO网站里GPL平台对应的平台信息,前面也有截图,如下

Google找的说是这个hgug4110b.db的注释R包,其实在老大总结里这个包对应的是GPL887平台,但是我想还是试试,于是我尝试了下载下,代码如下啦

# 首先我下载了一个错误的包
BiocManager::install('hgug4110b.db')
library('hgug4110b.db')
?hgug4110b
ls("package:hgug4110b.db")

#下面这段很眼熟,就是我上面在R语言20题里的截图,我把视频中的hgu95av2.db包换成我在谷歌搜索到的hgug4110b.db包
library('hgug4110b.db')
ids=toTable(hgug4110bSYMBOL)
length(unique(ids$symbol))
tail(sort(table(ids$symbol)))
table(sort(table(ids$symbol)))
plot(table(sort(table(ids$symbol))))

exprSet<-dat
table(rownames(exprSet) %in% ids$probe_id)
dim(exprSet)
exprSet=exprSet[rownames(exprSet) %in% ids$probe_id,]
dim(exprSet)

ids=ids[match(rownames(exprSet),ids$probe_id),]
head(ids)
exprSet[1:5,1:5]
tmp = by(exprSet,ids$symbol,
         function(x) rownames(x)[which.max(rowMeans(x))] )
probes = as.character(tmp)
exprSet=exprSet[rownames(exprSet) %in% probes ,]
dim(exprSet)
#写一个函数,可以之间过滤掉其他探针并且进行ID转换,
#此时的id转换是用bioconductor包来转换的,如果下载的matrix,则不用转换
jimmy <- function(exprSet,ids){
                             tmp = by(exprSet,
                             ids$symbol,
                              function(x) rownames(x)[which.max(rowMeans(x))] )
                probes = as.character(tmp)
                print(dim(exprSet))
                exprSet=exprSet[rownames(exprSet) %in% probes ,]
                print(dim(exprSet))
                return(exprSet)
}
new.exprSet <- jimmy(exprSet,ids)

#此时会报错,因为现在的exprSet和ids的长度不一样

由于expeSet里的ID能在ids里对应的很少,大部分都是对应不上的,如下图

对应上的基因数TRUE只有8190,因此我认为我谷歌到的这个hgug4110b.db并不对。

不过==没关系==鼓起勇气,继续探索

而且老大视频里又给了找不到对应的注释R包时,通过下面的代码来实现探针名和基因名的对接,代码网址:https://github.com/jmzeng1314/my-R/blob/master/9-microarray-examples/E-MTAB-3017.R

#代码如下
gpl <- getGEO('GPL17077', destdir=".")
colnames(Table(gpl)) 
head(Table(gpl)[,c(1,6,7)])  ## you need to check this , which column do you need 
write.csv(Table(gpl)[,c(1,6,7)],"GPL17077.csv")
ids=read.csv('GPL17077.csv')
#这样我们就同样获得了探针对应基因的表达矩阵啦

前面我所认为的第一步刚刚结束了,获得了探针对应基因的表达矩阵

2.下载数据,获得分组信息

下载数据:老大在视频里讲了三种找到数据集后的数据下载方式,我简单罗列如下(目的得到表达矩阵):

1.直接下载raw data,但不推荐大家用,原始数据

2.下载表达矩阵 series matrix file(s),下载后可读到R里面,考验网速

a=read.table('GSE42872_series_matrix.txt.gz')
> class(a)
[1] "data.frame"
> str(gset)

3.在R里面读取GSE号.

gset <- getGEO("GSE42589")

加载GEO包下载

library(GEOquery)
gset <- getGEO('GSE42872',destdir=".",AnnotGPL = F,getGPL = F)

老大推荐第三种方式,下面是代码

# 就这么来就对了,没毛病
###step1-downloadR
rm(list = ls())  ## 魔幻操作,一键清空~
options(stringsAsFactors = F)
# 注意查看下载文件的大小,检查数据 
f='GSE99507_eSet.Rdata'

library(GEOquery)
# 这个包需要注意两个配置,一般来说自动化的配置是足够的。
#Setting options('download.file.method.GEOquery'='auto')
#Setting options('GEOquery.inmemory.gpl'=FALSE)
if(!file.exists(f)){
  gset <- getGEO('GSE99507', destdir=".",
                 AnnotGPL = F,     ## 注释文件
                 getGPL = F)       ## 平台文件
  save(gset,file=f)   ## 保存到本地
}
load('GSE99507_eSet.Rdata')  ## 载入数据
class(gset)
length(gset)
class(gset[[1]])
# 因为这个GEO数据集只有一个GPL平台,所以下载到的是一个含有一个元素的list
a=gset[[1]]
dat=exprs
dim(dat)
#  GPL3921  [HT_HG-U133A] Affymetrix HT Human Genome U133A Array
# Bioconductor - hgu133a.db
dat[1:4,1:4]

pd=pData(a) #获得分组信息,就得到了前面一张截图,即前面悬念的解答处-GSE号对应的Samples分组信息,主要是根据文章里的那个截图的分组信息来对字符串进行拆分(str_split)和替换(str_replace)
library(stringr)
group_list = trimws(str_split(pd$title,' ',simplify = T)[,5])#拆分
group_list = str_replace(group_list,'LM2','Vector')
table(group_list)
save(dat,group_list,file = 'step1-output.Rdata')
#此时,要注意保存的这个文件step1-output.Rdata,我们要知道此时的dat表达矩阵是什么样的

3.ID转换

###step2-ids-filter.R

rm(list = ls())  ## 魔幻操作,一键清空~
options(stringsAsFactors = F)
load('step1-output.Rdata')
gpl <- getGEO('GPL17077', destdir=".")
colnames(Table(gpl)) ## [1] 41108    17
head(Table(gpl)[,c(1,7)])  ## you need to check this , which column do you need 
write.csv(Table(gpl)[,c(1,7)],"GPL17077.csv")
ids=read.csv('GPL17077.csv')
ids=ids[,-1]
dat[1:4,1:4] 
rownames(dat)

#如前所述,现在没有这个平台对应的注视R包,所以下面是根据下载的dat和ids来进行的ID转换步骤
ids[ids$GENE_SYMBOL!='',]
ids=ids[ids$GENE_SYMBOL!='',]
match(rownames(dat),ids$ID)
ids[match(rownames(dat),ids$ID),]
ids=ids[match(rownames(dat),ids$ID),]
ids=ids[complete.cases(ids),]
dat=dat[ids$ID,]

#下面是针对那些有多个基因去重的步骤,注意理解为什么要取median(中位数),巧妙
ids$median=apply(dat,1,median)
ids=ids[order(ids$GENE_SYMBOL,ids$median,decreasing = T),]
ids=ids[!duplicated(ids$GENE_SYMBOL),]
dat=dat[ids$ID,]
rownames(dat)=ids$GENE_SYMBOL
dat[1:4,1:4]  
dim(dat)

save(dat,group_list,file = 'step2-output.Rdata')

#此时此时,要注意保存的这个文件step2-output.Rdata,我们要知道此时的dat表达矩阵是什么样的

4.PCA和Heatmap

###step3-pca-heatmap

##PCA主成分分析

(list = ls())  ## 魔幻操作,一键清空~
options(stringsAsFactors = F)
load(file = 'step1-output.Rdata')
# 每次都要检测数据
dat[1:4,1:4]
## 下面是画PCA的必须操作,需要看说明书。
dat=t(dat)
dat=as.data.frame(dat)
dat=cbind(dat,group_list)
library("FactoMineR")
library("factoextra") 
# The variable group_list (index = ) is removed
# before PCA analysis
dat.pca <- PCA(dat[,-ncol(dat)], graph = FALSE)
fviz_pca_ind(dat.pca,repel =T,
             #geom.ind = "point", # show points only (nbut not "text")
             col.ind = dat$group_list, # color by groups
             palette = c("#00AFBB", "#E7B800"),
             addEllipses = TRUE, # Concentration ellipses
             legend.title = "Groups"
)

##热图:heatmap-sd

rm(list = ls())  ## 魔幻操作,一键清空~
options(stringsAsFactors = F)
load(file = 'step1-output.Rdata')
# 每次都要检测数据
dat[1:4,1:4]
cg=names(tail(sort(apply(dat, 1, sd)),1000))
library(pheatmap)
pheatmap(dat[cg,],show_colnames =F,show_rownames = F)
rowMeans(dat[,1:3]) -  rowMeans(dat[,4:6]) 
cg1=names(tail(sort(rowMeans(dat[,1:3]) -  rowMeans(dat[,4:6]) ),500))
cg2=names(head(sort(rowMeans(dat[,1:3]) -  rowMeans(dat[,4:6]) ),500))
cg=c(cg1,cg2)
n=t(scale(t(dat[cg,])))
n[n>2]=2
n[n< -2]= -2
n[1:4,1:4]
pheatmap(n,show_colnames =F,show_rownames = F)
ac=data.frame(g=group_list)
rownames(ac)=colnames(n)
pheatmap(n,show_colnames =F,
         show_rownames = F,
         cluster_cols = F,
         annotation_col=ac)

5.差异分析

##step4-DEG
rm(list = ls())  ## 魔幻操作,一键清空~
options(stringsAsFactors = F)
load(file = 'step2-output.Rdata')######要知道此时是step2中的dat哦
# 每次都要检测数据
dat[1:4,1:4]
table(group_list)

##boxplot图
boxplot(dat[1,]~group_list)
t.test(dat[1,]~group_list)
bp=function(g){
  library(ggpubr)
  df=data.frame(gene=g,stage=group_list)
  p <- ggboxplot(df, x = "stage", y = "gene",
                 color = "stage", palette = "jco",
                 add = "jitter")
  #  Add p-value
  p + stat_compare_means()
}
bp(dat[1,])
bp(dat[2,])
bp(dat[3,])
bp(dat[4,])

##DEG-limma包

library(limma)
design=model.matrix(~factor( group_list ))
fit=lmFit(dat,design)
fit=eBayes(fit)
options(digits = 4)
#topTable(fit,coef=2,adjust='BH') 
topTable(fit,coef=2,adjust='BH')
bp(dat['KLK10',])
bp(dat['FXYD3',])
deg=topTable(fit,coef=2,adjust='BH',number = Inf)

head(deg) 
save(deg,file = 'deg.Rdata')

## for volcano 
if(T){
  nrDEG=deg
  head(nrDEG)
  attach(nrDEG)
  plot(logFC,-log10(P.Value))
  library(ggpubr)
  df=nrDEG
  df$v= -log10(P.Value)
  ggscatter(df, x = "logFC", y = "v",size=0.5)

df$g=ifelse(df$P.Value>0.01,'stable',
              ifelse( df$logFC >1.5,'up',
                      ifelse( df$logFC < -1.5,'down','stable') )
  )
  table(df$g)#此时获得的上调基因为20,下调基因为145
  df$symbol=rownames(df)
  ggscatter(df, x = "logFC", y = "v",size=0.5,color = 'g')
  ggscatter(df, x = "logFC", y = "v", color = "g",size = 0.5,
            label = "symbol", repel = T,
            #label.select = rownames(df)[df$g != 'stable'] ,
            label.select = rownames(head(head(deg))),
            palette = c("#00AFBB", "#E7B800", "#FC4E07") )

ggscatter(df, x = "AveExpr", y = "logFC",size = 0.2)
  df$p_c = ifelse(df$P.Value<0.001,'p<0.001',
                  ifelse(df$P.Value<0.01,'0.001<p<0.01','p>0.01'))
  table(df$p_c )
  ggscatter(df,x = "AveExpr", y = "logFC", color = "p_c",size=0.2, 
            palette = c("green", "red", "black") )

}

## 热图:for heatmap 
rm(list = ls())  ## 魔幻操作,一键清空~
options(stringsAsFactors = F)
if(T){ 
  load(file = 'step2-output.Rdata')
  # 每次都要检测数据
  dat[1:4,1:4]
  table(group_list)
  load(file = 'deg.Rdata')
  x=deg$logFC
  names(x)=rownames(deg)
  cg=c(names(head(sort(x),20)),#老大的代码中是100、100,由于我获得上下调基因少,就改了 
       names(tail(sort(x),145)))
  library(pheatmap)
  pheatmap(dat[cg,],show_colnames =F,show_rownames = F)
  n=t(scale(t(dat[cg,])))
  n[n>2]=2
  n[n< -2]= -2
  n[1:4,1:4]
  pheatmap(n,show_colnames =F,show_rownames = F)
  ac=data.frame(g=group_list)
  rownames(ac)=colnames(n)
  pheatmap(n,show_colnames =F,
           show_rownames = F,
           cluster_cols = F,
           annotation_col=ac)

}

到这里就差不多结束了,基本得到和文章中差不多的热图。还有很多做图技巧需要慢慢学习。其中的代码均从老大那copy过来的,需要边做边理解,注意每一步变量的变化,以不变应万变,这点很重要哇。

十分<感谢老大>的指导和帮助,第一次做到这里,很开心哇~🤗

(0)

相关推荐