基因芯片批次效應處理

由于實驗人員、技術、環境、時間點、芯片處理等各種因素原因,得到的芯片表達矩陣是含有非生物學因素差異的。
有時候想分析兩組間差異,但是一個數據集下面的樣本數量略少,因此想整合多個樣本的數據進行大樣本分析。但是在一個數據集里面,即使是統一平臺的芯片數據之間都是有批次效應和偏差的,整合在一起就更加放大了。(對于seq數據來說好像影響沒這么大,TPM、FPKM等歸一方法效果拔群,因此經常有TCGA+GTEx的聯合分析)
這里記錄芯片數據的批次效應及多數據集整合。參考資料包括:http://www.lxweimin.com/p/454fbb13af28http://www.lxweimin.com/p/d4ff373d3d3fhttp://www.lxweimin.com/p/dce79ecf52eahttps://blog.csdn.net/yayiling/article/details/113664434
有一篇18年的sci report,用的sva來batch normalize,一言難盡,這真的能篩出來嗎?anyway,先記錄,再比較,看結果。(也許包的功能很好,只是文章讓人懷疑)

什么是批次效應?

Leek et. al (2010) define batch effects as follows: Batch effects are sub-groups of measurements that have qualitatively different behaviour across conditions and are unrelated to the biological or scientific variables in a study. For example, batch effects may occur if a subset of experiments was run on Monday and another set on Tuesday, if two technicians were responsible for different subsets of the experiments, or if two different lots of reagents, chips or instruments were used.
批次效應是測量時在條件間有質量差別行為的,在實驗中與生物學或科學變量不相關的一小群。舉個例子,如果一部分實驗在周一進行,另一部分在周二進行,批次效應可能發生。或者兩個技術員分別做同一實驗的不同部分,或者使用了不同的試劑、芯片或者使用手冊都會參數batch effect。

如何判斷批次效應?

1、數據集種明確說明
2、Boxplot圖
3、聚類樹
4、PCA分析
下面代碼節選自JIMMY的教程,有興趣的可以自行學習

## hclust
  colnames(exprSet)=paste(group_list,1:ncol(exprSet),sep='_')
  # Define nodePar
  nodePar <- list(lab.cex = 0.6, pch = c(NA, 19),
                  cex = 0.7, col = "blue")
  hc=hclust(dist(t(exprSet)))
  par(mar=c(5,5,5,10))
  png('hclust.png',res=120)
  plot(as.dendrogram(hc), nodePar = nodePar, horiz = TRUE)
  dev.off()
   ## PCA
  library(ggfortify)
  df=as.data.frame(t(exprSet))
  df$group=group_list
  png('pca.png',res=120)
  autoplot(prcomp( df[,1:(ncol(df)-1)] ), data=df,colour = 'group',frame.type = 'norm')+theme_bw()
  dev.off()

芯片數據的處理

1.批次效應不能被消除,只有盡可能的降低。
2.是否會矯枉過正?
① 聯合分析正常組為一個數據集(一種芯片);
② 實驗組為另一個數據集(另一種芯片);
批次因素和分組因素可能重疊,所以直接對原數據矯正批次可能會抵消一部分真實生物學因素
3.使用removeBatchEffect (limma) 或者ComBat (sva) 函數后得到的表達數據,僅可用于銜接可視化(如聚類、PCA等),可視化展示,不能將去批次后的數據用于差異分析!
問:那我去批次效應整合數據集有什么意義呢?
4.如果想要在鑒定差異基因的過程中降低批次效應,將批次加入到design中

情況1 【數據集(1個)明確給出批次效應】

使用sva包的ComBat函數
有些GEO數據里面包含了實驗的批次,就可以用這個包來去除。

情況2 【數據集(1個)壓根沒提批次效應】

僅判斷是否需要log2和normalization
使用limma包中normalizeBetweenArrays函數 (僅在同一個數據集里面使用)

boxplot(rt)
rt <- normalizeBetweenArrays(rt)
boxplot(rt)

問:這些所謂的去除批次效應的方法,和quantile normalization的區別在哪里呢?是否目的是一致的?

情況3 【多數據集合并】

##########################合并數據#########################
#了解到芯片數據每個都平臺保留的基因不一樣,要全都有的才留下
#setwd('path_to_data_you_download')
files <- unlist(lapply(strsplit(list.files(pattern = 'matrix'),'_'),function(x) {x[[1]]}))
exprslist <- list()
pdatalist <- list()
count <- c()
for (i in files){
  #批量生成數據框
  #assign(paste0(i,'_exprs'),read.table(paste0(i,'_matrix.txt'),sep='\t',row.names = 1))
 #assign(paste0(i,'_exprs'),mutate(get(paste0(i,"_exprs")),ID=rownames(get(paste0(i,"_exprs")))))
 #生成一個列表
  rt <- read.table(paste0(i,'_matrix.txt'),sep='\t',row.names = 1)
  count <- c(count,ncol(rt))
  rt <- as.data.frame(normalizeBetweenArrays(rt))
  rt$ID <- rownames(rt)
  exprslist[[i]] <- rt
  #assign(paste0(i,'_pdata'),read.delim(paste0(i,'_pdata.txt'),sep='\t',row.names = NULL))
  rt <- read.delim(paste0(i,'_pdata.txt'),sep='\t',row.names = NULL)
  pdatalist[[i]] <- rt
  }
rm(rt)
in_jo <- function(x,y){
  inner_join(x,y,by='ID')
}
merged_exprs <- Reduce(in_jo,exprslist)
rownames(merged_exprs) <- merged_exprs$ID
merged_exprs <- select(merged_exprs,-ID)
#有些行里面包含了na,需要去掉
merged_exprs <- merged_exprs[complete.cases(merged_exprs),]
Listrb <- function(x,y){
  rbind(x,y)
}
merged_pdata<- Reduce(Listrb,pdatalist)
merged_pdata$group <- ifelse(grepl('Primary',merged_pdata$title),'Primary','Metastasis')
rm(exprslist,pdatalist,i,in_jo,Listrb)
#最終我們得到了合并后的exprs和pdata,可以用來batch了,count包含每個batch的數量   

(1)可去除:使用sva包/limma包;

①limma包removeBatchEffect函數

library(limma)
boxplot(merged_exprs)
batch <- rep(files,times=count)
batch <- as.factor(batch)
rm(files,count)
design <- model.matrix(~0 + batch)
batchremove_limma <- removeBatchEffect(merged_exprs,
                                batch = batch)
boxplot(batchremove_limma)

library(ggfortify)
limma <- as.data.frame(t(batchremove_limma))
limma$group <- merged_pdata$group
limma$batch <- batch
autoplot(prcomp(limma[,1:(ncol(originaldata)-2)] ), 
         data=limma,colour = 'group',
         frame.type = 'norm')+
  theme_bw()
autoplot(prcomp(limma[,1:(ncol(originaldata)-2)] ), 
         data=limma,colour = 'batch',
         frame.type = 'norm')+
  theme_bw()

②sva包ComBat函數

library(sva)
batchremove_combat <- ComBat(dat = as.matrix(merged_exprs), batch = batch)
boxplot(batchremove_combat)

③MatchMixeR

(2)不可去除:RobustRankAggreg包整合分析

RobustRankAggreg不再需要合并原始數據,只需要按照流程得到每個數據集的差異表達基因,按照logFC從大到小的順序排列好即可。

padj=0.05
logFC=1

if(TRUE){
files=list.files()
upList=list()
downList=list()
allFCList=list()

for(i in 1:length(files)){
  inputFile=files[i]
  rt=read.table(inputFile,header=T,sep = '\t') # 注意文件讀取
  rt <- rt[order(rt$logFC),]
  header=unlist(strsplit(unlist(strsplit(inputFile,"_"))[[2]],".txt"))# 新數據需要修改
  downList[[header[1]]]=as.vector(rt[,1])
  upList[[header[1]]]=rev(as.vector(rt[,1]))
  fcCol=rt[,1:2]
  colnames(fcCol)=c("Gene",header[[1]])
  allFCList[[header[1]]]=fcCol
}

rm(fcCol,rt,files,header,i,inputFile)

mergeLe=function(x,y){
  merge(x,y,by="Gene",all=T)}
newTab=Reduce(mergeLe,allFCList)
#newTab = na.omit(newTab) 
newTab <- newTab[!duplicated(newTab$Gene),]
rownames(newTab)=newTab[,1]
newTab=newTab[,2:ncol(newTab)]
newTab[is.na(newTab)]=0
}

library(RobustRankAggreg)
if(TRUE){
upMatrix = rankMatrix(upList)
#upMatrix = rankMatrix(upList,full=T)

upAR = aggregateRanks(rmat=upMatrix)
colnames(upAR)=c("Name","Pvalue")
upAdj=p.adjust(upAR$Pvalue,method="bonferroni")#
upXls=cbind(upAR,adjPvalue=upAdj)
upFC=newTab[as.vector(upXls[,1]),]
upXls=cbind(upXls,logFC=rowMeans(upFC))

#write.table(upXls,file="up.xls",sep="\t",quote=F,row.names=F)
upSig=upXls[(upXls$adjPvalue<padj & upXls$logFC>logFC),]
#upSig=upXls[ upXls$logFC>logFC,]
#write.table(upSig,file="upSig.xls",sep="\t",quote=F,row.names=F)

downMatrix = rankMatrix(downList)
#downMatrix = rankMatrix(downList,full=T)

downAR = aggregateRanks(rmat=downMatrix)
colnames(downAR)=c("Name","Pvalue")
downAdj=p.adjust(downAR$Pvalue,method="bonferroni")
downXls=cbind(downAR,adjPvalue=downAdj)
downFC=newTab[as.vector(downXls[,1]),]
downXls=cbind(downXls,logFC=rowMeans(downFC))
#write.table(downXls,file="down.xls",sep="\t",quote=F,row.names=F)

downSig=downXls[(downXls$adjPvalue<padj & downXls$logFC< -logFC),]
#downSig=downXls[downXls$logFC< -logFC,]

#write.table(downSig,file="downSig.xls",sep="\t",quote=F,row.names=F)

allSig = rbind(upSig,downSig)
colnames(allSig)
allSig = allSig[,c("Name","logFC")]
#write.table(allSig,file = 'allSign.xls',sep = '\t',quote = F)
}

hminput=newTab[c(as.vector(upSig[1:20,1]),as.vector(downSig[1:20,1])),]

library(pheatmap)
pheatmap(hminput,display_numbers = TRUE,
         fontsize_row=10,
         fontsize_col=12,
         color = colorRampPalette(c("green", "white", "red"))(50),
         cluster_cols = FALSE,cluster_rows = FALSE, )

write.table(downSig,sep='\t',quote=F,row.names = F,file='downSig.txt')
write.table(upSig,sep='\t',quote=F,row.names = F,file='upSig.txt')

總結

本文以代碼形式提供了整合芯片數據獲得差異基因的幾種方法,具體的算法流程需要各位親自理解和摸索(因為我也不會)

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,578評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,701評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,691評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,974評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,694評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,026評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,015評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,193評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,719評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,442評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,668評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,151評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,846評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,255評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,592評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,394評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,635評論 2 380

推薦閱讀更多精彩內容