如何自动截取矩阵以匹配quantmod获取的ETF矩阵维度?
自动对齐不同维度的quantmod ETF数据矩阵
我通过quantmod包的getSymbol()获取了VOO和VTI的矩阵数据,VOO维度为3415×6,VTI维度为4434×6。目前需要手动将VTI截取为VTI[929:4434,]才能和VOO维度匹配,但处理多只ETF时手动计算截取位置太繁琐。
我自己写了一个函数可以判断两个矩阵的行数差值,但想知道有没有现成的内置函数能直接实现自动截取对齐的功能。
现有代码
手动计算截取的代码:
dim(VOO) dim(VTI) 4434 - 3415 cor(VTI[929:4343, ], VOO)
自定义行数差值判断函数:
matrix.subset <- function(x, y) { if (dim(x)[1] > dim(y)[1]) { cat("x", ">", "y", " : ", as.numeric(dim(x)[1] - dim(y)[1])) } if (dim(y)[1] > dim(x)[1]) { cat("y", ">", "x", " : ", as.numeric(dim(y)[1] - dim(x)[1])) } } matrix.subset(VOO, VTI)
函数输出:
y > x : 928
解决方案
首先要明确:quantmod获取的VOO和VTI是带时间戳索引的xts/zoo对象,直接按行数截取是不严谨的(比如遇到节假日休市导致日期缺失时,行数差和实际日期区间差不一致)。更可靠的方式是通过时间维度对齐,而非手动算行数。
方法1:用merge()自动对齐时间区间
merge()会自动匹配两个序列的时间索引,只保留共同的日期区间,还能处理缺失值:
# 合并两个序列,仅保留双方都有的日期 merged <- merge(VOO, VTI, all = FALSE) # 拆分回对齐后的VOO和VTI aligned_VOO <- merged[, grep("VOO", colnames(merged))] aligned_VTI <- merged[, grep("VTI", colnames(merged))] # 此时两者行数完全一致,可直接计算相关系数 cor(aligned_VTI, aligned_VOO)
方法2:用intersect()取共同日期索引
直接提取两个序列的共同日期,再分别截取:
common_dates <- intersect(index(VOO), index(VTI)) aligned_VOO <- VOO[common_dates, ] aligned_VTI <- VTI[common_dates, ]
若一定要按行数截取(不推荐)
可以优化你的自定义函数,直接返回对齐后的对象:
align_rows <- function(x, y) { n_x <- nrow(x) n_y <- nrow(y) if (n_x == n_y) { return(list(x = x, y = y)) } else if (n_x > n_y) { x_aligned <- x[(n_x - n_y + 1):n_x, ] return(list(x = x_aligned, y = y)) } else { y_aligned <- y[(n_y - n_x + 1):n_y, ] return(list(x = x, y = y_aligned)) } } # 使用示例 result <- align_rows(VOO, VTI) cor(result$y, result$x)
内容的提问来源于stack exchange,提问作者goldfishgamerhd
相关产品推荐
相关产品推荐

