【问题标题】:modify values of multiple columns in a table修改表中多列的值
【发布时间】: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 &lt;- 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中的melttidyr中的gather将您的数据框转换为“长”格式),之后问题就变成了微不足道?

标签: r data.table


【解决方案1】:

您可以获得“neg”的rowMeans,列(“val”),然后使用set更新数据集的所有列(从“val”中减去),除了第一个列。

 indx <- grep('^neg', names(mydata))
 val <- as.integer(rowMeans(mydata[, ..indx]))
 for(j in 2:ncol(mydata)){
  set(mydata, i=NULL, j=j, value=mydata[[j]]-val)
 }

 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

【讨论】:

    猜你喜欢
    • 2021-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-17
    • 1970-01-01
    相关资源
    最近更新 更多