table 中的背景减法
background subtraction in a table
我有基因表达数据作为每个探针的计数,如下所示:
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
列,我需要计算背景(假设它将是 [=14] 中所有值的平均值=] class) 然后从该列的每个值中减去该背景。目前我正在使用以下解决方案:
for (nm in names(mydata)[-c(1:2)]) {
bg <- mydata[molclass=='negative', nm, with=F];
bg <- mean(unlist(bg));
mydata[[nm]] <- (mydata[[nm]] - bg);
}
但我觉得一定有一些"nicer"方法。
P.S。我知道有一些包可以做这些事情,但我的数据对应于计数的数量,而不是信号的强度 - 所以我不能使用 limma
或为微阵列设计的类似工具。也许一些 seq-data 包可以提供帮助,但我不确定,因为我的数据也不是来自测序。
通常,您不应将 <-
与 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
函数和循环只是语法不同,我听说,您可以使用任何您喜欢的。
如果您需要用计算值替换 sample
列,您可以使用 set
(如 @Frank 的 post)但无需创建额外的对象
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']))
}
我有基因表达数据作为每个探针的计数,如下所示:
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
列,我需要计算背景(假设它将是 [=14] 中所有值的平均值=] class) 然后从该列的每个值中减去该背景。目前我正在使用以下解决方案:
for (nm in names(mydata)[-c(1:2)]) {
bg <- mydata[molclass=='negative', nm, with=F];
bg <- mean(unlist(bg));
mydata[[nm]] <- (mydata[[nm]] - bg);
}
但我觉得一定有一些"nicer"方法。
P.S。我知道有一些包可以做这些事情,但我的数据对应于计数的数量,而不是信号的强度 - 所以我不能使用 limma
或为微阵列设计的类似工具。也许一些 seq-data 包可以提供帮助,但我不确定,因为我的数据也不是来自测序。
通常,您不应将 <-
与 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
函数和循环只是语法不同,我听说,您可以使用任何您喜欢的。
如果您需要用计算值替换 sample
列,您可以使用 set
(如 @Frank 的 post)但无需创建额外的对象
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']))
}