0
votes

When running this code, I get the following error:

Error in `[<-.data.frame`(`*tmp*`, , i, value = list(x = 0.0654882985934691,  : 
new columns would leave holes after existing columns

I am trying to populate a data.frame with i number of columns, which with the output of the posted for loop should look like something like this (Excel example for convenience only):

enter image description here

The aim is to store the output of the loop in such a way that I can get the average of each column at a later stage.

What can be done to achieve this?

library(plyr)
library(forecast)
library(vars)

x <- rnorm(70)
y <- rnorm(70)

dx <- cbind(x,y)
dx <- as.ts(dx)


# Forecast Accuracy
j = 12  #Forecast horizon
k = nrow(dx)-j #length of minimum training set

prediction <- data.frame()

for (i in 1:j) { 
  trainingset <- window(dx, end = k+i-1)
  testset <- window(dx, start = k+i, end = k+j)
  fit <- VAR(trainingset, p = 2)                       
  fcast <- forecast(fit, h = j-i+1)
  fcastmean <- do.call('cbind', fcast[['mean']])
  fcastmean <- as.data.frame(fcastmean)

  prediction[,i] <- rbind(fcastmean[,1])
 }

Edit

As per the comment below, I have edited the above code to specify the first variable of fcastmean.

The error I get has however changed as a result, now being:

Error in `[<-.data.frame`(`*tmp*`, , i, value = c(-0.316529962287372,  : 
  replacement has 1 row, data has 0

Edit 2

Below is the minimum replicable version without any packages as requested in the comments. I believe that should be equivalent in terms of the question posed.

x <- rnorm(70)
y <- rnorm(70)

dx <- cbind(x,y)
dx <- as.ts(dx)

j = 12  
k = nrow(dx)-j 

prediction <- matrix(NA,j,j)

 for (i in 1:j) { 

  fcast <- as.matrix(1:(j-i+1))
  fcastmean <- fcast

  prediction[,i] <- (fcastmean)
}
1
fcastmean is two columns which you are trying to assign into one; also I think you mean for (i in 1:j) yes? - rawr
Yes @rawr, absolutely correct. Please see my edits. - youjustreadthis
1. You should probably use a matrix and not a data.frame. 2. You should pre-allocate the data.frame to the final size instead of growing it. 3. I don't understand what rbind(fcastmean[,1]) is supposed to achieve. - Roland
Each column inside a data.frame or matrix must be of the same length. That's why I wrote that you should pre-allocate to the final size. You can then assign to columns and rows. - Roland
If you come up with a more minimal example. I don't intend to install yet another package that I don't use myself. - Roland

1 Answers

1
votes

For your new example, try

sapply(1:j, function(i) `length<-`(1:(j-i+1), j))

The result is

      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
 [1,]    1    1    1    1    1    1    1    1    1     1     1     1
 [2,]    2    2    2    2    2    2    2    2    2     2     2    NA
 [3,]    3    3    3    3    3    3    3    3    3     3    NA    NA
 [4,]    4    4    4    4    4    4    4    4    4    NA    NA    NA
 [5,]    5    5    5    5    5    5    5    5   NA    NA    NA    NA
 [6,]    6    6    6    6    6    6    6   NA   NA    NA    NA    NA
 [7,]    7    7    7    7    7    7   NA   NA   NA    NA    NA    NA
 [8,]    8    8    8    8    8   NA   NA   NA   NA    NA    NA    NA
 [9,]    9    9    9    9   NA   NA   NA   NA   NA    NA    NA    NA
[10,]   10   10   10   NA   NA   NA   NA   NA   NA    NA    NA    NA
[11,]   11   11   NA   NA   NA   NA   NA   NA   NA    NA    NA    NA
[12,]   12   NA   NA   NA   NA   NA   NA   NA   NA    NA    NA    NA

`length<-`(x, j) pads x with NA until it reaches a length of j.


You can replace 1:(j-i+1) with whatever function of i you want. In the OP's original example, I am guessing something like this will work (untested):

sapply(1:j, function(i){

  trainingset <- window(dx, end = k+i-1)
  # testset   <- window(dx, start = k+i, end = k+j)
  # ^ this isn't actually used...

  fit         <- VAR(trainingset, p = 2)                       
  fcast       <- forecast(fit, h = j-i+1)
  `length<-`(fcast$mean, j)

})

function(i){...} is called an anonymous function and can be written like any other.