R语言 同比增长率反推系列

cunj1qz1  于 2023-03-27  发布在  其他
关注(0)|答案(1)|浏览(183)

我有一个包含GDP数据和同比增长率的数据集。增长率序列的开始时间早于GDP数据,因此我想使用它们递归地回溯GDP序列以扩大其样本量。
每个缺失值(例如2021年:第四季度)应该等于前一年同一季度的值(2022年:第四季度)除以该未来时期的同比增长率(i.e. x_t = x_{t+4} / g_{t+4})。由于每个新值都取决于“未来”值,因此我需要一种递归计算的方法。
我已经使用循环创建了所需的输出,但更喜欢在dplyr工作流中使用purrr::accumulate函数的解决方案。

library(dplyr)

# Dummy data set
set.seed(123)
df <- data.frame(date = seq(as.Date("2018/1/1"), by = "quarter", length.out = 20),
                 gdp = c(rep(NA, 16), cumprod(runif(4, 0.95, 1.05)) * 1000),
                 growth_rate = rnorm(5, mean = 3, sd = 1)) %>% 
  mutate(growth_rate = 1 + growth_rate/100) %>% 
  arrange(desc(date)) # Sorting the data descending to make the loop work

# for loop which gets a solution
for (i in 5:length(df$growth_rate)){
  df[i, "gdp"] <- df[i-4, "gdp"] / df[i-4, "growth_rate"]
}
db2dz4w8

db2dz4w81#

在您的示例中,您将分别处理每个季度的时间序列,每个季度都有一个不同的初始值,您希望从中进行外推。
但是,accumulate()只接受一个初始值作为其.init参数。因此,您必须按月拆分(或分组)数据,根据相应的初始值计算GDP值,最后合并结果。
下面是一个accumulate()的例子,用于建立直觉:

# single quarter
df1 <- df |> filter(lubridate::month(date) == 10)

accumulate(df1$growth_rate,
           `/`,
           .init = df1$gdp[1])
#> [1] 1036.0279 1001.3713  957.7120  929.1814  900.9869  860.4177

创建于2023-03-21带有reprex v2.0.2
然后,具有分组 Dataframe 的整个工作流可以看起来像这样:

library(lubridate)
library(tidyverse)

set.seed(123)
df <- data.frame(date = seq(as.Date("2018/1/1"), by = "quarter", length.out = 20),
                 gdp = c(rep(NA, 16), cumprod(runif(4, 0.95, 1.05)) * 1000),
                 growth_rate = rnorm(5, mean = 3, sd = 1)) %>% 
  mutate(growth_rate = 1 + growth_rate/100) %>% 
  arrange(desc(date)) # Sorting the data descending to make the loop work

df |>
  group_by(month = month(date)) |>
  mutate(new = accumulate(
    head(growth_rate, -1), `/`, .init = nth(gdp, 1)
  ))
#> # A tibble: 20 × 5
#> # Groups:   month [4]
#>    date         gdp growth_rate month   new
#>    <date>     <dbl>       <dbl> <dbl> <dbl>
#>  1 2022-10-01 1036.        1.03    10 1036.
#>  2 2022-07-01  998.        1.05     7  998.
#>  3 2022-04-01 1007.        1.03     4 1007.
#>  4 2022-01-01  979.        1.03     1  979.
#>  5 2021-10-01   NA         1.05    10 1001.
#>  6 2021-07-01   NA         1.03     7  953.
#>  7 2021-04-01   NA         1.05     4  976.
#>  8 2021-01-01   NA         1.03     1  950.
#>  9 2020-10-01   NA         1.03    10  958.
#> 10 2020-07-01   NA         1.05     7  921.
#> 11 2020-04-01   NA         1.03     4  932.
#> 12 2020-01-01   NA         1.05     1  921.
#> 13 2019-10-01   NA         1.03    10  929.
#> 14 2019-07-01   NA         1.03     7  881.
#> 15 2019-04-01   NA         1.05     4  901.
#> 16 2019-01-01   NA         1.03     1  879.
#> 17 2018-10-01   NA         1.05    10  901.
#> 18 2018-07-01   NA         1.03     7  855.
#> 19 2018-04-01   NA         1.03     4  862.
#> 20 2018-01-01   NA         1.05     1  850.

创建于2023-03-21带有reprex v2.0.2
当然,这里不需要accumulate(),因为已经有一个函数来计算基数R的累积乘积(cumprod()):

df |>
  group_by(month = month(date)) |>
  mutate(new = cumprod(c(nth(gdp, 1), head(growth_rate, -1)^(-1))))

相关问题