3

I'm fairly new to R. I've searched and tried different changes and can't seem to find anything that helps.

I am running multiple forecasts in a loop for different periods to compare the automatically generated forecast to those done by hand. I've gotten it to work manually, but now I'm trying to automate the process so that it goes through all 7 month. For some reason, when I try to execute the following code, I get this error message:

    Error in is.constant(x) : 
  (list) object cannot be coerced to type 'double'

Here is the traceback()

    > 2: is.constant(x)
      1: auto.arima(mth5[i])

Here's the code:

    #Creating data frame for loop
    year=c(2017,2017,2017,2017,2017,2017,2017)
    month=c(1, 2, 3, 4, 5, 6, 7)
    df1=data.frame(year, month)

library(forecast)
    library(zoo)
    library(sweep)
    library(timekit)
library(pacman)

    # List for storing the data being created in the loop
    additive <- list()
    mth5 <- list() 
    fit <- list() 
    #START LOOP

    for (i in 1:length(unique(df1$month)))
    {
    mth5[[i]] <- ts(mth3[c("TPCMTD")], frequency=12, start=c(2012,1), end=c(df1$year,df1$month)[i]) 
    fit[[i]] <- auto.arima(mth5[i])

    additive[[i]] <- data.frame(
        Add_Value = hw(mth5[i], h= 2, seasonal="additive")$mean[i],
          Mul_Value = hw(mth5[i], h= 2, seasonal="multiplicative")$mean[i],
        Arima_Value = forecast(fit[i], h = 2)$mean[i],
        Arima_Method = forecast(fit[i], h = 2)$method[i],
        Mth = unique(df1$month)[i]
    )
    }

    # END LOOP

the data of mth3 looks like this:

tail(mth3)
# A tibble: 6 x 2
        Date   TPCMTD
      <date>    <dbl>
1 2017-02-27 513.0
2 2017-03-30 448.4
3 2017-04-29 419.8
4 2017-05-30 512.7
5 2017-06-29 515.9
6 2017-07-30 508.2

I believe that to be all of the relevant information. If I can provide anything else, please let me know.

Jan Boldt
  • 135
  • 10
  • What is `mth5` and what is `fit`? Are they lists? – meenaparam Aug 17 '17 at 16:17
  • I think your first error is just because you swapped the rows and columns round. Rows should come first. Try `ts(mth3[i, "TPCMTD"],`. There might be more indexing errors. I have my own version running, but using your `mth3` data, my `additive` returns real values only for month 1 and month 2 - the rest are NA, but I don't know if they should have values in them. – meenaparam Aug 17 '17 at 16:33
  • Also, better to load your libraries outside of your loop - no need to have those library calls each time your loop runs. – meenaparam Aug 17 '17 at 16:34
  • @meenaparam - the mth5 is not defined in the code separately but a function of mth3. When running str(mth3), this is the result:Classes ‘tbl_df’, ‘tbl’ and 'data.frame': 67 obs. of 2 variables: $ Date : Date, format: "2012-01-30" "2012-02-28" ... $ TPCMTD: num 1231 1149 1643 2113 2145 ... – Jan Boldt Aug 17 '17 at 16:44
  • I get that part, but you must have to define it somewhere in order to make use of the index. The same way you use `additive[[i]]` and have previously defined `additive` as an empty list. Is there an equivalent `mth5` that is also an empty list that you populate as you go through the loop? – meenaparam Aug 17 '17 at 16:47
  • @meenaparam - thank you for your feedback. Much appreciated. I've moved the library outside of the loop and changed the 'ts(mth3[i, "TPCMTD"]'. The error is now:'Error: Column `1` not found' – Jan Boldt Aug 17 '17 at 16:48
  • @meenaparam - 'mth5' is not predefined as an empty list. Can this be done as 'mth5 <- null' or how should this be done – Jan Boldt Aug 17 '17 at 16:50
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/152181/discussion-between-meenaparam-and-jan-boldt). – meenaparam Aug 17 '17 at 16:50

1 Answers1

2

It looks like the code is referencing the list instead of the element stored in the list:

mth5[[i]] <- ts(mth3[c("TPCMTD")], frequency=12, start=c(2012,1), end=c(df1$year,df1$month)[i]) ' stored in mth5[[i]]
fit[[i]] <- auto.arima(mth5[i])

Change the second line to have double brackets:

fit[[i]] <- auto.arima(mth5[[i]])

This would be consistent with the error complaining that a list object is being passed to the function.

Error reproduced with following example:

mth5 <- list(WWWusage)
auto.arima(mth5[1])

Error in is.constant(x) : 
  (list) object cannot be coerced to type 'double'

The following returns results

auto.arima(mth5[[1]])

modified code based off comments

Note changes made to ts end parameter in addition to bracket changes

for (i in seq_along(unique(df1$month))) {

  mth5[[i]] <- ts(mth3[c("TPCMTD")], frequency = 12, start = c(2012, 1), end = c(df1$year[i], df1$month[i]))
  fit[[i]] <- auto.arima(mth5[[i]])

  additive[[i]] <- data.frame(Add_Value = hw(mth5[[i]], h = 2, seasonal = "additive")$mean,
                              Mul_Value = hw(mth5[[i]], h = 2, seasonal = "multiplicative")$mean,
                              Arima_Value = forecast(fit[[i]], h = 2)$mean,
                              Arima_Method = forecast(fit[[i]], h = 2)$method,
                              Mth = unique(df1$month)
  )

  }
manotheshark
  • 4,297
  • 17
  • 30
  • thank you. the 'fit[[i]]' is no containing the arima model. Unfortunately the 'additive[[i]]' is creating the error:'Error in hw(mth5[i], h = 2, seasonal = "additive") : The time series should have frequency greater than 1. ' – Jan Boldt Aug 17 '17 at 19:58
  • @JanBoldt the same would be applicable for `additive[[i]]` as all `mth5` and `fit` need to have double brackets instead of single. – manotheshark Aug 17 '17 at 20:01
  • @JanBoldt please see the following for `[[` vs `[` notations: https://stackoverflow.com/questions/1169456/the-difference-between-and-notations-for-accessing-the-elements-of-a-lis – manotheshark Aug 17 '17 at 20:06
  • The 'additive[[i]]' is now running without errors. But the output is not correct. The first [1] forecast should contain 2 lines, but only one is in the output. Number [3] and [4] etc does not contain any forecast. The 'traceback()' gives this result: ' – Jan Boldt Aug 17 '17 at 20:11
  • > traceback() 3: stop("The time series should have frequency greater than 1.") 2: hw(mth5[i], h = 2, seasonal = "additive") 1: data.frame(Add_Value = hw(mth5[i], h = 2, seasonal = "additive")$mean[i], Mul_Value = hw(mth5[i], h = 2, seasonal = "multiplicative")$mean[i], Arima_Value = forecast(fit[i], h = 2)$mean[i], Arima_Method = forecast(fit[i], h = 2)$method[i], Mth = unique(df1$month)[i]) – Jan Boldt Aug 17 '17 at 20:11