【发布时间】:2020-04-18 10:24:18
【问题描述】:
所以,这是我的示例数据:
library(data.table)
mydata <- fread(
"sample,neg1,neg2,neg3,gen1,gen2
sample1, 0, 1, 2, 30, 60
sample2, 1, 0, 1, 15, 30
sample3, 2, 1, 0, 10, 20
")
并且我想在每一行中减去背景(“否定”列的mean)。我当前的代码如下:
negatives <- names(mydata)[grep("^neg", names(mydata))] # "neg1" "neg2" "neg3"
mydata[, names(mydata)[-1]:={
bg <- mean(unlist(.SD[, negatives, with=F]));
.SD - as.integer(bg);
}, with=F, by=sample]
# mydata
# sample neg1 neg2 neg3 gen1 gen2
#1: sample1 -1 0 1 29 59
#2: sample2 1 0 1 15 30
#3: sample3 1 0 -1 9 19
它可以完成这项工作,但在我真正更大的桌子上运行速度很慢 - 我想,这是因为使用了.SD。有没有更好的方法来完成这项任务?以某种方式使用set?
(这个问题和我的previous one很相似:这里的源数据是另一种形式,所以我找不到与set应用相同解决方案的方法,希望不会被视为重复) .
【问题讨论】:
-
糟糕,很抱歉。
-
我想出了一个两步解决方案。您可以检查它是否比您的解决方案更快
mydata1 <- mydata[ , V1:=list(as.integer(rowMeans(.SD))), .SDcols=indx]; mydata1[, names(mydata1)[-c(1,7)]:= .SD-mydata1[['V1']], .SDcols=2:6][,V1:=NULL][] -
另一种选择是分别获取选定列上的
rowMeans,然后使用set更新所有列。我更新了解决方案 -
感谢您的指点,我对其进行了修改并移至最后(此处作为第四条评论看起来很奇怪;此外,我认为我链接到的上一个问题也可能对某人有用) .
-
如何融化整个东西(我的意思是使用
reshape2中的melt或tidyr中的gather将您的数据框转换为“长”格式),之后问题就变成了微不足道?
标签: r data.table