2011-11-15 3 views
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 

, 우리는 그래서 우리의 최종 행렬은 24 개의 행이 25 개 관측 시계열을 가지고있다. 1 행부터 시작하여 다음 12 회의 축약은 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 

답변

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 
+0

내 x가 시퀀스가 ​​아니면 어떻게됩니까? 'x <- ts (rnorm (25), start = 2000, frequency = 12)와 같은 벡터 인 경우 – Zach

+0

무슨 뜻인지 잘 모르겠습니다. 'seq_along (x)'는 벡터'c (1,2,3 ..., 24,25)'를 반환합니다. 대신 다른 것을 원하니? –

+0

최종 행렬에서 인덱스가 아닌 x의 실제 값을 반환하고 싶습니다. 그래서 당신의 방법은'apply (actuals, 2, function (a) x [a])'와 같은 마지막 단계를 필요로합니다. 나는 그것을 추가하는 것은 꽤 사소한 것 같다. – Zach

1

이것은 for 루프를 제거한다,하지만 난 그게 더 우아 있는지 확실하지 않습니다 : t(apply(embed(c(x,rep(NA,maxHorizon)),maxHorizon),1,rev))[2:length(x),]

편집 : 훨씬 빠릅니다.