查看原文
其他

理解 Quntile Normalization

果子 果子学生信 2023-06-15

每一次技术重复的时候,都会有误差,芯片的原始数据是由仪器读取的,不同的读取时间,或者扫描仪光线的强弱都会导致同一类型的样本出现误差,

比如,3vs3的实验设计中,3个样本居然重复性不好,而理论上他们应该是一样的。

这时候就出现了Quntile Normalization方法来校正这个误差。

我们创造一个矩阵,行是不同的基因,列是不同的样本, 同时我们用boxplot看一下他的分布

  1. 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)

  2. boxplot(quntile_test)

大概是这个样子的: 

然后我们对他进行Quntile Normalization,然后就变成这个样子了

确实效果不错,我们来看一下这个原理 

首先每一行是不同的基因,用不同的颜色表示,

把每一列的数据从小到大排列,这时候基因的顺序是乱的

把排列后的数据每一行求一个平均值,这时候基因的顺序还是乱的

最后,把基因的顺序恢复到原来的样子。

讲起来很复杂,但是做起来却很简单,在R语言中我们用R包preprocessCore来实现:

  1. library(BiocInstaller)

  2. biocLite("preprocessCore")

  3. library(preprocessCore)

  4. new <- normalize.quantiles(quntile_test)

做个图出来看一下,看达到效果没有 

最后一个样本出现了问题。没有办法解决,但是原理已经清楚了,我们可以自己写函数来搞定

1.首先把数据搞出来

  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))

  2. colnames(df) <- paste0("Sample",seq(1,4))

  3. rownames(df) <- paste0("Gene",seq(1,5))

  4. df

数据没有问题

2.给每一列的数据排序,返回排序的秩

  1. df_rank <- apply(df,2,rank,ties.method="min")

  2. df_rank

3.把每一列的数据按照从小到大排序

  1. df_sorted <- data.frame(apply(df, 2, sort))

  2. df_sorted

4.把每一行的平均值求出来

  1. df_mean <- apply(df_sorted, 1, mean)

  2. df_mean

  1. [1] 3.5 5.0 5.5 6.5 8.5

5.最后按照之前排好的顺序,把这个平均值对应起来,代替原来的值

写一个函数,输入一开始排序的秩,返回出对应的平均值

  1. index_to_mean <- function(my_index, my_mean){

  2.  return(my_mean[my_index])

  3. }

  4. df_final <- apply(df_rank, 2, index_to_mean, my_mean=df_mean)

  5. df_final

  6. boxplot(df_final)

运行成功了,但是问题依然存在 

追查问题后发现,问题出现在第一步rank,那里选择了ties.method="min",导致如果一个序列中有两个一个,他们的秩就一样 

把他改成ties.method="first"后就好了 

考虑到这个需求很常见,以及现有的工具没办法满足要求,我们把他写成一个函数,自己用

  1. quantile_normalisation <- function(df){

  2.  df_rank <- apply(df,2,rank,ties.method="first")

  3.  df_sorted <- data.frame(apply(df, 2, sort))

  4.  df_mean <- apply(df_sorted, 1, mean)

  5.  index_to_mean <- function(my_index, my_mean){

  6.    return(my_mean[my_index])

  7.  }

  8.  df_final <- apply(df_rank, 2, index_to_mean, my_mean=df_mean)

  9.  rownames(df_final) <- rownames(df)

  10.  return(df_final)

  11. }

我们试一下效果

  1. new <- quantile_normalisation(df)

  2. 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(健明的博客)


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存