【问题标题】:Convert from annual to quarterly data, constrained to annual average从年度数据转换为季度数据,限制为年度平均值
【发布时间】:2015-12-22 06:18:48
【问题描述】:

我在 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

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

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

已编辑以包含方法 #1 由 G. Grothendieck 提出

# 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,然后转换为季度。

其他研究:

【问题讨论】:

    标签: r time-series zoo


    【解决方案1】:

    这里有点晚了,但是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 
    

    【讨论】:

      【解决方案2】:

      我们可以通过移动 4 个季度的值或移动最后 3 个季度的值来操纵 na.spline 的输出,以确保其平均为年度值。在第一种情况下,我们将从每个季度减去 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) &lt;- "Originally annual",或

      • 使用命名约定,例如将_a 添加到系列名称(如果是) 原年度:c_a &lt;- c,或

      • 如果可以同时保留 c_q 和 c_q_adj 列,那么对于系列 源自季度数据的两列应该是 相同,否则不同,或

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

      【讨论】:

        【解决方案3】:

        也许我在这里遗漏了一些东西,但假设年度价值总是来自第一季度,你不能用min 替换aggregate 调用中的mean 吗?

         > 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
        

        【讨论】:

        • 一个问题是原始年度数据可能会在几年内下降,可能导致第四季度出现最小值。此外,我希望能够获取所有生成的季度数据,并通过取平均值(而不是第一季度的值或当年的最低值)将其转换为年度值。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-01-01
        • 2021-03-08
        • 2023-03-31
        • 2020-07-16
        • 1970-01-01
        • 2020-08-14
        • 2018-12-20
        相关资源
        最近更新 更多