3

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醜いループを使用せずにこれを行うにはどうすればよいですか?

編集:データがdata.frameや行のリストなど、別の形式で返された場合は問題ありません。

編集:これまでに持っている3つの関数を比較するためのいくつかのコードがあります:

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
4

2 に答える 2

2

編集:(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
于 2011-11-15T17:51:10.703 に答える
1

これはループを取り除きforますが、それがもっとエレガントかどうかはわかりません: t(apply(embed(c(x,rep(NA,maxHorizon)),maxHorizon),1,rev))[2:length(x),]

編集:しかし、それははるかに高速です。

于 2011-11-15T17:45:10.253 に答える