动态合并带有后缀的 xts 对象

merge xts objects with suffixes dynamically

任务是将多个 xts 对象动态合并为一个带有后缀的大 blob,其中后缀本质上是 xts 对象的列名。

示例数据:

library(xts)
a <- data.frame(alpha=1:10, beta=2:11)
xts1 <- xts(x=a, order.by=Sys.Date() - 1:10)
b <- data.frame(alpha=3:12, beta=4:13)
xts2 <- xts(x=b, order.by=Sys.Date() - 1:10)
c <- data.frame(alpha=5:14, beta=6:15)
xts3 <- xts(x=c, order.by=Sys.Date() - 1:10)

静态合并方式:

$> merge.zoo(xts1, xts2, xts3, suffixes=c("A", "B", "C"))
# output
           alpha.A beta.A alpha.B beta.B alpha.C beta.C
2022-03-11      10     11      12     13      14     15
2022-03-12       9     10      11     12      13     14
2022-03-13       8      9      10     11      12     13
2022-03-14       7      8       9     10      11     12
2022-03-15       6      7       8      9      10     11
2022-03-16       5      6       7      8       9     10
2022-03-17       4      5       6      7       8      9
2022-03-18       3      4       5      6       7      8
2022-03-19       2      3       4      5       6      7
2022-03-20       1      2       3      4       5      6

我可能有 3 个以上的 xts 对象,3 个只是任意演示。

我试过 do.call 但我的 do.call 尝试失败 with/out 后缀,因为我无法将 3 个 xts 对象包装成 [=50] 接受的数据结构=] 作为一个列表(在 R 的语言中它应该是一个包含 3 个项目的向量)。

do.call 演示:

# do.call with xts objects as separate args and suffixes, works
do.call(merge.zoo, list(xts1, xts2, xts3, suffixes=c("A", "B", "C")))

# do.call with xts objects wrapped up as list and suffixes, failed

# because R takes each element of list as vector and essentially a list of xts objects is a list of 3 lists, each of which has a xts object.

xts.list <- list(xts1, xts2, xts3)

# check data type
class(xts.list[[1]]) # output: xts,zoo
class(xts.list[1]) # output: list

# do.call failed attempt
do.call(merge.zoo, list(xts.list, suffixes=c("A", "B", "C")))
# Error Message
Error in zoo(structure(x, dim = dim(x)), index(x), ...) : 
“x” : attempt to define invalid zoo object

换句话说,如果我可以将列表解压缩为动态数量的参数,我就能让这个想法发挥作用;但是我似乎找不到在 R 或其他一些解决方案中解压参数的方法。

免责声明:我试图解决的最终问题是最终能够在多面板视图中绘制时间序列数据; ggplot 不适用于我每天使用的大多数软件包。

免责声明 2:merge.xts 忽略后缀(错误),merge.zoo 是可行的替代方案。有关详细信息,请查看 here

我们可以在 list 中传递所有内容,即

library(zoo)
c(xts.list, list(suffixes=c("A", "B", "C")))

现在,使用 do.call

中的 merge
do.call(merge.zoo, c(xts.list, list(suffixes=c("A", "B", "C"))))

-输出

            alpha.A beta.A alpha.B beta.B alpha.C beta.C
2022-03-11      10     11      12     13      14     15
2022-03-12       9     10      11     12      13     14
2022-03-13       8      9      10     11      12     13
2022-03-14       7      8       9     10      11     12
2022-03-15       6      7       8      9      10     11
2022-03-16       5      6       7      8       9     10
2022-03-17       4      5       6      7       8      9
2022-03-18       3      4       5      6       7      8
2022-03-19       2      3       4      5       6      7
2022-03-20       1      2       3      4       5      6

请注意,merge 的第一个参数是可变组件(... - 它可以采用一个或多个 xts 数据,其中所有其他组件都已命名,这就是我们仅针对那些组件(即后缀)创建带有 nameslist。根据 ?merge

merge(..., all = TRUE, fill = NA, suffixes = NULL, join = "outer", retside = TRUE, retclass = "xts", tzone = NULL, drop=NULL, check.names=NULL)

因此,当我们想要附加 listxts.list 与另一个列表元素时,将第二个命名向量包装在 list 中,然后 concatenate .它类似于

> c(list(1), list(a = 1, b = 2))
[[1]]
[1] 1

$a
[1] 1

$b
[1] 2

而不是以下内容,因为这会创建一个嵌套的 list

> list(list(1), list(a = 1, b = 2))
[[1]]
[[1]][[1]]
[1] 1


[[2]]
[[2]]$a
[1] 1

[[2]]$b
[1] 2

现在(终于)在 this commit 中修复了这个问题。感谢您的推动来解决这个问题!

library(xts)
idx <- Sys.Date() - 1:10
x1 <- xts(cbind(alpha = 1:10, beta = 2:11), idx)
x2 <- xts(cbind(alpha = 3:12, beta = 4:13), idx)
x3 <- xts(cbind(alpha = 5:14, beta = 6:15), idx)

suffixes <- LETTERS[1:3]

merge(x1, x2, x3, suffixes = suffixes)
##            alpha.A beta.A alpha.B beta.B alpha.C beta.C
## 2022-05-13      10     11      12     13      14     15
## 2022-05-14       9     10      11     12      13     14
## 2022-05-15       8      9      10     11      12     13
## 2022-05-16       7      8       9     10      11     12
## 2022-05-17       6      7       8      9      10     11
## 2022-05-18       5      6       7      8       9     10
## 2022-05-19       4      5       6      7       8      9
## 2022-05-20       3      4       5      6       7      8
## 2022-05-21       2      3       4      5       6      7
## 2022-05-22       1      2       3      4       5      6