使用purrr迭代时间序列数据

时间:2018-08-12 20:39:17

标签: r time-series purrr

我有一堆时间序列数据彼此堆叠在一个数据帧中;一个国家/地区的每个地区一个系列。我想将<a href="{{ route('about', ['uk']) }}"> 函数(来自https://yourdomain.com/uk/about 包)应用于每个系列,以使该系列季节性调整。为此,我首先必须将系列转换为seas()类。我正在努力使用seasonal来完成所有这些工作。

这是一个最小的工作示例:

ts

对于每个区域(用数字索引),我想执行以下操作。这是第一个区域作为示例:

purrr

然后我想将输出(即,多个tem4数据帧,每个区域一个)以及区域和四分之一标识符堆叠在一起。

因此,区域1的输出开始是这样:

library(seasonal)
library(tidyverse)
set.seed(1234)
df <- data.frame(region = rep(1:10, each = 20),
             quarter = rep(1:20, 10),
             var = sample(5:200, 200, replace = T))

第2区的数据将低于此等。

我从以下内容开始,但到目前为止还没有运气。基本上,我正在努力使时间序列更加混乱:

tem1 <- df %>% filter(region==1)
tem2 <- ts(data = tem1$var, frequency = 4, start=c(1990,1)) 
tem3 <- seas(tem2)
tem4 <- as.data.frame(tem3$data)

2 个答案:

答案 0 :(得分:5)

我对季节性调整部分了解不多,所以可能有些事情我错过了,但是我可以帮助您将计算结果移至map友好型函数中。

按区域分组后,您可以嵌套数据,因此每个区域都有一个嵌套的数据框。然后,您可以运行与以前基本相同的代码,但是可以在map中的函数中运行。取消嵌套结果列会为您提供一个长条形的调整数据框。

就像我说的那样,我没有专门知识来知道是否期望最后两列中包含NA

编辑:基于@wibeasley关于保留quarter列的问题,我添加了一个mutate,该列添加了嵌套数据框中列出的四分之一列。

library(seasonal)
library(tidyverse)
set.seed(1234)
df <- data.frame(region = rep(1:10, each = 20),
                 quarter = rep(1:20, 10),
                 var = sample(5:200, 200, replace = T))

df %>%
  group_by(region) %>%
  nest() %>%
  mutate(data.ts = map(data, function(x) {
    tem2 <- ts(x$var, frequency = 4, start = c(1990, 1))
    tem3 <- seas(tem2)
    as.data.frame(tem3$data) %>%
      mutate(quarter = x$quarter)
  })) %>%
  unnest(data.ts)
#> # A tibble: 200 x 8
#>    region final seasonaladj trend irregular quarter seasonal adjustfac
#>     <int> <dbl>       <dbl> <dbl>     <dbl>   <int>    <dbl>     <dbl>
#>  1      1    27          27  97.0    -68.0        1       NA        NA
#>  2      1   126         126  97.0     27.9        2       NA        NA
#>  3      1   124         124  97.0     27.1        3       NA        NA
#>  4      1   127         127  97.0     30.6        4       NA        NA
#>  5      1   173         173  97.0     75.0        5       NA        NA
#>  6      1   130         130  97.0     32.1        6       NA        NA
#>  7      1     6           6  97.0    -89.0        7       NA        NA
#>  8      1    50          50  97.0    -46.5        8       NA        NA
#>  9      1   135         135  97.0     36.7        9       NA        NA
#> 10      1   105         105  97.0      8.81      10       NA        NA
#> # ... with 190 more rows

我也考虑了不嵌套的情况,而是尝试使用split进行嵌套。将该数据帧列表传递到imap_dfr中,让我获取数据帧的每个分割片段及其名称(在本例中为region的值),然后将所有返回的rbind返回一起成为一个数据帧有时我只是因为看不到正在发生的事情而回避嵌套数据,所以这是一种更透明的选择。

df %>%
  split(.$region) %>%
  imap_dfr(function(x, reg) {
    tem2 <- ts(x$var, frequency = 4, start = c(1990, 1))
    tem3 <- seas(tem2)
    as.data.frame(tem3$data) %>%
      mutate(region = reg, quarter = x$quarter)
  }) %>%
  select(region, quarter, everything()) %>%
  head()
#>   region quarter final seasonaladj trend irregular seasonal adjustfac
#> 1      1       1    27          27 96.95 -67.97274       NA        NA
#> 2      1       2   126         126 96.95  27.87378       NA        NA
#> 3      1       3   124         124 96.95  27.10823       NA        NA
#> 4      1       4   127         127 96.95  30.55077       NA        NA
#> 5      1       5   173         173 96.95  75.01353       NA        NA
#> 6      1       6   130         130 96.95  32.10669       NA        NA

reprex package(v0.2.0)于2018-08-12创建。

答案 1 :(得分:1)

我将所有操作放入f()内,然后用purrr::map_df()进行调用。重新加入quarter是骇客。

f <- function( .region ) {
  d <- df %>% 
    dplyr::filter(region == .region)
  y <- d %>% 
    dplyr::pull(var) %>% 
    ts(frequency = 4, start=c(1990,1)) %>% 
    seas() 

  y$data %>% 
    as.data.frame() %>% 
    # dplyr::select(-seasonal, -adjustfac) %>% 
    dplyr::mutate(
      quarter  = d$quarter
    )
}

purrr::map_df(1:10, f, .id = "region")

结果:

    region     final seasonaladj     trend     irregular quarter     seasonal   adjustfac
1        1  27.00000    27.00000  96.95000 -6.797279e+01       1           NA          NA
2        1 126.00000   126.00000  96.95000  2.787381e+01       2           NA          NA
3        1 124.00000   124.00000  96.95000  2.710823e+01       3           NA          NA
4        1 127.00000   127.00000  96.95000  3.055075e+01       4           NA          NA
5        1 173.00000   173.00000  96.95000  7.501355e+01       5           NA          NA
6        1 130.00000   130.00000  96.95000  3.210672e+01       6           NA          NA
7        1   6.00000     6.00000  96.95000 -8.899356e+01       7           NA          NA
8        1  50.00000    50.00000  96.95000 -4.647254e+01       8           NA          NA
9        1 135.00000   135.00000  96.95000  3.671077e+01       9           NA          NA
10       1 105.00000   105.00000  96.95000  8.806955e+00      10           NA          NA
...
96       5  55.01724    55.01724  60.25848  9.130207e-01      16    1.9084928   1.9084928
97       5  60.21549    60.21549  59.43828  1.013076e+00      17    1.0462424   1.0462424
98       5  58.30626    58.30626  58.87065  9.904130e-01      18    0.1715082   0.1715082
99       5  61.68175    61.68175  58.07827  1.062045e+00      19    1.0537962   1.0537962
100      5  59.30138    59.30138  56.70798  1.045733e+00      20    2.5294523   2.5294523
...