使用不同方法规一化、PCA和批次效应矫正的差异

目录

1)规一化表达矩阵

转录组差异表达分析时,需要对表达矩阵进行规一化。比较常用的方法有log2和DESeq2包的vst和rlog方法。那么它们有什么不一样呢?我们拿DESeq2的示例数据进行比较。

library(RNAseqFlow)
library(DESeq2)
library(corrplot)
input <- createCountPhe() # 得到表达矩阵和表型信息
expr <- input[[1]]
phe <- input[[2]]
dds <- create_DEseq(count_data=expr,col_data=phe,design_names = "condition+type",group_name ="condition",ref_level = "untreated") # 创建DESeqDataSet对象

## [1] "The id order between gene count file and phenotype file is identical without modification!"

dds

## class: DESeqDataSet 
## dim: 10089 7 
## metadata(1): version
## assays(4): counts mu H cooks
## rownames(10089): FBgn0000008 FBgn0000017 ... FBgn0261574 FBgn0261575
## rowData names(26): baseMean baseVar ... deviance maxCooks
## colnames(7): treated1 treated2 ... untreated3 untreated4
## colData names(3): condition type sizeFactor

norm <- log2(expr+1) #直接用log2进行规一化
norm[1:5,1:5]

##              treated1  treated2  treated3 untreated1 untreated2
## FBgn0000008  7.139551  6.475733  6.149747   6.539159   7.339850
## FBgn0000017 12.599448 11.585432 11.703471  12.187661  13.089285
## FBgn0000018  9.497852  8.228819  8.271463   9.189825   9.573647
## FBgn0000024  3.459432  3.000000  2.584963   3.459432   3.584963
## FBgn0000032 10.730470  9.445015  9.566054  10.498849  10.743151

ntd <- normTransform(dds) # DESeq中的函数
assay(ntd)[1:5,1:5]

##              treated1  treated2  treated3 untreated1 untreated2
## FBgn0000008  6.436242  6.865379  6.410556   6.354468   6.504519
## FBgn0000017 11.889798 11.978840 11.967612  12.000870  12.247040
## FBgn0000018  8.789322  8.621190  8.534895   9.003332   8.732772
## FBgn0000024  2.830673  3.349813  2.808365   3.290618   2.834907
## FBgn0000032 10.021212  9.838041  9.829949  10.312153   9.901443

normalized_counts = counts(dds, normalized=TRUE) 
ntd1 = log2(normalized_counts+1)
ntd1[1:5,1:5]

##              treated1  treated2  treated3 untreated1 untreated2
## FBgn0000008  6.436242  6.865379  6.410556   6.354468   6.504519
## FBgn0000017 11.889798 11.978840 11.967612  12.000870  12.247040
## FBgn0000018  8.789322  8.621190  8.534895   9.003332   8.732772
## FBgn0000024  2.830673  3.349813  2.808365   3.290618   2.834907
## FBgn0000032 10.021212  9.838041  9.829949  10.312153   9.901443

rld <- rlog(dds, blind=FALSE) # DESeq中的函数
assay(rld)[1:5,1:5]

##              treated1  treated2  treated3 untreated1 untreated2
## FBgn0000008  6.499251  6.678569  6.494630   6.469361   6.527893
## FBgn0000017 11.933399 12.001811 11.993193  12.018453  12.208070
## FBgn0000018  8.758693  8.649608  8.594954   8.900817   8.721092
## FBgn0000024  2.679631  2.713855  2.679046   2.712598   2.679846
## FBgn0000032  9.998801  9.867264  9.861304  10.211745   9.911647

vsd <- vst(dds, blind=FALSE) # DESeq中的函数
assay(vsd)[1:5,1:5]

##              treated1  treated2  treated3 untreated1 untreated2
## FBgn0000008  8.005828  8.192922  7.995328   7.972665   8.034115
## FBgn0000017 11.968753 12.053246 12.042577  12.074190  12.309219
## FBgn0000018  9.322821  9.204951  9.145817   9.477809   9.282788
## FBgn0000024  7.105652  7.182429  7.102606   7.173068   7.106233
## FBgn0000032 10.283202 10.130746 10.124080  10.531172  10.183179

sample <- cbind(log2=norm[,1],ntd=assay(ntd)[,1],rld=assay(rld)[,1],vsd=assay(vsd)[,1])
corr <- cor(sample,use="pairwise.complete.obs")
corrplot(corr, order = "original", type = "upper", mar=c(1,5,5,1),tl.pos="n")
corrplot(corr, add = TRUE, type = "lower", method = "number", order = "original", 
         tl.pos="full",cl.pos="n")

从数值来看,不同方法相差不大。从相关性来看,不同方法规一化的数据差异也不大,以第一个样本为例,相关性都达到0.94以上。因此,不同规一化方法差别不是特别大,选择其中一个就好。

不同方法的运行速度:

  • log2 方法最简单,最方便。
  • normTransform 与log2类似,但是它会先进行size factor的规一化再log2。需要首先转成DESeqDataSet类。
  • rlog 速度比较慢。需要首先转成DESeqDataSet类。
  • vst是rlog的快速版。需要首先转成DESeqDataSet类。

2)PCA 展示

如果输入数据是DESeqDataSet类,可以使用plotPCA进行展示:

plotPCA(ntd,intgroup=c("condition"))

plotPCA(rld,intgroup=c("condition"))

plotPCA(vsd,intgroup=c("condition"))

如果是log2的结果,可以用plot_PCA展示:

library(bioTools)
library(ggplot2)
plot_PCA(t(norm),phe=input[[2]],group = "condition")

plot_PCA是bioTools包的函数,可用devtools::install_github("Feng-Zhang/bioTools")进行安装。 plot_PCA会使用prcomp函数计算距离矩阵,再用ggplot2画图。prcomp函数的输入文件是data.frame(n*m),行(n)为样本,列(m)为多维变量。prcomp会将多维变量降维到n维。 注意如果mat是没有规一化的数据,需要设置其中的参数scale=T,将数据进行规一化。

可以看到rlog和vst的结果是类似的,且比normTransform方法好,因为PC1和PC2加起来解释的方差更大。而log2方法的效果也很不错。因此:

  • 如果使用DESeq2进行相关分析时,推荐使用vst方法。
  • 如果输入文件是一般的表达矩阵,用log2的方法也是不错的选择,不用费劲地转成DESeqDataSet类。
  • 用plot_PCA可以方便地画PCA图。它是用ggplot2画的,返回的结果还可以用ggplot2进一步优化。

3)查看批次效应

我们一般用PCA方法来看样本间是否有批次效应。 本例中condition是我们关注的因素,但是type不是,它是指不同测序平台类型。我们不希望不同平台的数据对我们所关注的因素造成影响,即不希望不同平台的测序结果有系统性差异。因此可以先用PCA方法查看type对样本的影响。

plotPCA(ntd,intgroup=c("type"))

plotPCA(rld,intgroup=c("type"))

plotPCA(vsd,intgroup=c("type"))

plot_PCA(t(norm),phe=input[[2]],group="type")

我们看到所有方法的规一化数据都表明,不同type之间的样本有明显的差别,即存在显著的批次效应。

4)矫正批次效应

1. 用limma去除批次效应

model <-  model.matrix(~condition, colData(dds))
mat <- limma::removeBatchEffect(assay(ntd), ntd$type,design = model)
assay(ntd) <- mat
plotPCA(ntd,intgroup=c("condition"))

plotPCA(ntd,intgroup=c( "type"))

mat <- limma::removeBatchEffect(assay(rld), rld$type,design = model)
assay(rld) <- mat
plotPCA(rld, intgroup=c("condition"))

plotPCA(rld, intgroup=c( "type"))

mat <- limma::removeBatchEffect(assay(vsd), vsd$type,design = model)
assay(vsd) <- mat
plotPCA(vsd, intgroup=c("condition"))

plotPCA(vsd, intgroup=c("type"))

可以看到样本可以被condition分开,但不能被type分开,表明矫正成功。

2. 用ComBat去除批次效应

library(sva)
model <- model.matrix(~condition,data = phe)
clean_norm <- norm[rowSums(norm)>1 & rowMedians(norm)>1,]
adjusted_expr <- ComBat(dat = clean_norm, batch = as.character(phe$type))

## Found 33 genes with uniform expression within a single batch (all zeros); these will not be adjusted for batch.

plot_PCA(t(adjusted_expr),phe=phe,group = "condition")

plot_PCA(t(adjusted_expr),phe=phe,group = "type")

注意ComBat的输入文件是过滤且规一化的数据,不能是原始count。

相关