【问题标题】:background subtraction in a table表格中的背景减法
【发布时间】:2015-04-20 07:06:26
【问题描述】:

我有基因表达数据作为每个探针的计数,如下所示:

library(data.table)
mydata <- fread(
"molclass,mol.id,sample1,sample2,sample3
negative, negat1,  0, 1,   2
negative, negat2,  2, 1,   1
negative, negat3,  1, 2,   0
 endogen,  gene1, 30, 15, 10
 endogen,  gene2, 60, 30, 20
")

我的问题是 - 执行背景减法的最佳方法是什么,即对于每个 sampleN 列我需要计算背景(假设它将是来自 negative 类的所有值的平均值)然后从该列的每个值中减去该背景。目前我正在使用以下解决方案:

for (nm in names(mydata)[-c(1:2)]) {
  bg <- mydata[molclass=='negative', nm, with=F];
  bg <- mean(unlist(bg));
  mydata[[nm]] <- (mydata[[nm]] - bg);
}

但我觉得必须有一些“更好”的方式。

附:我知道有一些软件包可以做这些事情,但我的数据对应于计数的数量,而不是信号的强度——所以我不能使用limma 或为微阵列设计的类似工具。也许一些 seq-data 包会有所帮助,但我不确定,因为我的数据也不是来自测序。

【问题讨论】:

    标签: r data.table bioconductor


    【解决方案1】:

    如果您需要将sample 列替换为计算值,您可以使用set(如@Frank 的帖子中所示),但无需创建额外的对象

    indx <- grep('^sample', names(mydata))
    for(j in indx){
     set(mydata, i=NULL, j=j, value=mydata[[j]]- 
           mydata[molclass=='negative', mean(unlist(.SD)), .SDcols=j])
    }
    mydata
    #   molclass  mol.id sample1    sample2 sample3
    #1: negative  negat1      -1 -0.3333333       1
    #2: negative  negat2       1 -0.3333333       0
    #3: negative  negat3       0  0.6666667      -1
    #4:  endogen   gene1      29 13.6666667       9
    #5:  endogen   gene2      59 28.6666667      19
    

    或者@Frank 建议的变体(更有效)是

    for(j in indx){
     set(mydata, i=NULL, j=j, value=mydata[[j]]- 
        mean(mydata[[j]][mydata$molclass=='negative']))
    }
    

    【讨论】:

    • 当然,这实际上更接近于我所做的,尽管可以(应该?)在不使用方括号和 .SD 的情况下计算被减去的“背景”对象——mean(mydata[[j]][mydata$molclass=='negative'])——。 ..至少那是知识渊博的人通常所说的。另外,我猜您正在覆盖原始值,这与 OP 的期望输出一致(并且可以在一个 set 命令中完成所有操作),但在许多情况下可能不是正确的方法。跨度>
    • @Frank 是的,这样更好。我只想在一个 [ 中做到这一点。关于覆盖值,是的,我只看预期的结果。在我的帖子中,我确实提到了这一点。
    • 仅供参考,我上一条评论中的[mydata[ 中的[ 不同。第一个只是对向量进行子集化,而后者调用[.data.table,无论出于何种原因,它都有一些开销,其中的.SD 也是如此。
    • @Frank 现在,.SD 可能会慢一点,但我想它会在新版本中进行优化(使其更快)。
    • @VasilyA 这里我们得到了[.data.table。正如我们在 cmets 中所讨论的,这可能会慢一些(不确定)
    【解决方案2】:

    通常,您不应将&lt;-data.table 一起使用。 set 循环中的最后一个分配会更好。输入?set查看帮助页面了解详情。

    mycols  <- paste0('sample',1:3)
    newcols <- paste0(mycols,'bk')
    
    s       <- mydata[['molclass']] == 'negative'
    mybkds  <- sapply(mycols,function(j) mean(mydata[[j]][s]) )
    
    mydata[,(newcols):=NA]
    for (j in mycols) set(mydata,j=paste0(j,'bk'),value=mydata[[j]]-mybkds[j])
    

    我只完成了循环中的最后一步,但这与您的代码基本相同(所有内容都在循环中)。 *apply 函数和循环只是语法不同,我听说过,你可以随心所欲。

    【讨论】:

    • 非常感谢您的解决方案,尤其是您的解释!
    猜你喜欢
    • 2023-03-12
    • 2016-06-19
    • 1970-01-01
    • 1970-01-01
    • 2011-12-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多