使用data.tables时替换唯一(rbind())

Cla*_*nJY 5 r data.table

所以,我有很多data.tables我想组合成一个没有重复行的data.table."天真"的方法是用唯一的方式包装一个rbind调用:unique(do.call(rbind, list.of.tables))

这肯定有效,但它很慢.在我的实际案例中,表格有两列; 哈希字符串和大小.在代码中的这一点上,它们是非键控的.我首先使用hash进行键控,但是组合的增益被键入的时间所抵消.

以下是我对这些选项进行基准测试的方法:

require(data.table)

makeHash <- function(numberOfHashes) {

  hashspace <- c(0:9, sapply(97:122, function(x) rawToChar(as.raw(x))))
  replicate(numberOfHashes, paste(sample(hashspace, 16), collapse=""))

}

mergeNoKey <- function(tableLength, modCount=tableLength/2) {

  A <- B <- data.table(hash=makeHash(tableLength), size=sample(1:(1024^2), tableLength))

  A[1:modCount] <- data.table(hash=makeHash(modCount), size=sample(1:(1024^2), modCount))

  C <- unique(rbind(A,B))
}

mergeWithKey <- function(tableLength, modCount=tableLength/2) {

  A <- B <- data.table(hash=makeHash(tableLength), size=sample(1:(1024^2), tableLength))

  A[1:modCount] <- data.table(hash=makeHash(modCount), size=sample(1:(1024^2), modCount))

  setkey(A, hash)
  setkey(B, hash)

  C <- unique(rbind(A,B))
}

require(microbenchmark)
m <- microbenchmark(mergeNoKey(1000), mergeWithKey(1000), times=10)
plot(m)
Run Code Online (Sandbox Code Playgroud)

我玩过tableLength和时代,并且在性能方面没有太大的区别.我觉得有一个更好的data.table-ish方式来做到这一点.

在实践中,我需要使用许多data.tables,而不是两个,所以可伸缩性非常重要; 我只是想保持上面的代码简单.

提前致谢!

Sim*_*lon 5

我想你想使用rbindlistunique.data.table...

C <- unique( rbindlist( list( A , B ) ) )
Run Code Online (Sandbox Code Playgroud)

  • +1 btw,`unique`在v1.8.10(在CRAN上)获得`以获得更大的灵活性(感谢Steve),并且`list()`不再复制GNU R v3中的命名输入(如本例所示). 1.0(v1.8.10知道并喜欢). (6认同)
  • @JoshO'Brien那是对的,`ab < - list(a,b)`不会复制`a`或`b`,只是增加引用计数器(NAMED).由于`list`也是原始的,我们在data.table(内部和查询中)中使用`list()`它可能会产生显着的差异(尚未测试). (4认同)