我有一堆时间序列数据彼此堆叠在一个数据帧中;一个国家/地区的每个地区一个系列。我想将<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)
答案 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
...