使用R中的data.table将多个列添加到data.table with =,只有一个函数调用

时间:2014-03-13 10:21:27

标签: r data.table combn

这是Question的直接扩展。 我有一个数据集,我想根据变量x和y找到变量v的所有成对组合:

library(data.table)
DT = data.table(x=rep(c("a","b","c"),each=6), y=c(1,1,6), v=1:18)
        x y  v
     1: a 1  1
     2: a 1  2
     3: a 6  3
     4: a 1  4
     5: a 1  5
     6: a 6  6
     7: b 1  7
     8: b 1  8
     9: b 6  9
    10: b 1 10
    11: b 1 11
    12: b 6 12
    13: c 1 13
    14: c 1 14
    15: c 6 15
    16: c 1 16
    17: c 1 17
    18: c 6 18

DT[, list(new1 = t(combn(sort(v), m = 2))[,1], 
   new2 = t(combn(sort(v), m = 2))[,2]), 
   by = list(x, y)]
        x y new1 new2
     1: a 1    1    2
     2: a 1    1    4
     3: a 1    1    5
     4: a 1    2    4
     5: a 1    2    5
     6: a 1    4    5
     7: a 6    3    6
     8: b 1    7    8
     9: b 1    7   10
    10: b 1    7   11
    11: b 1    8   10
    12: b 1    8   11
    13: b 1   10   11
    14: b 6    9   12
    15: c 1   13   14
    16: c 1   13   16
    17: c 1   13   17
    18: c 1   14   16
    19: c 1   14   17
    20: c 1   16   17
    21: c 6   15   18

代码执行我想要的但是两次函数调用使得较大数据集的速度变慢。我的数据集有超过300万行和超过130万的x和y组合。 关于如何更快地做到这一点的任何建议? 我更喜欢这样的东西:

DT[, list(c("new1", "new2") = t(combn(sort(v), m = 2))), by = list(x, y)]

2 个答案:

答案 0 :(得分:5)

这应该有效:

DT[, {
    tmp <- combn(sort(v), m = 2 )
    list(new1 = tmp[1,], new2 = tmp[2,] )
  }
, by = list(x, y) ]

答案 1 :(得分:4)

以下也有效。诀窍是将matrix转换为data.table

DT[, data.table(t(combn(sort(v), m = 2))), by=list(x, y)]

如有必要,只需在

之后重命名列
r2 <- DT[, data.table(t(combn(sort(v), m = 2))), by=list(x, y)]
setnames(r2, c("V1", "V2"), c("new1", "new2"))