我进行时间序列分解,我想将生成的对象保存在dataframe
中。如果我将结果存储在一个对象中,然后用它来制作dataframe
,它将起作用:
# needed packages
library(tidyverse)
library(forecast)
# some "time series"
vec <- 1:1000 + rnorm(1000)
# store pipe results
pipe_out <-
# do decomposition
decompose(msts(vec, start= c(2001, 1, 1), seasonal.periods= c(7, 365.25))) %>%
# relevant data
.$seasonal
# make a dataframe with the stored seasonal data
data.frame(ts= pipe_out)
但与单线执行相同操作会失败:
decompose(msts(vec, start= c(2001, 1, 1), seasonal.periods= c(7, 365.25))) %>%
data.frame(ts= .$seasonal)
我得到了错误
as.data.frame.default(x [[i]],可选= TRUE,stringsAsFactors = stringsAsFactors)中的错误: 无法将“ decomposed.ts”类强制转换为data.frame
我认为管道只是向前移动了最后一步中出现的内容,从而节省了我们将这些内容存储在对象中的时间。如果是这样,两个代码难道不应该得到相同的输出吗?
编辑(根据评论)
第一个代码有效,但这是一个不好的解决方案,因为如果要提取分解的时间序列的所有向量,则需要分多个步骤进行。像下面这样会更好:
decompose(msts(vec, start= c(2001, 1, 1),
seasonal.periods= c(7, 365.25))) %>%
data.frame(seasonal= .$seasonal, x=.$x, trend=.$trend, random=.$random)
答案 0 :(得分:1)
根据您的示例尚不清楚要提取$x
还是$seasonal
。无论哪种方式,都可以根据需要使用基本的`[[`()
函数或extract2()
的别名magrittr
提取列表的一部分。然后,在最后一步中创建.
时应使用data.frame
。
对代码进行一些整理以使其与管道保持一致,可以完成以下工作:
library(magrittr)
library(tidyverse)
library(forecast)
vec <- 1:1000 + rnorm(1000)
vec %>%
msts(start = c(2001, 1, 1), seasonal.periods= c(7, 365.25)) %>%
decompose %>%
`[[`("seasonal") %>%
# extract2("seasonal") %>% # Another option, uncomment if preferred
data.frame(ts = .) %>%
head # Just for the reprex, remove as required
#> ts
#> 1 -1.17332998
#> 2 0.07393265
#> 3 0.37631946
#> 4 0.30640395
#> 5 1.04279779
#> 6 0.20470768
根据评论进行编辑:
要执行您在注释中提到的内容,您需要使用大括号(有关原因的解释,请参见例如reprex package)。因此,以下工作原理:
library(magrittr)
library(tidyverse)
library(forecast)
vec <- 1:1000 + rnorm(1000)
vec %>%
msts(start= c(2001, 1, 1), seasonal.periods = c(7, 365.25)) %>%
decompose %>%
{data.frame(seasonal = .$seasonal,
trend = .$trend)} %>%
head
#> seasonal trend
#> 1 -0.4332034 NA
#> 2 -0.6185832 NA
#> 3 -0.5899566 NA
#> 4 0.7640938 NA
#> 5 -0.4374417 NA
#> 6 -0.8739449 NA
但是,对于您的特定用例,使用magrittr::extract
然后使用bind_cols
可能会更清晰,更容易:
vec %>%
msts(start= c(2001, 1, 1), seasonal.periods = c(7, 365.25)) %>%
decompose %>%
magrittr::extract(c("seasonal", "trend")) %>%
bind_cols %>%
head
#> # A tibble: 6 x 2
#> seasonal trend
#> <dbl> <dbl>
#> 1 -0.433 NA
#> 2 -0.619 NA
#> 3 -0.590 NA
#> 4 0.764 NA
#> 5 -0.437 NA
#> 6 -0.874 NA
由here(v0.3.0)于2019-11-29创建
答案 1 :(得分:1)
使用每日数据,decompose()
不能很好地工作,因为它只能处理年度季节性,并且对它的估计相对较差。如果数据涉及人类行为,则可能具有每周和每年的季节性模式。
此外,msts
对象也不适合用于日常数据,因为它们没有显式存储日期。
我建议您将tsibble
对象用于STL分解。这是使用您的数据的示例。
library(tidyverse)
library(tsibble)
library(feasts)
mydata <- tsibble(
day = as.Date(seq(as.Date("2001-01-01"), length=1000, by=1)),
vec = 1:1000 + rnorm(1000)
)
#> Using `day` as index variable.
mydata
#> # A tsibble: 1,000 x 2 [1D]
#> day vec
#> <date> <dbl>
#> 1 2001-01-01 0.161
#> 2 2001-01-02 2.61
#> 3 2001-01-03 1.37
#> 4 2001-01-04 3.15
#> 5 2001-01-05 4.43
#> 6 2001-01-06 7.35
#> 7 2001-01-07 7.10
#> 8 2001-01-08 10.0
#> 9 2001-01-09 9.16
#> 10 2001-01-10 10.2
#> # … with 990 more rows
# Compute a decomposition
mydata %>% STL(vec)
#> # A dable: 1,000 x 7 [1D]
#> # STL Decomposition: vec = trend + season_year + season_week + remainder
#> day vec trend season_year season_week remainder season_adjust
#> <date> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 2001-01-01 0.161 14.7 -14.6 0.295 -0.193 14.5
#> 2 2001-01-02 2.61 15.6 -14.2 0.0865 1.04 16.7
#> 3 2001-01-03 1.37 16.6 -15.5 0.0365 0.240 16.9
#> 4 2001-01-04 3.15 17.6 -13.0 -0.0680 -1.34 16.3
#> 5 2001-01-05 4.43 18.6 -13.4 -0.0361 -0.700 17.9
#> 6 2001-01-06 7.35 19.5 -12.4 -0.122 0.358 19.9
#> 7 2001-01-07 7.10 20.5 -13.4 -0.181 0.170 20.7
#> 8 2001-01-08 10.0 21.4 -12.7 0.282 1.10 22.5
#> 9 2001-01-09 9.16 22.2 -13.8 0.0773 0.642 22.9
#> 10 2001-01-10 10.2 22.9 -12.7 0.0323 -0.0492 22.9
#> # … with 990 more rows
由reprex package(v0.3.0)于2019-11-30创建
输出是一个dable
(分解表),大多数情况下,其行为类似于数据帧。因此,您可以按常规方式提取趋势列或任何一个季节性成分列。