R,基于方差截止的滤波器矩阵

时间:2013-06-08 21:17:03

标签: r subset variance quantile

请参阅下面的编辑 使用R,我想过滤一个矩阵(基因表达数据)并只保留具有高方差值的行(基因/探针)。例如,我希望仅保留具有底部和顶部百分位数值的行(例如,低于20%且高于80%)。我想将我的研究仅限于下游分析的高变异基因。 R中有基因过滤的常用方法吗?

我的矩阵有18个样本(列)和47000个探针(行),其值为log2变换和标准化。我知道quantile()函数可以识别每个样本列中的20%和80%截止值。我无法弄清楚如何为整个矩阵找到这些值,然后将原始矩阵子集化以删除所有非变量"行。

示例矩阵的平均值为5.97,因此最后三行应该被删除,因为它们包含20%和80%截止值之间的值:

> m

                sample1 sample2 sample3 sample4 sample5 sample6
ILMN_1762337    7.86    5.05    4.89    5.74    6.78    6.41
ILMN_2055271    5.72    4.29    4.64    5.00    6.30    8.02
ILMN_1736007    3.82    6.48    6.06    7.13    8.20    4.06
ILMN_2383229    6.34    4.34    6.12    6.83    4.82    5.57
ILMN_1806310    6.15    6.37    5.54    5.22    4.59    6.28
ILMN_1653355    7.01    4.73    6.62    6.27    4.77    6.12
ILMN_1705025    6.09    6.68    6.80    6.85    8.35    4.15
ILMN_1814316    5.77    5.17    5.94    6.51    7.12    7.20
ILMN_1814317    5.97    5.97    5.97    5.97    5.97    5.97
ILMN_1814318    5.97    5.97    5.97    5.97    5.97    5.97
ILMN_1814319    5.97    5.97    5.97    5.97    5.97    5.97

我很欣赏我应该研究的任何建议或功能。 谢谢!

修改

对不起,我在OP中不太清楚。 (1)我想知道整个矩阵的20%和80%截止值(不仅仅是每个样本)。 (2)然后,如果任何行包含上百分位数或下百分位数的值,则R将保留这些行。如果一行包含接近均值的值(对于所有样本),则抛出这些行。

3 个答案:

答案 0 :(得分:7)

好的,假设你有一个矩阵(所以我假设你的ID列实际上是rownames),那么这很简单。

#  First find the desired quantile breaks for the entire matrix
qt <- quantile( m , probs = c(0.2,0.8) )
# 20%  80% 
#5.17 6.62 
#  Next get a logical vector of the rows that have any values outside these breaks
rows <- apply( m , 1 , function(x) any( x < qt[1] | x > qt[2] ) )
#  Subset on this vector
m[ rows , ]
#            sample1 sample2 sample3 sample4 sample5 sample6
#ILMN_1762337    7.86    5.05    4.89    5.74    6.78    6.41
#ILMN_2055271    5.72    4.29    4.64    5.00    6.30    8.02
#ILMN_1736007    3.82    6.48    6.06    7.13    8.20    4.06
#ILMN_2383229    6.34    4.34    6.12    6.83    4.82    5.57
#ILMN_1806310    6.15    6.37    5.54    5.22    4.59    6.28
#ILMN_1653355    7.01    4.73    6.62    6.27    4.77    6.12
#ILMN_1705025    6.09    6.68    6.80    6.85    8.35    4.15
#ILMN_1814316    5.77    5.17    5.94    6.51    7.12    7.20

any( x < qt[1] | x > qt[2] )函数的apply部分(用于跨矩阵的边距应用函数)如果任何值,则返回TRUE该行超出样本矩阵的20%和80%分位数。根据定义,如果没有值超出这些边界,则返回FALSE,表示我们将在下一行中删除该行。

答案 1 :(得分:3)

Biocondcutor genefilter包提供与微阵列分析相关的常见过滤器。基于行方式可变性的典型过滤器将是

m = matrix(rnorm(47000 * 6), 47000)
varFilter(m)

软件包登录页面引用说明基本操作的小插图,并提供过滤使用的诊断指南。

微阵列分析的基本原则是一行中的值是可比较的,但不是行之间的值。这是因为与每行相关联的探针具有引入行特异性偏差的不同特征 - 与第二行中相同样品的值相比,第一行中的值可合理地指示更多,更少或相等的基因表达。这意味着@Todd不希望基于行间比较(整个矩阵中的最大值和最小值)进行标准化。相反,varFilter计算每行(四分位间行范围)的可变性度量,并选择具有最大可变性的分数(var.cutoff参数)。

varFilter定义的快速峰值表明,对于行方式可变性var.func和(单个)分位数var.cutoff的某些度量,这通常不会比这更棘手。

vars <- apply(m, 1, var.func)
m[vars > quantile(vars, var.cutoff), ]

答案 2 :(得分:1)

我不是统计学家,所以我不知道是否有一般方法来解决这个问题。对我来说,如果你以长格式重塑数据,问题会更简单。

library(reshape2)
dat.m <- melt(dat)
dat.m$value <- as.numeric(dat.m$value)
head(dat.m)
            ID variable value
1 ILMN_1762337  sample1  7.86
2 ILMN_2055271  sample1  5.72
3 ILMN_1736007  sample1  3.82
4 ILMN_2383229  sample1  6.34
5 ILMN_1806310  sample1  6.15
6 ILMN_1653355  sample1  7.01

然后对于每个变量,您执行以下操作:

  1. 使用分位数计算限制
  2. 去除不符合条件的基因。
  3. 您可以使用ddply中的plyr

    执行此操作
    res <- ddply(dat.m,.(variable),function(x){
      ## compute limits for each sample
      z <- x$value
      qq <- quantile(z, probs = c(0.2,0.8))
      ## keep only genes with high or low variance
      dd <- x[z < qq[1] | z > qq[2],]
    })
    ## return to the wide format
    acast(res,ID~variable)
    
                sample1 sample2 sample3 sample4 sample5 sample6
    ILMN_1653355    7.01      NA    6.62      NA    4.77      NA
    ILMN_1705025      NA    6.68    6.80    6.85    8.35    4.15
    ILMN_1736007    3.82    6.48      NA    7.13    8.20    4.06
    ILMN_1762337    7.86      NA    4.89      NA      NA      NA
    ILMN_1806310      NA      NA      NA    5.22    4.59      NA
    ILMN_1814316      NA      NA      NA      NA      NA    7.20
    ILMN_2055271    5.72    4.29    4.64    5.00      NA    8.02
    ILMN_2383229      NA    4.34      NA      NA      NA      NA
    
    在OP澄清之后

    编辑,如果您希望整个矩阵的20%和80%截止值不仅适用于每个单独的样本,则计算ddply之外的qq

       qq <- quantile(dat.m$value, probs = c(0.2,0.8))
    

    然后你评论相应的行,如下所示:

    res <- ddply(dat.m,.(variable),function(x){
      z <- x$value
      ## keep only genes with high or low variance
      dd <- x[z < qq[1] | z > qq[2],]
    })
    

    PS这里的数据是:

    dat <- read.table(text='         ID    sample1 sample2 sample3 sample4 sample5 sample6
    ILMN_1762337    7.86    5.05    4.89    5.74    6.78    6.41
    ILMN_2055271    5.72    4.29    4.64    5.00    6.30    8.02
    ILMN_1736007    3.82    6.48    6.06    7.13    8.20    4.06
    ILMN_2383229    6.34    4.34    6.12    6.83    4.82    5.57
    ILMN_1806310    6.15    6.37    5.54    5.22    4.59    6.28
    ILMN_1653355    7.01    4.73    6.62    6.27    4.77    6.12
    ILMN_1705025    6.09    6.68    6.80    6.85    8.35    4.15
    ILMN_1814316    5.77    5.17    5.94    6.51    7.12    7.20
    ILMN_1814317    5.97    5.97    5.97    5.97    5.97    5.97
    ILMN_1814318    5.97    5.97    5.97    5.97    5.97    5.97
    ILMN_1814319    5.97    5.97    5.97    5.97    5.97    5.97',header=TRUE)