Search code examples
rmagrittr

Unable to loop using over ARMA models using magrittr forward pipe


I have the following piece of code. It seems very simple it just loops over various combinations of ARMA models AR(1), MA(0) then AR(1) MA(2) and so on.

load.or.install <- function(package.names) {
    is.installed <- function(mypkg) is.element(mypkg, installed.packages()[, 1])

    for (package.name in package.names) {
        if (!is.installed(package.name)) {
            install.packages(package.name)
        }
        library(package.name, character.only = TRUE, quietly = TRUE, verbose = FALSE)
    }
}

load.or.install(c("tseries", "forecast", "ggplot2", "dplyr", "magrittr", "rdatamarket"))

max.p <- 8 #  maximum number of AR terms
max.q <- 7 #  maximum number of MA terms
    #import data 
ausgdp <- as.ts(dmseries("http://data.is/1jDQwpr")[, 1]) %>% log() %>% diff(difference = 1)


model.orders <- as.matrix(expand.grid(AR = 0:max.p, DIF = 0, MA = 0:max.q))
models <- list()
1:nrow(model.orders) %>% {
    models[[.]] <- Arima(ausgdp, order = model.orders[.,], include.constant = T, method = "ML")
}

however I get the following error msg.

Error in stats::arima(x = x, order = order, seasonal = seasonal, xreg = xreg,  : 
  'order' must be a non-negative numeric vector of length 3

if I run the following command outside the loop it works;

Arima(ausgdp, order = model.orders[1,], include.constant = T, method = "ML")

once its in the loop with model.orders[.,] it fails Any help would be appreciated.


Solution

  • Note what happens when you run the following.

    1:nrow(model.orders) %>% {length(.)}

    You are actually passing all elements in 1:nrow(model.orders) at once, not one by one.

    Instead of subsetting model.orders one row at a time and then passing it to order, you are getting all rows in one go, prompting an error.

    You can achieve your desired result using lapply after the pipe.

    models <- 1:nrow(model.orders) %>% 
      lapply(., function(row_n){
        Arima(ausgdp, 
              order = as.vector(model.orders[row_n, ]), 
              include.constant = T, 
              method = "ML")
      })