将 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.by
即xts
的索引应该是日期/日期时间类。根据`?xts
order.by - 唯一时间/日期的对应向量 - 必须属于已知的基于时间的类。
如果初始对象是xts
并且日期是Date
类,一个选项是rbind
转换为data.frame
和fortify.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.xts
和cbind.xts
来执行此操作。
以下示例中使用的xts1
和xts2
对象在末尾的注释中以可重现的形式显示。
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 对象与一些常用列合并的主要内容,如果未能解决你的问题,请参考以下文章
将两个数据框与一些公共列合并,其中公共的组合需要是自定义函数