如何按季度日期按序列号对xts对象进行子集化?

时间:2017-06-12 21:45:42

标签: r xts

我正在尝试根据数字位置从大型xts对象中提取季度末数据而且我很茫然。任何帮助将不胜感激。举个例子,假设我有一年的数据如下:

set.seed(78)
date.a <-seq(as.Date("2000/1/1"), as.Date("2000/12/31"), "days")
dat <-xts(rnorm(length(date.a)), date.a)

head(dat)
                 [,1]
2000-01-01  0.7172775
2000-01-02  0.2581460
2000-01-03  1.0750581
2000-01-04 -0.5375775
2000-01-05 -1.3264418
2000-01-06  1.1817348

我可以轻松地手动提取季度末数据,例如:

a <-dat[91]
b <-dat[182]  
c <-dat[274]
d <-dat[366]

c(a,b,c,d)
                 [,1]
2000-03-31  0.7329080
2000-06-30  1.0648634
2000-09-30 -3.1556240
2000-12-31  0.9452281

我如何以编程方式提取这些日期/数据?挑战在于弄清楚数字序列在数年或数十年的过程中如何发挥作用。由于间隔时间不是标准的~91天,因此尚不清楚如何进行。有什么建议?谢谢!

2 个答案:

答案 0 :(得分:2)

您可以将日期转换为zoo::yearqtr。然后在设置yearqtr时将Date转换回frac = 1,即每个季度的最后一个日期(请参阅?yearmon)。使用这些日期来对数据进行分组:

dat[index(dat) == as.Date(as.yearqtr(index(dat)), frac = 1)]
#                 [,1]
# 2000-03-31  0.7329080
# 2000-06-30  1.0648634
# 2000-09-30 -3.1556240
# 2000-12-31  0.9452281

答案 1 :(得分:1)

您可以创建日期d的向量,并将xts元素称为dat[d]

以下是我将如何操作(我喜欢使用lubridate包,我喜欢在Excel中模拟EOMonth函数):

library(lubridate)
EOMonth = function(d, step) {
  day(d) = 1 # just in case we inadvertantly compute 30 February or 31 April.
  month(d) = month(d) + step
  day(d) = days_in_month(d)
  return(d)
}
d = EOMonth(ymd("1999-12-31"), seq(from = 3, to = 12, by = 3))
dat[d]

如果您需要索引,则可以执行以下操作:

all.d = ymd("1999-12-31") + 1:366
answer = which(all.d %in% d)