老大在群里出的題,說感覺這個熱圖很詭異,然后中間我自己沒有用
boxplot
查看數據的表達量,對于數據不能有正確的認識,導致一開始的deg
的logFC都沒有達到正負1
的,最重要的是:1.是因為我知道什么情況下用
log
函數,然后我還在這里面錯誤的用了log
函數;2.不能用
[1:4,1:4]
查看數據集機構;3.
normalizeBetweenArrays
和removeBatchEffect
函數的用處。老大幫助修改了代碼,關于
normalizeBetweenArrays
、removeBatchEffect
和boxplot
的,結果才清晰明了。
原文圖片
下載數據+準備數據
rm(list = ls())
options(stringsAsFactors = F)
library(GEOquery)
eSet1 <- getGEO("GSE83521",
destdir = '.',
getGPL = F)
#(1)提取表達矩陣exp
exp1 <- exprs(eSet1[[1]])
exp1[1:4,1:4]
dim(exp1)
# 一定要看boxplot
boxplot(exp1,las=2)
pd1 <- pData(eSet1[[1]])
#(3)提取芯片平臺編號
gpl1 <- eSet1[[1]]@annotation
save(pd1,exp1,gpl1,file = "step1-1output.Rdata")
load("step1-1output.Rdata")
eSet2 <- getGEO("GSE89143",
destdir = '.',
getGPL = F)
#(1)提取表達矩陣exp
exp2 <- exprs(eSet2[[1]])
exp2[1:4,1:4]
dim(exp2)
boxplot(exp2,las=2)
從上面的箱線圖結果可以看到,數值的表達量并不在同一條水平線上,并且有成敗上千,也有零,很明顯是沒有經過log的。這是需要把數據log后再用boxplot
來看數據的分布,用boxplot
來看數據的分布非常重要。不能僅僅用[1:4,1:4]來查看,因為[1:4,1:4]并不能看到整體的數據情況。關于為什么要log,是因為做差異分析的limma包要求表達矩陣中的數據是經過log的??梢詤⒖祭洗蟮倪@篇:關于limma包差異分析結果的logFC解釋
exp2 = log2(exp2+1)
boxplot(exp2,las=2)
接下來這個函數厲害了,從上面的圖中可以看到有一個樣本的中位數和其他樣本明顯不在一條水平顯示,這個normalizeBetweenArrays
函數,可以把他拉回正常水平,normalizeBetweenArrays只能是在同一個數據集里面使用
。
library(limma)
exp2=normalizeBetweenArrays(exp2)
boxplot(exp2,las=2)
從上面的箱線圖可以看到,exp2的數據的分布基本在一條水平線上。
接下來將exp2的數據保存
#(2)提取臨床信息
pd2 <- pData(eSet2[[1]])
#(3)提取芯片平臺編號
gpl2 <- eSet2[[1]]@annotation
#這些代碼是什么鬼東西,我給你注釋了。
index <- sort.int(pd2$characteristics_ch1,index.return = T)
class(index)
pd2 <- pd2[index$ix,]
exp2 <- exp2[,match(rownames(pd2),colnames(exp2))]
save(pd2,exp2,gpl2,file = "step1-2output.Rdata")
load("step1-2output.Rdata")
探針注釋
## 是同一個平臺,非常棒
gpl2
gpl1
if(T){
library(GEOquery)
gpl<- getGEO('GPL19978', destdir=".")
dim(gpl)
colnames(Table(gpl)) #查一下列明
head(Table(gpl)[,c(1,2)])
ids=Table(gpl)[,c(1,2)]
ids <- ids[-c(1:2),]
ids <- ids[-c(1:13),]
save(ids,file='ids.Rdata')
}
看一下獲得的探針和circ_RNA的對應關系
差異分析-去除批次效應
x1 <- exp1[rownames(exp1) %in% ids$ID,]
x2 <- exp2[rownames(exp2) %in% ids$ID,]
boxplot(x1,las=2)
boxplot(x2,las=2)
cg=intersect(rownames(x1),rownames(x2))
x_merge=cbind(x1[cg,],x2[cg,])
- 又有大招了,得到的這個
merge
后的表達矩陣x_merge
,一定一定要用boxplot
看一下,因為我們是將兩個數據集通過共同的探針合并了,因為是來自兩個數據,所以第一次在實際案例中接觸到了這個高大上的名次-去除批次效應
。 - 那么就
boxplot
來看看!
boxplot(x_merge)
上面這張圖,就是非常明顯的看到了,由于后面的三個樣本就是來自另一個數據集的。從前面的boxplot(exp2)
也可以看到他的表達量在8以上。
- 這樣就需要去除批次效應,參考多種批次效應去除的方法比較
- 但是還需要做一些數據準備
pd1$title
pd2$characteristics_ch1
group_list <- c(rep('tumor',6),rep('normal',6),rep(c('tumor', 'normal'),each=3))
gse <- c(rep('GSE83527',12),rep('GSE89143',6))
table(group_list,gse)
dat <- x_merge
library(sva)
library(limma)
## 使用 limma 的 removeBatchEffect 函數
dat[1:4,1:4]
batch <- c(rep('GSE83521',12),rep('GSE89143',6))
design=model.matrix(~group_list)
ex_b_limma <- removeBatchEffect(dat,
batch = batch,
design = design)
dim(ex_b_limma)
- 這個時候一定要看 boxplot , 不然就白學的了?。。。?!
boxplot(ex_b_limma)
從上面的圖可以看到了,去除了批次效應后,數據的表達水平。
接下來就做差異分析
{
library(limma)
fit=lmFit(ex_b_limma,design)
fit=eBayes(fit)
options(digits = 4)
topTable(fit,coef=2,adjust='BH')
deg=topTable(fit,coef=2,adjust='BH',number = Inf)
}
得到的deg
如下圖
??兩張圖主要是為了看logFC
的值,我第一次把兩個數據全部log并且沒有進行一個normalizeBetweenArrays
來去除樣本間的批次差異,而沒有一個logFC
值是在>1和<-1的。
火山圖
if(T){
nrDEG=deg
head(nrDEG)
attach(nrDEG)
plot(logFC,-log10(P.Value))
library(ggpubr)
df=nrDEG
df$v= -log10(P.Value) #df新增加一列'v',值為-log10(P.Value)
ggscatter(df, x = "logFC", y = "v",size=0.5)
df$g=ifelse(df$P.Value>0.05,'stable', #if 判斷:如果這一基因的P.Value>0.01,則為stable基因
ifelse( df$logFC >1,'up', #接上句else 否則:接下來開始判斷那些P.Value<0.01的基因,再if 判斷:如果logFC >1.5,則為up(上調)基因
ifelse( df$logFC < -1,'down','stable') )#接上句else 否則:接下來開始判斷那些logFC <1.5 的基因,再if 判斷:如果logFC <1.5,則為down(下調)基因,否則為stable基因
)
table(df$g)
df$name=rownames(df)
head(df)
ggscatter(df, x = "logFC", y = "v",size=0.5,color = 'g')
ggscatter(df, x = "logFC", y = "v", color = "g",size = 0.5,
label = "name", repel = T,
#label.select = rownames(df)[df$g != 'stable'] ,
label.select = head(rownames(deg)), #挑選一些基因在圖中顯示出來
palette = c("#00AFBB", "#E7B800", "#FC4E07") )
ggsave('volcano.png')
}
熱圖
- 在畫特圖前,還有一小問題,那么就是這個探針的問題,我們可以看到原文的熱圖上的基因是
hsa-circ-0034398
,而我們id轉換后的表達矩陣的基因名是,如下圖標記所示
學習群里的小伙伴將一個Alias
的對應表格分享到群里,把它讀進R里進行進一步的轉換,文件是ID.txt
。
if(T){
up <- df[df$g=='up',]
down <- df[df$g =='down',]
x <- rbind(up,down)
x$ID <- rownames(x)
#上面是為了提取出差異基因的子集
y <- merge(x,ids,by='ID') #merge函數可以根據兩列共有的內容進行合并,合并后含有共有的行名
ex_b_limma2 <- ex_b_limma[match(y$ID,rownames(ex_b_limma)),]
rownames(ex_b_limma2) <- y$circRNA
#上面的函數寫的不咋好,命名變量不好命名,需要得到結果后看一下
z <- read.csv('ID.txt',sep = '\t')
tmp1 <- z[z$circRNA %in% rownames(ex_b_limma2),]
ex_b_limma3 <- ex_b_limma2[match(tmp1$circRNA,rownames(ex_b_limma2)),]
rownames(ex_b_limma3) <- tmp1$Alias
library(pheatmap)
pheatmap(ex_b_limma3,show_colnames =T,show_rownames = T)
n=t(scale(t(ex_b_limma3)))
n[n>2]=2
n[n< -2]= -2
n[1:4,1:4]
pheatmap(n,show_colnames =F,show_rownames = F)
ac=data.frame(SampleType=group_list,#這步就是可以實現兩個分組了
GeoDatabase=gse)
rownames(ac)=colnames(n) #將ac的行名也就分組信息 給到n的列名,即熱圖中位于上方的分組信息,這步很重要
pheatmap(n,show_colnames =T,
show_rownames = T,
cluster_cols = F,
annotation_col=ac,
fontsize = 8,
filename = 'deg-heatmap.png') #列名注釋信息為ac即分組信息
}
重要的如下:
1.理解
boxplot
的重要性,來看數據集是否需要log,以便后面才能用limma包進行差異分析2.
normalizeBetweenArrays
只能是在同一個數據集里面用來去除樣本的差異,不同數據集需要用limma 的removeBatchEffect
函數去除批次效應。