11

我有一个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对象。

4

3 回答 3

12

我使用Dominik回答这个问题时提供的策略

我已经把它变成了我的qmao包中的一个函数。此代码也是FinancialInstrument 包中getSymbols.FI的核心。

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]]
}

如果你愿意rbind data.frames@JoshuaUlrich在这里提供了一个优雅的解决方案


据我所知(无需仔细观察),所提供的三种解决方案(@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显然以速度取胜。

于 2012-08-19T19:34:38.860 回答
10

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

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

@GSee 解决方案的替代方法是使用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)
于 2012-08-19T20:18:26.800 回答
1

以下是如何有效地做到这一点:将每个xts对象转换为 adata.frame并简单地转换rbind它们。这几乎不会增加内存使用量。如有必要,只需xtsdata.frame

于 2012-08-19T18:42:50.773 回答