user20203146
user20203146

Reputation: 498

Unable to Write a forecast/list into a Data frame using a Loop in R

I am trying to add forecast generated into a new data frame within a for loop so that the first set of time series, which goes into the Holt-Winters function and the forecast for that is generated (the column mean) and stored in a dataset and then the next column is added as time series and the same happens till the end.

The error that I am coming across is: Error in `[<-.data.frame`(`*tmp*`, , i, value = NULL) : new columns would leave holes after existing columns

Can someone help me with the issue and let me know how to resolve this issue and get the output based on my expectation?

library(dplyr)
library(tidyverse)
library(tidyr)
library(tidymodels)
library(forecast)
library(prophet)
library(readxl)
library(writexl)
library(tibble)

pd <- readxl::read_excel("C:/X/X/X/Dummy.xlsx")
colnames(pd)[1]="ds"

colnames(pd)
pd1 <- pd %>% select(`X1`,`X2`,`X3`)
    
for(i in 1:ncol(pd1))
{
  Y1 <- ts(data = pd1[,i],
           frequency = 12,
           start = c(2019,1),
           end = c(2022,8))
  print(Y1)
  
  Model_Y1 = HoltWinters(x=Y1,
                         seasonal = 'additive')
  
  Predictions_Y1= forecast(Model_Y1,
                               h=6)
  
  Output_Y1[,i] = Predictions_Y1$Mean
}

The Input dataset pd which I am working with is:

structure(list(ds = c("2019-01-01", "2019-02-01", "2019-03-01", 
"2019-04-01", "2019-05-01", "2019-06-01", "2019-07-01", "2019-08-01", 
"2019-09-01", "2019-10-01", "2019-11-01", "2019-12-01", "2020-01-01", 
"2020-02-01", "2020-03-01", "2020-04-01", "2020-05-01", "2020-06-01", 
"2020-07-01", "2020-08-01", "2020-09-01", "2020-10-01", "2020-11-01", 
"2020-12-01", "2021-01-01", "2021-02-01", "2021-03-01", "2021-04-01", 
"2021-05-01", "2021-06-01", "2021-07-01", "2021-08-01", "2021-09-01", 
"2021-10-01", "2021-11-01", "2021-12-01", "2022-01-01", "2022-02-01", 
"2022-03-01", "2022-04-01", "2022-05-01", "2022-06-01", "2022-07-01", 
"2022-08-01"), X1 = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 
85, 72, 111, 96, 50, 95, 48, 87, 75, 249, 173, 74, 86, 127, 209, 
92, 137, 49, 84, 75, 73, 376, 196, 91, 107, 124, 177, 244, 275, 
100, 176), X2 = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 29, 243, 
281, 262, 283, 0, 264, 104, 289, 41, 76), X3 = c(0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 157, 171, 377, 409, 375, 314, 253, 322, 
130, 472, 115, 179)), class = c("tbl_df", "tbl", "data.frame"
), row.names = c(NA, -44L))

Upvotes: 0

Views: 46

Answers (1)

danlooo
danlooo

Reputation: 10637

The data frame Predictions_Y1 must be defined before the for loop, otherwise it can not be found.

However, you just want to apply the function HoltWinters to every column of pd1 and store the results in a new data frame. This can be best archived using lapply, e.g. to get the predictions in a new combined table:

pd1 |>
  lapply(function(col) {
  Y1 <- ts(
    data = col,
    frequency = 12,
    start = c(2019, 1),
    end = c(2022, 8)
  )
  
  HoltWinters(
    x = Y1,
    seasonal = "additive"
  )$fitted
}) |>
  enframe() |>
  unnest(value)
# A tibble: 96 × 2
#   name  value[,"xhat"] [,"level"] [,"trend"] [,"season"]
#   <chr> <ts>           <ts>       <ts>       <ts>       
# 1 X1    -35.74199      -11.253788 7.407634   -31.895833 
# 2 X1     52.61996        3.066494 7.407634    42.145833 
# 3 X1     46.89648       15.968013 7.407634    23.520833 
# 4 X1     90.81340       27.634934 7.407634    55.770833 
# 5 X1     73.14607       38.467606 7.407634    27.270833 
# 6 X1     20.84797       49.752840 7.407634   -36.312500 

Upvotes: 1

Related Questions