stl() декомпозиция не примет одномерный объект TS?

У меня есть проблемы с функцией декомпозиции временных рядов stl() в R, которая говорит мне, что мой объект ts не является одномерным, когда он есть на самом деле?

tsData <- ts(data = dummyData, start = c(2012,1), end = c(2014,12), frequency = 12)

> tsData
     Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
2012  22  26  34  33  40  39  39  45  50  58  64  78
2013  51  60  80  80  93 100  96 108 111 119 140 164
2014 103 112 154 135 156 170 146 156 166 176 193 204

> class(tsData)
[1] "ts"

> stl(tsData, s.window = "periodic")
Error in stl(tsData, s.window = "periodic") : 
  only univariate series are allowed

> dput(dummyData)
structure(list(index = c(22L, 26L, 34L, 33L, 40L, 39L, 39L, 45L, 
50L, 58L, 64L, 78L, 51L, 60L, 80L, 80L, 93L, 100L, 96L, 108L, 
111L, 119L, 140L, 164L, 103L, 112L, 154L, 135L, 156L, 170L, 146L, 
156L, 166L, 176L, 193L, 204L)), .Names = "index", class = "data.frame", row.names = c(NA, 
-36L))

Кто-нибудь знает, как решить эту проблему?

7 ответов

Решение

Я не уверен на 100% в том, что именно является причиной проблемы, но вы можете это исправить, передав dummyData$index в ts вместо всего объекта:

tsData2 <- ts(
  data=dummyData$index, 
  start = c(2012,1), 
  end = c(2014,12), 
  frequency = 12)
##
R>  stl(tsData2, s.window="periodic")
 Call:
 stl(x = tsData2, s.window = "periodic")

Components
            seasonal     trend   remainder
Jan 2012 -24.0219753  36.19189   9.8300831
Feb 2012 -20.2516062  37.82808   8.4235219
Mar 2012  -0.4812396  39.46428  -4.9830367
Apr 2012 -10.1034302  41.32047   1.7829612
May 2012   0.6077088  43.17666  -3.7843705
Jun 2012   4.4723800  45.22411 -10.6964877
Jul 2012  -7.6629462  47.27155  -0.6086074
Aug 2012  -1.0551286  49.50673  -3.4516016
Sep 2012   2.2193527  51.74191  -3.9612597
Oct 2012   7.3239448  55.27391  -4.5978509
Nov 2012  18.4285405  58.80591 -13.2344456
Dec 2012  30.5244146  63.70105 -16.2254684

...


Я предполагаю, что когда вы проходите data.frame к data аргумент tsнекоторые дополнительные атрибуты переносятся, и хотя это, как правило, не является проблемой для многих функций, которые принимают ts объект класса (одномерный или другой), по-видимому, это проблема для stl,

R>  all.equal(tsData2,tsData)
[1] "Attributes: < Names: 1 string mismatch >"                         
[2] "Attributes: < Length mismatch: comparison on first 2 components >"
[3] "Attributes: < Component 2: Numeric: lengths (3, 2) differ >"      
##
R>  str(tsData2)
 Time-Series [1:36] from 2012 to 2015: 22 26 34 33 40 39 39 45 50 58 ...
##
R>  str(tsData)
 'ts' int [1:36, 1] 22 26 34 33 40 39 39 45 50 58 ...
 - attr(*, "dimnames")=List of 2
  ..$ : NULL
  ..$ : chr "index"
 - attr(*, "tsp")= num [1:3] 2012 2015 12

Редактировать:

Рассматривая это немного дальше, я думаю, что проблема связана с dimnames атрибут переносится с dummyData когда он передается в целом. Обратите внимание на этот отрывок из тела stl:

if (is.matrix(x)) 
        stop("only univariate series are allowed")

и из определения matrix:

is.matrix возвращает TRUE, если x является вектором и имеет атрибут "dim" длины 2), и FALSE в противном случае

так что, хотя вы проходите stl одномерный временной ряд (оригинал tsData), что касается функции, вектор длиной 2 dimnames атрибут (т.е. matrix) не является одномерной серией. Кажется немного странным делать обработку ошибок таким образом, но я уверен, что у автора функции была очень веская причина для этого.

Чтобы избежать подобных проблем или ошибок, попытайтесь создать одномерный временной ряд, просто формируя необработанные точки данных или значения, вызывая функцию ts().

Проще говоря, вы всегда должны указывать только значения вашей переменной, а не всю структуру переменной. Позвольте мне объяснить это на очень простом примере:

Представьте, что у вас есть переменная X, которая является вектором (наиболее вероятно, импортированным или сформированным из других источников данных) размером 100x1, то есть содержит 100 значений или точек данных. Если вы хотите сделать из этого вектора одномерный временной ряд неправильным способом, как вы это сделали для своего случая:

ts (X, частота =24)

БУДЬТЕ ОСТОРОЖНЫ, ПРАВИЛЬНЫЙ способ сделать это так:

ts (X [1: 100], частота =24)

или даже так:

ts (X [1: 100,1], частота =24)

Я надеюсь, мой дорогой друг, что ты сможешь избежать этого в следующий раз, когда тебе понадобится сделать одномерный временной ряд..!!

Еще один способ исправить проблему с данными временного ряда:

stl(tsData[, 1], s.window = "periodic")

Пожалуйста, сравните

str(tsData)

с

str(tsData[, 1])

чтобы увидеть разницу.

У меня была такая же проблема, и вот как я ее исправил:

stl(x[,1], s.window = "periodic"

У меня была та же ошибка, и действительно, как упоминал nrussell, проблема заключалась в том, что я передавал временные ряды, которые также были матрицей.

(Тем не менее, $index не работал для меня, и R пожаловался, что объект ts должен иметь одно или несколько наблюдений. Я довольно новичок в R и не знаю, почему это так, но для меня сработал следующий подход)

Вы можете исправить это с помощью:

dummyVector = as.vector(t(dummyData))

А потом продолжайте получать stl:

tsData = ts(dummyVector, start=2012, end=(2014, 12), frequency = 12)
stl = stl(tsData, "periodic")

Если вы используете R Studio, вы можете видеть, что сейчас ваша временная серия указана в

Временные ряды [1:36] с 2012 по 2015: yourData

тогда как раньше, скорее всего,

int[1:3, 1:12] yourData

Возможно, проблема в том, что вы не указали end = c (гггг, мм).

Если вы используете декомпозицию, вам не нужно указывать конец =. Если вы переключаетесь на stl и используете какой-то старый код, вам нужно добавить этот параметр (если вы не использовали его с разложением).

Это исправило проблему с "одномерной" ошибкой для меня.

Когда объект фрейма данных передается в ts() функция будет приведена к числовой матрице через data.matrix()(видеть ). Функция вернет объект временного ряда, который будет матрицей класса ts с новым атрибутом tsp и исходными атрибутами фрейма данных. Эти накладки преобразуются в dimnames в виде списка из 2 атрибутов: dimnames[[1]] (первоначально 'row.names') и dimnames[[2]] (первоначально «имена»).

Когда вектор передается в ts() он вернет объект временного ряда, состоящий из вектора и атрибута tsp.

Наконец, когда объект временного ряда передается в stl() он проверит, является ли объект матрицей, с помощью is-matrix() и вернет ошибку, если это правда.

      if (is.matrix(x)) 
      stop("only univariate series are allowed")

Примечание:

  • Фрейм данных - это список векторов одинаковой длины с такими атрибутами, как «имена» и «имена строк».
  • «Объект временного ряда - это вектор или матрица с классом 'ts' и дополнительными атрибутами» ( help(ts)).

Чтобы проверить атрибуты объекта R, вызовите функции: attributes (obj) Также можно проверить размерность объекта, то есть, является ли он вектором, с помощью функций is.vector(obj), dim(obj), а также dimnames(obj).

См. Пример кода ниже:

      # Exploring stl() arguments #

# load packages ####
if (!require("pacman")) install.packages("pacman")
pacman::p_load("vctrs")
pacman::p_load("stats")

# create a data frame "df" ####
df <- vctrs::data_frame(x = 133:165, y = pi, z = seq(25.25, 1.25, by = -0.75))

# visualizing and checking attributes
head(df)
str(df)
attributes(df)
dimnames(df)

# accessing single vectors/variables with subsetting ####
# 1 - double brackets
head(df[[3]]) # return a vector
is.vector(df[[3]])
# 2 - $ operator
head(df$z) # returns a vector
is.vector(df$z)
# 3 - single brackets 
head(df[3]) # return a data frame!
is.vector(df[3])
dim(df[3])
dimnames(df[3])
attributes(df[3])

# creating a Time-Series object using ts() ####
MySeriesTs1 <- ts(df[[3]], start = c(1999, 10), frequency = 12)
MySeriesTs1
str(MySeriesTs1)
dim(MySeriesTs1) # time-series is a vector

MySeriesTs2 <- ts(df$z, start = c(1999, 10), frequency = 12)
MySeriesTs2
str(MySeriesTs2)
dim(MySeriesTs2) # time-series is a vector

MySeriesTs3 <- ts(df[3], start = c(1999, 10), frequency = 12)
MySeriesTs3
str(MySeriesTs3)
dim(MySeriesTs3) # time-series is a matrix!
dimnames(MySeriesTs3)
attributes(MySeriesTs3)

# Note: ts() accepts either a vector, a matrix or a data frame object as argument.
# here I pass the data frame with all three variables as argument to ts()
MySeriesTs <- ts(df, start = c(1999, 10), frequency = 12)
MySeriesTs
dim(MySeriesTs)
str(MySeriesTs) #returns a matrix with a List of 2 "dimnames" attributes: NULL and "x" "y" "z"

# calling stl() function ####
# stl() accepts only univariate time series as argument.
# Therefore, if the Time-Series object is a matrix, it has to be subset when passed to stl.
# passing a vector
MyDecompose1 <- stl(MySeriesTs1, s.window = 12) # RUN
# passing a vector
MyDecompose2 <- stl(MySeriesTs2, s.window = 12) # RUN
# passing a matrix
MyDecompose3 <- stl(MySeriesTs3, s.window = 12) # ERROR!
# passing a subset of a matrix
MyDecompose3 <- stl(MySeriesTs3[,"z"], s.window = 12) # RUN
# passing a matrix
MyDecompose <- stl(MySeriesTs, s.window = 12) #ERROR!
# passing a subset of a matrix
MyDecompose <- stl(MySeriesTs[,"z"], s.window = 12) #RUN
Другие вопросы по тегам