使用来自另一个 xts 对象的数据更新 xts 时间序列对象

Update an xts time series object with data from another xts object

我正在寻找一种更简单的方法来使用另一个 xts 对象中的数据更新 xts 时间序列对象。应更新重叠时间段和维度的数据,应添加其他时间段,并应根据需要添加缺失的系列维度。目前我正在使用合并、子集和赋值的组合。有没有办法以更少的步骤完成此操作?

例子

两个具有共同一维(y)和两个共同时间段(2018 Q2 和 2018 Q3)的 xts 时间序列对象。

library(xts)

t <- as.yearqtr(paste(2018, 1:4, sep = ":Q"), format = "%Y:Q%q")

short <- xts(
    matrix(1, ncol = 2, nrow = 2, dimnames = list(NULL, c("x", "y"))), 
    order.by = t[2:3]
)

long <- xts(
    matrix(0, ncol = 2, nrow = 4, dimnames = list(NULL, c("y", "z"))),
    order.by = t
)

short

        x y
2018 Q2 1 1
2018 Q3 1 1

long

        y z
2018 Q1 0 0
2018 Q2 0 0
2018 Q3 0 0
2018 Q4 0 0

情况 1 的预期结果:用 long

更新 short
         x  y z
2018 Q1 NA  0 0
2018 Q2  1  0 0
2018 Q3  1  0 0
2018 Q4 NA  0 0

情况 2 的预期结果:将 long 更新为 short

         x  y z
2018 Q1 NA  0 0
2018 Q2  1  1 0
2018 Q3  1  1 0
2018 Q4 NA  0 0

案例一

合并非重叠维度,然后子集化并分配重叠维度(如:Updating an XTS object

short2 <- short
for (j in setdiff(colnames(long), colnames(short2))) {
    short2 <- merge(short2, long[, j])
}
short3 <- short2
for (j in intersect(colnames(short3), colnames(long))) {
    short3[index(long), j] <- long[, j]
}
short3

         x y z
2018 Q1 NA 0 0
2018 Q2  1 0 0
2018 Q3  1 0 0
2018 Q4 NA 0 0

案例二

相同的方法:合并非重叠系列维度,然后子集并分配重叠维度

long2 <- long
for (j in setdiff(colnames(short), colnames(long2))) {
    long2 <- merge(long2, short[, j])
}
long3 <- long2
for (j in intersect(colnames(short), colnames(long3))) {
    long3[index(short), j] <- short[, j]
}
long3

        y z  x
2018 Q1 0 0 NA
2018 Q2 1 0  1
2018 Q3 1 0  1
2018 Q4 0 0 NA

还有什么比这两个步骤更简单的吗?也许是来自另一个包的功能或选项。

无法在 Rmerge 中为共享相同名称的列分配优先级。我刚才有一个类似的问题。 R 默认情况下必须生成唯一的列名。您可以在之后使用 setNames 直接为列分配一个通用名称,但 R 将始终分配唯一的名称(请参阅 ?make.names 了解一些解释)。不推荐这样做,因为它会使之后的操作变得更加复杂。

操作tsxts对象也很复杂。可以做到,但真的不值得花时间。最好转换为 data.frametibble 并以这些格式开展业务,然后再转换回来。

以下是tidyverse解决方案,也使用了timetk包。

library(xts)
library(timetk)
library(dplyr)

xts::merge.xts(long, short) %>% #merge xts objects using merge.xts
  timetk::tk_tbl() %>% #convert xts object to tibble
  dplyr::mutate(y = dplyr::coalesce(y.1, y)) %>% #replace y with coalesced y & y.1
  dplyr::select(-y.1) %>% #deselect y.1
  timetk::tk_xts(silent = T) #convert back to xts

        y z  x
2018 Q1 0 0 NA
2018 Q2 1 0  1
2018 Q3 1 0  1
2018 Q4 0 0 NA