Создание матрицы будущих значений для временного ряда - PullRequest
3 голосов
/ 15 ноября 2011

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

x <- ts(1:25,start=2000, frequency=12)
maxHorizon <- 12

freq <- frequency(x)
st <- tsp(x)[1]-(1/freq)

actuals <- matrix(NA,length(x)-1,maxHorizon)
for(i in seq(1, (length(x)-1))) {
    xnext <- window(x, start=st+(i+1)/freq, end=st+(i+maxHorizon)/freq)
    actuals[i,1:length(xnext)] <- xnext
}
actuals

В этом случае у нас есть временной ряд с 25 наблюдениями, поэтому наша окончательная матрица имеет 24 строки. Начиная со строки 1, следующие 12 ovbservations 2-13. Строка 2 - 3-13 и т. Д. В конце матрицы мы заполняем ее значениями NA.

> x
     Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
2000   1   2   3   4   5   6   7   8   9  10  11  12
2001  13  14  15  16  17  18  19  20  21  22  23  24
2002  25

> actuals
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
 [1,]    2    3    4    5    6    7    8    9   10    11    12    13
 [2,]    3    4    5    6    7    8    9   10   11    12    13    14
 [3,]    4    5    6    7    8    9   10   11   12    13    14    15
 [4,]    5    6    7    8    9   10   11   12   13    14    15    16
 [5,]    6    7    8    9   10   11   12   13   14    15    16    17
 [6,]    7    8    9   10   11   12   13   14   15    16    17    18
 [7,]    8    9   10   11   12   13   14   15   16    17    18    19
 [8,]    9   10   11   12   13   14   15   16   17    18    19    20
 [9,]   10   11   12   13   14   15   16   17   18    19    20    21
[10,]   11   12   13   14   15   16   17   18   19    20    21    22
[11,]   12   13   14   15   16   17   18   19   20    21    22    23
[12,]   13   14   15   16   17   18   19   20   21    22    23    24
[13,]   14   15   16   17   18   19   20   21   22    23    24    25
[14,]   15   16   17   18   19   20   21   22   23    24    25    NA
[15,]   16   17   18   19   20   21   22   23   24    25    NA    NA
[16,]   17   18   19   20   21   22   23   24   25    NA    NA    NA
[17,]   18   19   20   21   22   23   24   25   NA    NA    NA    NA
[18,]   19   20   21   22   23   24   25   NA   NA    NA    NA    NA
[19,]   20   21   22   23   24   25   NA   NA   NA    NA    NA    NA
[20,]   21   22   23   24   25   NA   NA   NA   NA    NA    NA    NA
[21,]   22   23   24   25   NA   NA   NA   NA   NA    NA    NA    NA
[22,]   23   24   25   NA   NA   NA   NA   NA   NA    NA    NA    NA
[23,]   24   25   NA   NA   NA   NA   NA   NA   NA    NA    NA    NA
[24,]   25   NA   NA   NA   NA   NA   NA   NA   NA    NA    NA    NA

Как я могу сделать это без использования уродливой петли for?

edit: было бы хорошо, если бы данные были возвращены в другом формате, таком как data.frame или даже список строк.

edit: вот код для сравнения трех функций, которые у нас есть:

rm(list = ls(all = TRUE))

zach1 <- function(x,maxHorizon) {
    freq <- frequency(x)
    st <- tsp(x)[1]-(1/freq)

    actuals <- matrix(NA,length(x)-1,maxHorizon)

    for(i in seq(1, (length(x)-1))) {
        xnext <- window(x, start=st+(i+1)/freq, end=st+(i+maxHorizon)/freq)
        actuals[i,1:length(xnext)] <- xnext
    }

    actuals
}

zach2 <- function(x,maxHorizon) {
    t(apply(embed(c(x,rep(NA,maxHorizon)),maxHorizon),1,rev))[2:length(x),]
}

josh1 <- function(x,maxHorizon) {
    actuals <- outer(seq_along(x), seq_len(maxHorizon), FUN="+")
    actuals[actuals > length(x)] <- NA
    actuals <- actuals[1:(length(x)-1),]
    actuals <- apply(actuals,2,function(a) x[a])
    actuals
}

x <- ts(rnorm(10000),start=2000, frequency=12)

> system.time(actuals1 <- zach1(x, 6))
   user  system elapsed 
  11.81    0.00   11.93 

> system.time(actuals2 <- zach2(x, 6))
   user  system elapsed 
   0.15    0.00    0.16 

> system.time(actuals3 <- josh1(x, 6))
   user  system elapsed 
      0       0       0 

> all.equal(actuals1,actuals2)
[1] TRUE
> all.equal(actuals1,actuals3)
[1] TRUE

Ответы [ 2 ]

2 голосов
/ 15 ноября 2011

РЕДАКТИРОВАНИЕ: Чтобы заполнить матрицу элементами x (а не их индексами), вы можете передать outer() «анонимную функцию» вашего собственного устройства. Это должно сделать трюк:

# Trying it out
x <- ts(rnorm(25),start=2000, frequency=12)
maxHorizon <- 12

actuals <- outer(seq_along(x), seq_len(maxHorizon), 
                 FUN = function(X,Y) {x[X+Y]}
)

tail(actuals)
#             [,1]       [,2]       [,3]       [,4]      [,5] [,6] [,7] [,8] [,9]
# [20,] -1.2729640 -0.4983060  0.6199497 -2.0999648 0.1673402   NA   NA   NA   NA
# [21,] -0.4983060  0.6199497 -2.0999648  0.1673402        NA   NA   NA   NA   NA
# [22,]  0.6199497 -2.0999648  0.1673402         NA        NA   NA   NA   NA   NA
# [23,] -2.0999648  0.1673402         NA         NA        NA   NA   NA   NA   NA
# [24,]  0.1673402         NA         NA         NA        NA   NA   NA   NA   NA
# [25,]         NA         NA         NA         NA        NA   NA   NA   NA   NA
#       [,10] [,11] [,12]
# [20,]    NA    NA    NA
# [21,]    NA    NA    NA
# [22,]    NA    NA    NA
# [23,]    NA    NA    NA
# [24,]    NA    NA    NA
# [25,]    NA    NA    NA
1 голос
/ 15 ноября 2011

Это избавляет от цикла for, но я не уверен, что он более элегантный: t(apply(embed(c(x,rep(NA,maxHorizon)),maxHorizon),1,rev))[2:length(x),]

edit: хотя это намного быстрее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...