在不获取 NA 的情况下将 xts 对象与字符输入合并

Merging xts object with character inputs without getting NAs

我目前正在处理跨资产 类 的期货数据集——其中涉及具有数字和字符输入的 xts 对象。我正在应用 merge() 将数据集与一致的日期对齐,但是,在具有字符输入的 xts 对象上的 merge(),如下例所示,给出了 NA。有解决办法吗?

下面是样本 xts 对象(基础期货合约)的 dput 输出:

uContracts <- structure(c("SPH00-USA", "SPH00-USA", "SPH00-USA", "SPH00-USA", 
"SPH00-USA", "SPH00-USA", "SPH00-USA", "SPH00-USA", "SPH00-USA", 
"SPH00-USA", "SPH00-USA", "SPH00-USA", "SPH00-USA", "SPH00-USA", 
"SPH00-USA", "SPH00-USA", "SPH00-USA", "SPH00-USA", "SPH00-USA", 
"SPH00-USA", "SPH00-USA", "SPH00-USA", "SPH00-USA", "SPH00-USA", 
"SPH00-USA", "SPH00-USA", "SPH00-USA", "SPH00-USA", "SPH00-USA", 
"SPH00-USA", "SPH00-USA", "SPH00-USA", "SPH00-USA", "SPH00-USA", 
"SPH00-USA", "SPH00-USA", "SPH00-USA", "SPH00-USA", "SPH00-USA", 
"SPH00-USA", "SPM00-USA", "SPM00-USA", "SPM00-USA", "SPM00-USA", 
"SPM00-USA", "SPM00-USA", "SPM00-USA", "SPM00-USA", "SPM00-USA", 
"SPM00-USA", "SPM00-USA", "SPM00-USA", "SPM00-USA", "SPM00-USA", 
"SPM00-USA", "SPM00-USA", "SPM00-USA", "SPM00-USA", "SPM00-USA", 
"SPM00-USA"), class = c("xts", "zoo"), .indexCLASS = "Date", .indexTZ = "UTC", tclass = "Date", tzone = "UTC", index = structure(c(946598400, 
946857600, 946944000, 947030400, 947116800, 947203200, 947462400, 
947548800, 947635200, 947721600, 947808000, 948153600, 948240000, 
948326400, 948412800, 948672000, 948758400, 948844800, 948931200, 
949017600), tzone = "UTC", tclass = "Date"), .Dim = c(20L, 3L
), .Dimnames = list(NULL, c("SP00-USA", "SP.1-USA", "SP.2-USA"
)))

D 输出样本日期:

tW <- structure(c(10956, 10959, 10960, 10961, 10962, 10963, 10966, 
10967, 10968, 10969, 10970, 10973, 10974, 10975, 10976, 10977, 
10980, 10981, 10982, 10983), class = "Date")

我想按照 tW 中的日期格式化 uContracts,其中 tW 中不在 uContracts 中的任何日期,从最后一个可用日期开始填写基础合同名称。我目前正在这样做:

adjContracts <- merge(uContracts, tW, fill = na.locf)

以上命令适用于数字数据(如价格),但不适用于字符数据。我当前的输出是:

NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, 
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, 
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, 
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, 
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, 
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, 
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, 
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, 
NA_real_, NA_real_), .Dim = c(21L, 3L), .Dimnames = list(NULL, 
    c("SP00.USA", "SP.1.USA", "SP.2.USA")), index = structure(c(946598400, 
946857600, 946944000, 947030400, 947116800, 947203200, 947462400, 
947548800, 947635200, 947721600, 947808000, 948067200, 948153600, 
948240000, 948326400, 948412800, 948672000, 948758400, 948844800, 
948931200, 949017600), tzone = "UTC", tclass = "Date"), class = c("xts", 
"zoo"), .indexCLASS = "Date", .indexTZ = "UTC", tclass = "Date", tzone = "UTC")

据我所知,xts 正在将基础数据集转换为数字(从字符)。我相信,Darren Cook(PS - 我希望你能接受大喊大叫)在 中提到了这个问题,但我不确定如何在这里应用它。

如有任何帮助,我们将不胜感激。

干杯, S

更新:下面是预期的输出(注意 xts 对象索引的不同):

structure(c("SPH00-USA", "SPH00-USA", "SPH00-USA", "SPH00-USA", 
"SPH00-USA", "SPH00-USA", "SPH00-USA", "SPH00-USA", "SPH00-USA", 
"SPH00-USA", "SPH00-USA", "SPH00-USA", "SPH00-USA", "SPH00-USA", 
"SPH00-USA", "SPH00-USA", "SPH00-USA", "SPH00-USA", "SPH00-USA", 
"SPH00-USA", "SPH00-USA", "SPH00-USA", "SPH00-USA", "SPH00-USA", 
"SPH00-USA", "SPH00-USA", "SPH00-USA", "SPH00-USA", "SPH00-USA", 
"SPH00-USA", "SPH00-USA", "SPH00-USA", "SPH00-USA", "SPH00-USA", 
"SPH00-USA", "SPH00-USA", "SPH00-USA", "SPH00-USA", "SPH00-USA", 
"SPH00-USA", "SPM00-USA", "SPM00-USA", "SPM00-USA", "SPM00-USA", 
"SPM00-USA", "SPM00-USA", "SPM00-USA", "SPM00-USA", "SPM00-USA", 
"SPM00-USA", "SPM00-USA", "SPM00-USA", "SPM00-USA", "SPM00-USA", 
"SPM00-USA", "SPM00-USA", "SPM00-USA", "SPM00-USA", "SPM00-USA", 
"SPM00-USA"), .Dim = c(20L, 3L), .Dimnames = list(NULL, c("SP00-USA", 
"SP.1-USA", "SP.2-USA")), index = structure(c(946598400, 946857600, 
946944000, 947030400, 947116800, 947203200, 947462400, 947548800, 
947635200, 947721600, 947808000, 948067200, 948153600, 948240000, 
948326400, 948412800, 948672000, 948758400, 948844800, 948931200
), tzone = "UTC", tclass = "Date"), class = c("xts", "zoo"), .indexCLASS = "Date", tclass = "Date", .indexTZ = "UTC", tzone = "UTC")

也许有一种方法可以在不转换数据的情况下解决这个问题,但如果将其转换为数据框,操作起来会更容易。使用 tidyverse 中的函数,我们可以执行以下操作

library(tidyverse)
library(xts)

as.data.frame(uContracts) %>%
   rownames_to_column('Date') %>%
   mutate(Date = as.Date(Date)) %>%
   right_join(tibble(Date = tW)) %>%
   fill(everything()) %>%
   column_to_rownames('Date') %>%
   as.xts()

#             SP00-USA    SP.1-USA    SP.2-USA   
#1999-12-31 "SPH00-USA" "SPH00-USA" "SPM00-USA"
#2000-01-03 "SPH00-USA" "SPH00-USA" "SPM00-USA"
#2000-01-04 "SPH00-USA" "SPH00-USA" "SPM00-USA"
#2000-01-05 "SPH00-USA" "SPH00-USA" "SPM00-USA"
#2000-01-06 "SPH00-USA" "SPH00-USA" "SPM00-USA"
#2000-01-07 "SPH00-USA" "SPH00-USA" "SPM00-USA"
#2000-01-10 "SPH00-USA" "SPH00-USA" "SPM00-USA"
#2000-01-11 "SPH00-USA" "SPH00-USA" "SPM00-USA"
#2000-01-12 "SPH00-USA" "SPH00-USA" "SPM00-USA"
#2000-01-13 "SPH00-USA" "SPH00-USA" "SPM00-USA"
#2000-01-14 "SPH00-USA" "SPH00-USA" "SPM00-USA"
#2000-01-17 "SPH00-USA" "SPH00-USA" "SPM00-USA"
#2000-01-18 "SPH00-USA" "SPH00-USA" "SPM00-USA"
#2000-01-19 "SPH00-USA" "SPH00-USA" "SPM00-USA"
#2000-01-20 "SPH00-USA" "SPH00-USA" "SPM00-USA"
#2000-01-21 "SPH00-USA" "SPH00-USA" "SPM00-USA"
#2000-01-24 "SPH00-USA" "SPH00-USA" "SPM00-USA"
#2000-01-25 "SPH00-USA" "SPH00-USA" "SPM00-USA"
#2000-01-26 "SPH00-USA" "SPH00-USA" "SPM00-USA"
#2000-01-27 "SPH00-USA" "SPH00-USA" "SPM00-USA"

题中代码有几个问题:

  • tW 未转换为 xts,如果未转换,则假定该对象表示 data 而实际上它表示索引
  • 从预期的输出来看,您似乎只希望 tW 中的日期出现在输出中,因此需要适当地指定 all= 参数。

要做到这一点,请注意支持零宽度 xts 对象,因此请将 tW 转换为 xts 对象,如下所示,然后将 uContracts 与其合并。从问题中显示的预期输出来看,结果中似乎只有 tW 中的日期。在这种情况下,请使用如下所示的 all= 参数。 (如果相反,输出中需要两个对象的所有日期,则省略 all= 参数,因为默认值为 all = TRUE,它保留两个对象的日期。)

merge(uContracts, xts(, tW), all = c(FALSE, TRUE), fill = na.locf)