数据表有效回收

问题描述 投票:0回答:2

例如,当我需要对未来几年进行预测时,我经常在data.table中使用回收。每年以后我都会重复原始数据。

这可能会导致类似的结果:

library(data.table)
dt <- data.table(cbind(1:500000, 500000:1))
dt2 <- dt[, c(.SD, .(year = 1:10)), by = 1:nrow(dt) ]

但是我经常不得不处理数百万行,并且比这个玩具示例中的列要多得多。时间增加了..试试这个:

library(data.table)
dt <- data.table(cbind(1:50000000, 50000000:1))
dt2 <- dt[, c(.SD, .(year = 1:10)), by = 1:nrow(dt) ]

我的问题是:有没有更有效的方法来实现这一目的?

感谢您的帮助!

r data.table recycle
2个回答
0
投票

我将这个问题视为交叉联接。没有内置的方法可以在两个数据表之间进行交叉联接(CJ函数对向量有效),但是从讨论on this issue来看,此函数很好用:

CJDT <- function(...) {
    Reduce(function(DT1, DT2) cbind(DT1, DT2[rep(1:.N, each=nrow(DT1))]), list(...))
}

使用您的大型示例,这对我有用:

years = data.table(year = 1:10, key = "year")
setkey(dt)
dt3 = CJDT(dt, years)

您的方法需要更长的时间才能耗尽内存。


0
投票

如评论中所述,我怀疑问题的前提可能是可疑。无论如何,这是一个更快的替代方法:

dt[CJ(V1, year = 1:10), on = "V1"]

基准测试

data.table(cbind(1:50000000, 50000000:1))
microbenchmark::microbenchmark(
  op = dt[, c(.SD, .(year = 1:10)), by = 1:nrow(dt) ],
  sb = dt[CJ(V1, year = 1:10), on = "V1"],
  times = 4
)

Unit: milliseconds
 expr      min       lq     mean   median        uq       max neval
   op 724.7858 726.5420 890.5499 840.6526 1054.5578 1156.1085     4
   sb 197.3953 201.4305 235.6163 206.1864  269.8021  332.6971     4
© www.soinside.com 2019 - 2024. All rights reserved.