从年度数据转换为季度数据,限制为年平均值

时间:2015-09-24 15:07:16

标签: r time-series zoo

我在R的年频率上有几个变量,我希望将其包含在回归分析中,其他变量以季度频率提供。此外,我希望能够以再现原始年度数据的方式将季度数据转换回年度频率。

从低频到高频时间序列数据转换时,我目前的方法是使用zoo包中的na.spline函数。但是,我没有看到如何限制季度数据以匹配相应的年平均值。因此,当我将数据从季度转换回年度频率时,我得到的年度值与原始系列不同。

可重复的例子:

library(zoo)

# create annual example series
a <- as.numeric(c("100", "110", "111"))
b <- as.Date(c("2000-01-01", "2001-01-01", "2002-01-01"))
z_a <- zoo(a, b); z_a

# current approach using na.spline in zoo package
end_z <- as.Date(as.yearqtr(end(z_a))+ 3/4)
z_q <- na.spline(z_a, xout = seq(start(z_a), end_z, by = "quarter"), method = "hyman")

# result, with first quarter equal to annual value
c <- merge(z_a, z_q); c

# convert back to annual using aggregate in zoo package 
# At this point I would want both series to be equal, but they aren't. 
d <- aggregate(c, as.integer(format(index(c),"%Y")), mean, na.rm=TRUE); d

存储原始年度数据是一种解决方案,或者我可以将第一季度值作为年度值进行转换。但是这两种方法都增加了复杂性,因为我需要跟踪我的季度系列中哪一个最初是从年度数据中转换出来的。

我更喜欢动物园或xts包中的解决方案,但也欢迎其他建议。

编辑纳入方法#1 G.格洛腾迪克提议

# Approach 1
yr <- format(time(c), "%Y")
c$z_q_adj <- ave(coredata(c$z_q), yr, FUN = function(x) x - mean(x) + x[1]); c

# simple plot
dat <- c%>%
data.frame(date=time(.), .) %>%
gather(variable, value, -date)
ggplot(data=dat, aes(x=date, y=value, group=variable, color=variable)) +
  geom_line() +
  geom_point() +
  theme(legend.position=c(.7, .4)) + 
  geom_point(data = subset(dat,variable == "z_a"),  colour="red", shape=1, size=7)

这是一个干净,有效的建议。然而,我对方法1的初步挑战是它有可能导致Q4和Q1之间的跳跃(例如2001Q1相对于前一季度,如图所示)。这些意味着一个季度的快速增长。部分解决方案可能是使用6月的年度值进行年度转换为月度,然后使用样本,然后按照G. Grothendieck的建议应用方法1,然后转换为季度。

其他研究:

3 个答案:

答案 0 :(得分:2)

这里有点晚了,但tempdisagg包做了你想要的。它确保得到的高频序列的和,平均值,第一个或最后一个值与低频序列一致。

它还允许您使用外部指标系列,例如,通过 Chow-Lin 技术。如果你没有, Denton-Cholette 方法产生的结果比Eviews中的方法更好。

以下是您的示例:

# need ts object as input
z_a <- ts(c(100, 110, 111), start = 2000)

library(tempdisagg)
z_q <- predict(td(z_a ~ 1, method = "denton-cholette", conversion = "average"))

z_q
#           Qtr1      Qtr2      Qtr3      Qtr4
# 2000  97.65795  98.59477 100.46841 103.27887
# 2001 107.02614 109.71460 111.34423 111.91503
# 2002 111.42702 111.06100 110.81699 110.69499

# which has the same means as your original series:

tapply(z_q, floor(time(z_q)), mean)
# 2000 2001 2002 
#  100  110  111 

答案 1 :(得分:0)

我们可以操纵na.spline的输出,以确保通过改变4个季度来平均到年度值。价值或改变最后3个季度&#39;值。在第一种情况下,我们将从每个季度中减去4个季度的平均值,然后将每年的年度值添加到每个季度。在第二种情况下,我们从过去3个季度中减去过去3个季度的平均值并添加年度。

在每种情况下,在一年中的四个季度中平均z_q_adj值将恢复原始年度值。

以下是提到的两种方法:

# 1
yr <- format(time(c), "%Y")
c$z_q_adj <- ave(coredata(c$z_q), yr, FUN = function(x) x - mean(x) + x[1])

,并提供:

> c
           z_a      z_q   z_q_adj
2000-01-01 100 100.0000  95.36604
2000-04-01  NA 103.4434  98.80946
2000-07-01  NA 106.4080 101.77405
2000-10-01  NA 108.6844 104.05046
2001-01-01 110 110.0000 109.39295
2001-04-01  NA 110.5723 109.96527
2001-07-01  NA 110.8719 110.26484
2001-10-01  NA 110.9840 110.37694
2002-01-01 111 111.0000 110.86116
2002-04-01  NA 111.0150 110.87615
2002-07-01  NA 111.1219 110.98311
2002-10-01  NA 111.4184 111.27958


# 2
c$z_q_adj <- ave(coredata(c$z_q), yr, FUN = function(x) c(x[1], x[-1] - mean(x[-1]) +x[1]))

,并提供:

> c
           z_a      z_q  z_q_adj
2000-01-01 100 100.0000 100.0000
2000-04-01  NA 103.4434  97.2648
2000-07-01  NA 106.4080 100.2294
2000-10-01  NA 108.6844 102.5058
2001-01-01 110 110.0000 110.0000
2001-04-01  NA 110.5723 109.7629
2001-07-01  NA 110.8719 110.0625
2001-10-01  NA 110.9840 110.1746
2002-01-01 111 111.0000 111.0000
2002-04-01  NA 111.0150 110.8299
2002-07-01  NA 111.1219 110.9368
2002-10-01  NA 111.4184 111.2333

已添加如果您想知道系列是否已插值,有些方法是:

  • 在系列中添加评论,例如comment(c) <- "Originally annual"

  • 使用命名约定,例如如果是,则将_a添加到系列名称中 最初年度:c_a <- c

  • 如果可以保留c_qc_q_adj列,那么系列就可以了 源于季度数据的两列应该是 相同或不相关,或

  • 为原始数据和季度数据保留一列

答案 2 :(得分:0)

也许我在这里遗漏了一些东西,但假设年度价值总是来自第一季度,您是否只能用mean替换aggregate来电中的min?< / p>

 > d <- aggregate(c, as.integer(format(index(c),"%Y")), min, na.rm=TRUE)
 > d
      z_a z_q
 2000 100 100
 2001 110 110
 2002 111 111