【问题标题】:Merge xts objects with different time intervals合并不同时间间隔的xts对象
【发布时间】:2016-11-09 11:19:52
【问题描述】:

我使用 quantmod 从 yahoo 下载报价,计算季度回报并希望将回报和报价合并到一个 xts 对象中。在这个新对象中,我只想查看同时获得回报和季度回报的日期(通常是季度的最后一天)。然而,我看到的是:

代码如下:

library(quantmod)

#Define stocks
tickers<-c("DBK.DE","DTE.DE")
stock<-tickers
StartDate<-'2011-6-25'
EndDate<-'2016-06-25'

PF <- getSymbols(tickers, src='yahoo', from=StartDate, to=EndDate)

# combine the adjusted close values in one (xts) object
dataset <- Ad(get(PF[1]))
for (i in 2:length(PF)) {
  dataset <- merge(dataset, Ad(get(PF[i])))
}

#Getting Quarterly Returns
QReturns<-as.xts(as.data.frame(lapply(dataset,quarterlyReturn)))

#Here is where I suspect the problem
Quarterly_Portfolio<-merge.xts(dataset,QReturns)

有什么想法吗?

【问题讨论】:

    标签: r merge time-series xts quantmod


    【解决方案1】:

    虽然FXQuantTrader's answer 解决了问题,但它没有正确诊断或解决根本原因。

    合并两个具有不同索引类的 xts 对象并没有错,因为所有 xts 对象在内部都将索引存储为 POSIXct。例如:

    d <- Sys.Date()
    merge(date=xts(1,d), posixct=xts(2,as.POSIXct(d,tz="UTC")))
                 date posixct
    # 2016-07-09    1       2
    

    问题是因为您的两个 xts 对象有不同的时区。请注意,dataset 有 UTC 时区,因为日期索引不能有时区。

    R> str(dataset)
    An ‘xts’ object on 2011-06-27/2016-06-24 containing:
      Data: num [1:1305, 1:2] 33.5 34.3 34.6 35.1 36 ...
     - attr(*, "dimnames")=List of 2
      ..$ : NULL
      ..$ : chr [1:2] "DBK.DE.Adjusted" "DTE.DE.Adjusted"
      Indexed by objects of class: [Date] TZ: UTC
      xts Attributes:  
    List of 2
     $ src    : chr "yahoo"
     $ updated: POSIXct[1:1], format: "2016-07-09 08:21:12"
    

    但是QReturns 有一个“空”TZ 属性(这意味着使用您的本地时区)。

    R> str(QReturns)
    An ‘xts’ object on 2011-06-30/2016-06-24 containing:
      Data: num [1:21, 1:2] 0.047 -0.354 0.118 0.267 -0.215 ...
     - attr(*, "dimnames")=List of 2
      ..$ : NULL
      ..$ : chr [1:2] "quarterly.returns" "quarterly.returns.1"
      Indexed by objects of class: [POSIXct,POSIXt] TZ: 
      xts Attributes:  
     NULL
    

    QReturns 看起来像这样,因为您在 data.frame 上调用了as.xts,而as.xts.data.frame 默认指定dateFormat = "POSIXct"。如果设置dateFormat = "Date",则合并这两个对象不会有问题。

    另请注意,直接调用方法是不好的做法 (merge.xts)。您应该只调用merge 泛型并让S3 系统处理方法调度。

    QReturns <- as.xts(as.data.frame(lapply(dataset,quarterlyReturn)),dateFormat="Date")
    Quarterly_Portfolio <- merge(dataset,QReturns)
    head(Quarterly_Portfolio)
    #            DBK.DE.Adjusted DTE.DE.Adjusted quarterly.returns quarterly.returns.1
    # 2011-06-27         33.5422           7.820                NA                  NA
    # 2011-06-28         34.2747           7.786                NA                  NA
    # 2011-06-29         34.6194           7.909                NA                  NA
    # 2011-06-30         35.1193           8.085        0.04701838          0.03388747
    # 2011-07-01         36.0286           7.992                NA                  NA
    # 2011-07-04         35.7787           7.995                NA                  NA
    

    我个人会通过在计算QReturns 时不从 xts 转换回 data.frame 来避免这一切。您可以直接在 xts 对象上调用 lapply,然后使用 do.call(merge, ...) 将结果合并在一起。

    QReturns <- do.call(merge, lapply(dataset, quarterlyReturn))
    Quarterly_Portfolio <- merge(dataset, QReturns)
    

    您的getSymbols 和“组合”步骤也可以更紧凑地完成:

    PF <- new.env()
    getSymbols(tickers, from=StartDate, to=EndDate, env=PF)
    # combine the adjusted close values in one (xts) object
    dataset <- do.call(merge, eapply(PF, Ad))
    

    【讨论】:

    • 有趣。感谢分享
    【解决方案2】:

    你的问题出现是因为有不同种类的时间对象:

    > class(index(dataset))
    [1] "Date"
    > class(index(QReturns))
    [1] "POSIXct" "POSIXt" 
    

    您想在使用merge.xts 时转换为相同的类。你可以试试这个,在方便的lubridate 函数floor_date 的帮助下,当 POSIXct 对象值附加非零小时时,它将 POSIXct 时间向下舍入到最近的日期:

    require(lubridate)
    index(dataset) <- floor_date(as.POSIXct(index(dataset)), "day")
    Quarterly_Portfolio<-merge.xts(dataset,QReturns)
    
    > head(Quarterly_Portfolio)
               DBK.DE.Adjusted DTE.DE.Adjusted quarterly.returns quarterly.returns.1
    2011-06-27         33.5422           7.820                NA                  NA
    2011-06-28         34.2747           7.786                NA                  NA
    2011-06-29         34.6194           7.909                NA                  NA
    2011-06-30         35.1193           8.085        0.04701838          0.03388747
    2011-07-01         36.0286           7.992                NA                  NA
    2011-07-04         35.7787           7.995                NA                  NA
    

    或者,您也可以使用基本 R 的 round.POSIXt 代替 floor_date,如下所示:as.POSIXct(round.POSIXt(as.POSIXct(index(dataset)), "day"))

    【讨论】:

      猜你喜欢
      • 2014-04-12
      • 2020-11-06
      • 1970-01-01
      • 2016-04-18
      • 1970-01-01
      • 2021-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多