【问题标题】:merging a large list of xts objects合并大量 xts 对象
【发布时间】:2012-08-15 06:03:50
【问题描述】:

我有一个 xts 对象的列表,它们是互斥天数。我想将merge 列表合并为一个大的xts 对象。我这样做的尝试是“

merged_reg_1_min_prices <- do.call(cbind, reg_1_min_prices)

但是这似乎内存不足。 reg_1_min_prices 是 6,000 天的 1 分钟在互斥天返回,所以它不是很大。有谁知道如何解决这个问题?

要明确:reg_1_min_prices 包含相互排斥的日期,每天有 1 分钟的价格,列表中的每个条目都是一个 xts 对象。

【问题讨论】:

  • reg_1_min_prices 是 6,000 个 xts 对象的列表,其中每个列表元素是一天的 1 分钟数据吗?
  • 是的。抱歉,让我将其添加到问题中
  • 您确定要cbind 而不是rbind?如果您想rbind 数据,this function 可能会有所帮助
  • 我试过mergerbindcbind。不幸的是,它们都失败了,内存使用量从 aourn 4 gigs 增加到大约 60 gigs。
  • 我上面引用的函数在FinancialInstrument:::getSymbols.FI 中使用,它可以很好地加载和合并大量天数的高频数据。

标签: r list merge xts zoo


【解决方案1】:

我使用Dominikhis answerthis question提供的策略

我已经把它变成了function 在我的qmao 包中。这段代码也是getSymbols.FI的核心,在FinancialInstrument package中。

do.call.rbind <- function(lst) {
  while(length(lst) > 1) {
    idxlst <- seq(from=1, to=length(lst), by=2)
    lst <- lapply(idxlst, function(i) {
      if(i==length(lst)) { return(lst[[i]]) }
      return(rbind(lst[[i]], lst[[i+1]]))
    })
  }
  lst[[1]]
}

如果你想rbinddata.frames@JoshuaUlrich提供了一个优雅的解决方案here


据我所知(无需仔细观察)内存对于所提供的三种解决方案(@JoshuaUlrich's@Alex's 和 qmao::do.call.rbind)中的任何一种都不是问题。所以,归根结底是速度……

library(xts)
l <- lapply(Sys.Date()-6000:1, function(x) {
    N=60*8;xts(rnorm(N),as.POSIXct(x)-seq(N*60,1,-60))})
GS <- do.call.rbind
JU <- function(x) Reduce(rbind, x)
Alex <- function(x) do.call(rbind, lapply(x, as.data.frame)) #returns data.frame, not xts

identical(GS(l), JU(l)) #TRUE

library(rbenchmark)
benchmark(GS(l), JU(l), Alex(l), replications=1)
     test replications elapsed relative user.self sys.self user.child sys.child
3 Alex(l)            1  89.575 109.9080    56.584   33.044          0         0
1   GS(l)            1   0.815   1.0000     0.599    0.216          0         0
2   JU(l)            1 209.783 257.4025   143.353   66.555          0         0

do.call.rbind 显然在速度上获胜。

【讨论】:

    【解决方案2】:

    您不想使用merge,因为这将返回一个包含 6000 列的对象,其中每个列表元素中的每一行都有一行(在我的示例中为 2,880,000)。大多数值将是NAcbind.xts 只是使用一些默认参数值调用 merge.xts,所以你也不想使用它。

    我们知道通过do.call 调用rbind.xts 引起的内存问题。 Jeff 确实有更高效的代码,但它是一个不公开的原型。

    @GSee's solution 的替代方法是使用Reduce。这需要一段时间才能在我的笔记本电脑上运行,但即使只有 4GB,内存也不是问题。

    library(xts)
    l <- lapply(Sys.Date()-6000:1, function(x) {
      N=60*8;xts(rnorm(N),as.POSIXct(x)-seq(N*60,1,-60))})
    x <- Reduce(rbind, l)
    

    【讨论】:

    • 太棒了!什么是减少?我似乎找不到它的 R 参考
    • @Alex:它是基础包中的一个函数。见?Reduce
    • +1 用于解释为什么 cbind 不是 OP 想要的。
    【解决方案3】:

    这里是如何有效地做到这一点:将每个 xts 对象转换为 data.frame 和简单的 rbind 它们。这几乎不会增加内存使用量。如有必要,只需从 data.frame 创建一个新的 xts 对象

    【讨论】:

    • 我不认为do.call.rbind 使用太多内存,而且对于我测试过的数据来说,它的速度要快很多(甚至不包括转换回xts 的时间)。
    • 好吧,让我试一试。你碰巧知道普通的 rbind 是怎么搞砸的吗?
    • 不,但我敢打赌@JoshuaUlrich 会。如果我没记错的话,Jeff 有一些未提交的代码可以更有效地执行此操作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-16
    • 2014-05-07
    • 2012-08-31
    • 2011-09-16
    • 2012-08-19
    • 2020-11-06
    • 2017-12-08
    相关资源
    最近更新 更多