理解 Quntile Normalization
每一次技术重复的时候,都会有误差,芯片的原始数据是由仪器读取的,不同的读取时间,或者扫描仪光线的强弱都会导致同一类型的样本出现误差,
比如,3vs3的实验设计中,3个样本居然重复性不好,而理论上他们应该是一样的。
这时候就出现了Quntile Normalization方法来校正这个误差。
我们创造一个矩阵,行是不同的基因,列是不同的样本, 同时我们用boxplot看一下他的分布
quntile_test <- matrix(c(2,5,4,3,3,4,14,8,8,9,4,4,6,5,3,5,7,9,8,5),ncol=4,byrow = F)
boxplot(quntile_test)
大概是这个样子的:
然后我们对他进行Quntile Normalization,然后就变成这个样子了
确实效果不错,我们来看一下这个原理
首先每一行是不同的基因,用不同的颜色表示,
把每一列的数据从小到大排列,这时候基因的顺序是乱的
把排列后的数据每一行求一个平均值,这时候基因的顺序还是乱的
最后,把基因的顺序恢复到原来的样子。
讲起来很复杂,但是做起来却很简单,在R语言中我们用R包preprocessCore来实现:
library(BiocInstaller)
biocLite("preprocessCore")
library(preprocessCore)
new <- normalize.quantiles(quntile_test)
做个图出来看一下,看达到效果没有
最后一个样本出现了问题。没有办法解决,但是原理已经清楚了,我们可以自己写函数来搞定
1.首先把数据搞出来
df <- data.frame(c(2,5,4,3,3),c(4,14,8,8,9),c(4,4,6,5,3),c(5,7,9,8,5))
colnames(df) <- paste0("Sample",seq(1,4))
rownames(df) <- paste0("Gene",seq(1,5))
df
2.给每一列的数据排序,返回排序的秩
df_rank <- apply(df,2,rank,ties.method="min")
df_rank
3.把每一列的数据按照从小到大排序
df_sorted <- data.frame(apply(df, 2, sort))
df_sorted
4.把每一行的平均值求出来
df_mean <- apply(df_sorted, 1, mean)
df_mean
[1] 3.5 5.0 5.5 6.5 8.5
5.最后按照之前排好的顺序,把这个平均值对应起来,代替原来的值
写一个函数,输入一开始排序的秩,返回出对应的平均值
index_to_mean <- function(my_index, my_mean){
return(my_mean[my_index])
}
df_final <- apply(df_rank, 2, index_to_mean, my_mean=df_mean)
df_final
boxplot(df_final)
运行成功了,但是问题依然存在
追查问题后发现,问题出现在第一步rank,那里选择了ties.method="min",导致如果一个序列中有两个一个,他们的秩就一样
把他改成ties.method="first"后就好了
考虑到这个需求很常见,以及现有的工具没办法满足要求,我们把他写成一个函数,自己用
quantile_normalisation <- function(df){
df_rank <- apply(df,2,rank,ties.method="first")
df_sorted <- data.frame(apply(df, 2, sort))
df_mean <- apply(df_sorted, 1, mean)
index_to_mean <- function(my_index, my_mean){
return(my_mean[my_index])
}
df_final <- apply(df_rank, 2, index_to_mean, my_mean=df_mean)
rownames(df_final) <- rownames(df)
return(df_final)
}
我们试一下效果
new <- quantile_normalisation(df)
boxplot(new)
确实很不错!
对于这个过程,如果还不理解的话,statquest上还有个视频 https://goo.gl/6APsUr
还有一个重要的问题,做Quntile Normalization的假设是差异来自于技术重复,但是如果这个差异来自于生物背景呢,
比如,样品来自于不同的组织,他们的基因本身就很不一样,这时候怎么办?
要是我,我就是先分类,再分别做Quntile Normalization,
而判定是否来自于不同的样本,有一个R可以做 R-package quantro
在这个R包的文章中有一个图是这样的
最左边的图说,如果这个样本见没有技术上的差异,可以做,也可以不做
中间的图,如果样本间有技术差异,那么一定要做
第三章图,如果样本有重复,也有不同来源,要判断!判断就用R-package quantro
参考资料: https://goo.gl/FYhwpG
https://goo.gl/kLP2fB
https://goo.gl/L6Q1qJ(健明的博客)