按索引合并任意数量的不同长度的 xts 对象

问题描述

我想将 3 个不同长度的 xts 对象合并为一个具有 3 列的 xts,并按第一个 xts 对象的日期进行索引。

a_xts <- xts(4:10,Sys.Date()+4:10)
b_xts <- xts(c(7:12),Sys.Date()+4:9)
c_xts <- xts(15:18,Sys.Date()+4:7)

我想保留 a_xts 索引日期。合并后的 xts 应如下所示:

           a_xts b_xts c_xts
2021-03-05     4     7    15
2021-03-06     5     8    16
2021-03-07     6     9    17
2021-03-08     7    10    18
2021-03-09     8    11    NA
2021-03-10     9    12    NA
2021-03-11    10    NA    NA

我的解决方案是将每一个合并,为每个添加创建一个新的 xts 对象:

ab_xts <- merge(a_xts,b_xts,all = c(TRUE,FALSE))
abc_xts <- merge(ab_xts,c_xts,FALSE))

有没有更好的方法来做到这一点,而无需转换为 .zoo 并返回到 .xts 对象?

编辑

在合并所有 xts 对象时,我只想保留与 a_xts 的索引日期匹配的行,而不添加任何其他索引日期。例如:

d_xts <- xts(c(7:18),Sys.Date()+4:15

d_xts 的长度大于 a_xts,而 b_xts 和 c_xts 的长度更短。通过一个一个添加 xts 对象来继续我的解决方案,但似乎效率低下。

> abcd_xts <- merge(abc_xts,d_xts,FALSE))
> abcd_xts
           a_xts b_xts c_xts d_xts
2021-03-05     4     7    15     7
2021-03-06     5     8    16     8
2021-03-07     6     9    17     9
2021-03-08     7    10    18    10
2021-03-09     8    11    NA    11
2021-03-10     9    12    NA    12
2021-03-11    10    NA    NA    13

解决方法

我们可以将它放在 list 中,并使用 mergeReduce

out <- Reduce(merge,mget(ls(pattern = '_xts$')))
colnames(out) <- paste0(letters[1:3],"_xts")
,

我们可以使用以下内容(尽管对于问题中的具体示例,不需要 [...])。

merge(a_xts,b_xts,c_xts)[time(a_xts),]

给予:

           a_xts b_xts c_xts
2021-03-05     4     7    15
2021-03-06     5     8    16
2021-03-07     6     9    17
2021-03-08     7    10    18
2021-03-09     8    11    NA
2021-03-10     9    12    NA
2021-03-11    10    NA    NA
,

我发现 merge() 可以在带有参数 all = c(TRUE,FALSE)多个 xts 对象上进行左外连接。这仅匹配传递给 merge() 的第一个 xts 中的行。

> merge(a_xts,c_xts,d_xts,all = c(TRUE,FALSE))

                   a_xts b_xts c_xts d_xts
        2021-03-05     4     7    15     7
        2021-03-06     5     8    16     8
        2021-03-07     6     9    17     9
        2021-03-08     7    10    18    10
        2021-03-09     8    11    NA    11
        2021-03-10     9    12    NA    12
        2021-03-11    10    NA    NA    13