【问题标题】:Rolling Calculations in R, quarterly data but the rolling should be on annual basis, cumprodR 中的滚动计算,季度数据,但滚动应按年度计算,cumprod
【发布时间】:2019-12-04 05:11:20
【问题描述】:

我有以下数据

PERIOD    GROWTH    PRICE
2011K1    0.88    0.88
2011K2    0.93    0.93
2011K3    0.96    0.96
2011K4    0.98    0.98
2012K1    1.13
2012K2    1.16
2012K3    1.12
2012K4    1.17
2013K1    1.07
2013K2    1.11
2013K3    1.03
2013K4    1.03

In 2011 PRICE = GROWTH
In 2012K1 PRICE = GROWTH[2012K1]*avg(PRICE in 2011)
In 2012K2 PRICE = GROWTH[2012K2]*avg(PRICE in 2011)
In 2012K3 PRICE = GROWTH[2012K3]*avg(PRICE in 2011)
In 2012K4 PRICE = GROWTH[2012K4]*avg(PRICE in 2011)
In 2013K1 PRICE = GROWTH[2013K1]*avg(PRICE in 2012)
In 2013K2 PRICE = GROWTH[2013K2]*avg(PRICE in 2012)
In 2013K3 PRICE = GROWTH[2013K3]*avg(PRICE in 2012)
In 2013K4 PRICE = GROWTH[2013K4]*avg(PRICE in 2012)

...

在每个季度,上一季度的平均价格用于乘以该特定季度的增长,即同一年内的每个季度乘以相同的平均价格,即前一年的平均价格。

我尝试使用 cumprod(),但当我的数据是季度数据时,它未能使其每年滚动。我可以做for循环,问题是我必须为成千上万的产品做这个。

有什么建议吗?

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    给定最后注释中的数据计算季度,qtr,然后遍历计算 PRICE 的行。没有使用任何包。

    run <- function(DF, k = 4) {
      nr <- nrow(DF)
      DF$qtr <- 1:k
      for(i in (k+1):nr) DF$PRICE[i] <- DF$GROWTH[i] * mean(DF$PRICE[i-DF$qtr[i]-(k-1):0])
      DF
    }
    run(DF)
    

    给予:

       PERIOD GROWTH    PRICE qtr
    1  2011K1   0.88 0.880000   1
    2  2011K2   0.93 0.930000   2
    3  2011K3   0.96 0.960000   3
    4  2011K4   0.98 0.980000   4
    5  2012K1   1.13 1.059375   1
    6  2012K2   1.16 1.087500   2
    7  2012K3   1.12 1.050000   3
    8  2012K4   1.17 1.096875   4
    9  2013K1   1.07 1.148578   1
    10 2013K2   1.11 1.191516   2
    11 2013K3   1.03 1.105641   3
    12 2013K4   1.03 1.105641   4
    

    注意

    Lines <- "PERIOD    GROWTH    PRICE
    2011K1    0.88    0.88
    2011K2    0.93    0.93
    2011K3    0.96    0.96
    2011K4    0.98    0.98
    2012K1    1.13
    2012K2    1.16
    2012K3    1.12
    2012K4    1.17
    2013K1    1.07
    2013K2    1.11
    2013K3    1.03
    2013K4    1.03"
    DF.orig <- read.table(text = Lines, header = TRUE, fill = TRUE, as.is = TRUE)
    

    【讨论】:

    • @Grothendieck,感谢您的回答,您的程序完成了这项工作,您能否概括一下,我的意思是我们有一个简短的样本,我有数千种产品,我的数据是长格式的,我想在 group_by 语句中使用您的代码并将其传递给 dplyr 的 mutate。
    • 已经变成函数了。
    • 我编辑了 DF.original 以包含一个分组变量 PRODUCT 并将它们堆叠在一起,我想知道如何将您的函数与 group_by(PRODUCT) %>% mutate(PRICE =乐趣(),...)
    • 已经回答的问题请不要再更改。使用原始数据,我们可以添加一个 PRODUCT 列,例如 DF$PRODUCT &lt;- 1 然后 DF %&gt;% group_by(PRODUCT) %&gt;% do(run(.)) %&gt;% ungroup 尽管这仅显示一种产品,但对于许多产品来说都是相同的。关键点是,点通常指的是整个数据框,即使在group_by 内也是如此,但在do 内,点仅指当前组中数据框的行。
    • 感谢您的意见,因为您的回答,我走了很长一段路,我理解您关于不改变问题的观点,我不知道如何撤消,现在由审阅者决定.
    【解决方案2】:

    -- 更新:意识到这个答案会产生不正确的结果--@Rebecca

    另一种选择:)

    # I'll use tidyverse for this approach.
    library(tidyverse)
    
    # First, I'll generate a dataset similar to yours.
    data <- tibble(year = rep(2011:2013, each=4),
                   quarter = rep(1:4, times=3),
                   growth_quarter = c(0.88,
                              0.93,
                              0.96,
                              0.98,
                              1.13,
                              1.16,
                              1.12,
                              1.17,
                              1.07,
                              1.11,
                              1.03,
                              1.03))
    
    # Create a new tibble with desired output.
    data_m <- data %>%
    
      # Find the average growth per year.
      group_by(year) %>%
      mutate(growth_annual = mean(growth_quarter)) %>%
    
      # Remove grouping by year for next calculations.
      ungroup() %>%
    
      # Organize by year and quarter to ensure consistent results for calculation in next step.
      arrange(year, quarter) %>%
    
      # Multiply current quarter's growth by last year's average growth.
      mutate(growth_quarter*lag(growth_annual))
    

    如果您有任何问题,请告诉我!

    【讨论】:

    • 我喜欢你的方法,我更喜欢 tidyverse 的方式,因为我有成千上万的产品,我的数据是长格式的。您的程序没有按照我的意图进行,今年的增长率必须乘以上一年的平均 PRICE,而不是平均增长率。​​span>
    • 第 6 行的值应该是 1.16 * ( 0.88 +0.93+ 0.96+ 0.98)/4 = 1.0875 但不是。
    • 感谢您的关注!我已经玩了一段时间,但我不确定如何在没有 for 循环的情况下完成此操作 - 计算建立在自身之上。不过,如果其他人有想法,我会全力以赴。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-27
    • 1970-01-01
    • 2021-03-12
    • 2011-10-19
    • 2020-10-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多