管道(分解msts对象)后在数据框中使用对象存在问题

时间:2019-11-28 11:04:03

标签: r dataframe pipe tidyverse

我进行时间序列分解,我想将生成的对象保存在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)

2 个答案:

答案 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

enter image description here(v0.3.0)于2019-11-28创建

根据评论进行编辑:

要执行您在注释中提到的内容,您需要使用大括号(有关原因的解释,请参见例如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(分解表),大多数情况下,其行为类似于数据帧。因此,您可以按常规方式提取趋势列或任何一个季节性成分列。