Search code examples
rmodelrstudioforecastingets

How can I Forecast One Variable Multiple Times by One Script in R?


Suppose you have a data set that looks like this:

|Month|Food|Sales|
|01|Apple|1564|
|02|Apple|1323|
....
|12|Apple|1645|
|01|Banana|2158|

... that continues on a pattern all the way to "Zucchini".

So lets say you would like to forecast the sales in R as such:

ets <- forecast(ets(data))

How can I forecast, each of values in the "Food" column, in such a way that it will give me all of their forecasts separate?

Currently, I'm sub setting my data to only look at "Apple" and make a forecast. Then, I have to go back and change my sub setting data to "Banana" and make a forecast. I would like for each of their outputs separate, so that I may export them into Excel.

Thanks!


Solution

  • You can write a custom function that takes the name of a fruit and performs all the steps needed for a forecast, and then apply that function to a list of all the fruits you know. I have a code example here, but be aware that you may need to change lots of things based on your specific circumstances.

    First, some data:

    df <- data.frame(
      month = rep(1:12, times = 5),
      fruit = rep(c("Apple", "Banana", "Citrus", "Date", "Elderberry"), each = 12),
      sales = runif(12*5, min = 100, max = 10000)
    )
    

    Next, I want to create a custom function. In this case, the only argument I have is the type of fruit. I might want to add more arguments such as "how long do I want my forecast to be", etc. Note that this function returns the entire forecast object - you might want to select, for example, the fitted part of the model.

    forecast_custom <- function(selected_fruit) {
      df_sub <- subset(df, fruit == selected_fruit)
      ts_sub <- ts(df_sub$sales)
    
      forecast(ets(ts_sub))
    }
    

    I can run this function by telling it which fruit to forecast:

    forecast_custom("Apple")
    

    I can also use something out of the apply family to run it over all types of fruit at once.

    lapply(unique(df$fruit), forecast_custom)
    

    If you want, you can also use a map function from the purrr package instead of lapply or sapply. The map function are a bit more strict about what goes in and what comes out. For example, it would be easier to generate a nice-looking data frame using purrr:

    forecast_custom <- function(selected_fruit) {
      df_sub <- subset(df, fruit == selected_fruit)
      ts_sub <- ts(df_sub$sales)
    
      data.frame(
        fruit = selected_fruit,
        month = 13:24,
        forecasted_sales = as.numeric(forecast(ets(ts_sub))$fitted)
      )
    }
    
    > map_df(unique(df$fruit), forecast_custom)
    #>         fruit month forecasted_sales
    #> 1       Apple    13        4781.3679
    #> 2       Apple    14        4781.3330
    #> 3       Apple    15        4780.8736
    #> 4       Apple    16        4781.2790
    #> 5       Apple    17        4781.3523