将 xts 对象与一些常用列合并

Posted

技术标签:

【中文标题】将 xts 对象与一些常用列合并【英文标题】:Merging xts objects with some common columns 【发布时间】:2021-11-23 11:45:08 【问题描述】:

我正在对股票指数成员的交易策略进行回溯测试。我每年都有历史股价日期。我想合并这些时间序列对象。我的问题是指数成分不一样,所以我不能简单地对它们进行 rbind。合并也不是一种选择,因为它会为不同年份的相同股票创建单独的列。有人可以建议我一个解决方案吗?

这是我的问题的一个例子: xts1:

                                  AAPL    AMZ   AA    AXP     
              11/01/2020          100     85     90    70     
              12/01/2020          105     70     80    90     

xts2:

                                  AAPL    AM    AXP     BA
              01/01/2021          108     75     80     50
              02/01/2021          110     60     70     60 

最终xts:

                                  AAPL    AMZ   AA    AXP     BA
              11/01/2020          100     85     90    70     NA
              12/01/2020          105     70     80    90     NA
              01/01/2021          108     75     NA    80     50
              02/01/2021          110     60     NA    70     60 

                

【问题讨论】:

您的输出显示为rbind,即尝试bind_rows(fortify.zoo(xt1), fortify.zoo(xt2)) 第二个数据中有'AM'还是'AMZ' 【参考方案1】:

order.byxts 的索引应该是日期/日期时间类。根据`?xts

order.by - 唯一时间/日期的对应向量 - 必须属于已知的基于时间的类。

如果初始对象是xts 并且日期是Date 类,一个选项是rbind 转换为data.framefortify.zoo 之后

library(xts)
library(dplyr)
bind_rows(fortify.zoo(xt1), fortify.zoo(xt2))
       Index AAPL AMZ AA AXP BA
1 2020-11-01  100  85 90  70 NA
2 2020-12-01  105  70 80  90 NA
3 2021-01-01  108  75 NA  80 50
4 2021-02-01  110  60 NA  70 60

如果我们想重新转换为xts

out <- bind_rows(fortify.zoo(xt1), fortify.zoo(xt2))
xts(out[-1], order.by = out$Index)
           AAPL AMZ AA AXP BA
2020-11-01  100  85 90  70 NA
2020-12-01  105  70 80  90 NA
2021-01-01  108  75 NA  80 50
2021-02-01  110  60 NA  70 60

数据

xt1 <- structure(c(100L, 105L, 85L, 70L, 90L, 80L, 70L, 90L), .Dim = c(2L, 
4L), .Dimnames = list(NULL, c("AAPL", "AMZ", "AA", "AXP")), index = structure(c(1604188800, 
1606780800), tzone = "UTC", tclass = "Date"), class = c("xts", 
"zoo"))

xt2 <- structure(c(108L, 110L, 75L, 60L, 80L, 70L, 50L, 60L), .Dim = c(2L, 
4L), .Dimnames = list(NULL, c("AAPL", "AMZ", "AXP", "BA")), index = structure(c(1609459200, 
1612137600), tzone = "UTC", tclass = "Date"), class = c("xts", 
"zoo"))

【讨论】:

【参考方案2】:

我们定义了一个函数Merge 来合并两个xts 对象。它只使用 xts 包。它使用c.xtscbind.xts 来执行此操作。

以下示例中使用的xts1xts2 对象在末尾的注释中以可重现的形式显示。

Merge <- function(xts1, xts2) 

  nms1 <- names(xts1)
  nms2 <- names(xts2)
  both <- intersect(nms1, nms2)

  cbind(c(xts1[, both], xts2[, both]), 
        xts1[, !nms1 %in% both], 
        xts2[, !nms2 %in% both])


x <- Merge(xts1, xts2); x

给出这个 xts 对象:

           AAPL AXP AMZ AA AM BA
2020-11-01  100  70  85 90 NA NA
2020-12-01  105  90  70 80 NA NA
2021-01-01  108  80  NA NA 75 50
2021-02-01  110  70  NA NA 60 60

另请注意,xts 支持 yearmon 类,它在内部将年和月表示为年 + 分数,其中分数为 0 表示一月,1/12 表示二月,...,11/12 表示十二月,它显示如下.

aggregate(x, as.yearmon)

给予:

         AAPL AXP AMZ AA AM BA
Nov 2020  100  70  85 90 NA NA
Dec 2020  105  90  70 80 NA NA
Jan 2021  108  80  NA NA 75 50
Feb 2021  110  70  NA NA 60 60

注意

library(xts)

Lines1 <- "                      AAPL    AMZ   AA    AXP     
              11/01/2020          100     85     90    70     
              12/01/2020          105     70     80    90     "
xts1 <- read.zoo(text = Lines1, format = "%m/%d/%Y", index = 0) |>
  as.xts()

Lines2 <- "                                  AAPL    AM    AXP     BA
              01/01/2021          108     75     80     50
              02/01/2021          110     60     70     60 " 
xts2 <- read.zoo(text = Lines2, format = "%m/%d/%Y", index = 0) |>
  as.xts()

【讨论】:

以上是关于将 xts 对象与一些常用列合并的主要内容,如果未能解决你的问题,请参考以下文章

合并大量 xts 对象

如何将 data.frame 表转换为 xts 对象

在循环中添加 xts 对象

将两个数据框与一些公共列合并,其中公共的组合需要是自定义函数

将两个数据帧与一些常见列合并,其中共同需要的组合是自定义函数

如何将数据框转换为xts