我在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次挖掘是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
答案 0 :(得分: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
答案 1 :(得分:1)
这摆脱了for
循环,但我不确定它是否更优雅:
t(apply(embed(c(x,rep(NA,maxHorizon)),maxHorizon),1,rev))[2:length(x),]
编辑:但速度要快得多。