【问题标题】:Subtract every column from each other column in a R data.table从 R data.table 中的每一列中减去每一列
【发布时间】:2013-06-04 14:06:23
【问题描述】:

假设我有一个 data.table

set.seed(1) # to make the example reproducible
ex<-data.table(AAA=runif(100000),
               BBB=runif(100000),
               CCC=runif(100000),
               DDD=runif(100000),
               FLAG=c(rep(c("a","b","c","d","e"),200000)))

我想从AAA 列中减去每隔一列,然后从BBB 中减去每一列(FLAG 除外),依此类推,以使输出看起来像...

ex[,list(AAA_BBB=AAA-BBB,
         AAA_CCC=AAA-CCC,
         AAA_DDD=AAA-DDD,
         BBB_CCC=BBB-CCC,
         BBB_DDD=BBB-DDD,
         CCC_DDD=CCC-DDD)]

是否有一个 data.table 语法可以在不知道有多少列或它们的名称是什么的情况下干净地做到这一点?

【问题讨论】:

  • 在您的示例中处理 1000000 行并不是很有趣。您的问题中没有提到效率……这是一个问题吗?无论如何,我只尝试了十行的答案。
  • @Frank 我相信,如果使用 data.table,则几乎暗示了对效率的需求。
  • @Frank 对示例中的行过多感到抱歉,我刚刚复制粘贴了一个先前的问题,我询问了与示例相关的大量行。
  • 啊,没问题。我的解决方案既低效又冗长。我不知道这个不错的combn 函数,如果没有你的大示例数据,我也不会意识到它有多好。 :) 另外,Roland 是对的:我应该假设 data.table 问题与效率有关。

标签: r data.table


【解决方案1】:

循环遍历 data.table 中的组合:

comblist <- combn(names(ex)[-5],2,FUN=list)
res2 <- ex[,lapply(comblist,function(x) get(x[1])-get(x[2]))]

setnames(res2,names(res2),sapply(comblist,paste,collapse="_"))

【讨论】:

  • 有没有办法将FLAG 保留在res2 中,或者我必须稍后再添加?我试过list(lapply(comblist,function(x) get(x[1])-get(x[2])),FLAG)],但没用。
  • 您可以使用 ex[,sapply(comblist,paste,collapse="_"):=lapply(comblist,function(x) get(x[1])-get(x[2]))] 并通过引用将新列添加到原始 data.table 中。
【解决方案2】:

combnapply 的解决方案:

cc <- combn(colnames(ex)[1:4], 2)
apply(cc, 2, function(x)ex[[x[1]]]-ex[[x[2]]])

给出前 5 行:

             [,1]         [,2]       [,3]        [,4]        [,5]         [,6]
 [1,] -0.43500930 -0.520148152  0.1602265 -0.08513885  0.59523580  0.680374655
 [2,] -0.32964090 -0.153303302 -0.3807295  0.17633760 -0.05108855 -0.227426149
 [3,]  0.25991705 -0.079679566  0.2040904 -0.33959662 -0.05582670  0.283769917
 [4,]  0.35585252  0.153083047  0.2382553 -0.20276948 -0.11759719  0.085172292
 [5,] -0.67081018 -0.116543468 -0.3413471  0.55426671  0.32946305 -0.224803663

编辑

正如 Arun 所建议的,combn 可以采用函数参数,因此更好的解决方案是

res <- combn(colnames(ex)[1:4], 2, function(x) ex[[x[1]]] - ex[[x[2]]])
colnames(res) <- combn(colnames(ex)[1:4], 2, paste, collapse="_")
as.data.table(res)

            AAA_BBB     AAA_CCC     AAA_DDD     BBB_CCC     BBB_DDD     CCC_DDD
      1: -0.4350093 -0.52014815  0.16022650 -0.08513885  0.59523580  0.68037465
      2: -0.3296409 -0.15330330 -0.38072945  0.17633760 -0.05108855 -0.22742615
      3:  0.2599171 -0.07967957  0.20409035 -0.33959662 -0.05582670  0.28376992
      4:  0.3558525  0.15308305  0.23825534 -0.20276948 -0.11759719  0.08517229
      5: -0.6708102 -0.11654347 -0.34134713  0.55426671  0.32946305 -0.22480366
     ---                                                                       
 999996: -0.8450458 -0.47951267 -0.30333929  0.36553310  0.54170648  0.17617338
 999997: -0.5778393 -0.01784418 -0.24353237  0.55999516  0.33430697 -0.22568819
 999998:  0.7127352  0.82554276  0.01258673  0.11280758 -0.70014846 -0.81295604
 999999: -0.6693544 -0.42335069 -0.81080852  0.24600375 -0.14145408 -0.38745783
1000000: -0.8511655 -0.23341818 -0.15830584  0.61774732  0.69285966  0.07511234

【讨论】:

  • (+1) combn 也有一个函数参数:combn(colnames(ex)[1:4], 2, function(x) ex[[x[1]]] - ex[[x[2]]])
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-24
  • 1970-01-01
  • 1970-01-01
  • 2019-07-09
  • 1970-01-01
相关资源
最近更新 更多