2
votes

I have the following code which returns the model with the lowest AIC, but I want all the models with their AIC in ascending or descending order without using the built-in sort function in R

sp <- rnorm(100)  ## just some toy data to make code work!
spfinal.aic <- Inf
spfinal.order <- c(0,0,0)
for (p in 1:4) for (d in 0:1) for (q in 1:4) {
  spcurrent.aic <- AIC(arima(sp, order=c(p, d, q)))
   if (spcurrent.aic < spfinal.aic) {
     spfinal.aic <- spcurrent.aic
     spfinal.order <- c(p, d, q)
     spfinal.arima <- arima(sp, order=spfinal.order)
   }
}

I want spfinal.order<-c(p,d,p) to be a list of all models in ascending or descending order of AIC. How can I do that?

1
Could you explain why you want to avoid using sort?Hack-R
Using functions like order() or sort() leads to superfluous computations.Waqas

1 Answers

2
votes

The code below does what you want. As you want a record of all models having been tried, no comparison is done inside the loop. A vector aic.vec will hold AIC values of all models, while a matrix order.matrix will hold column-by-column the ARIMA specification. In the end, we sort both by ascending AIC values, so that you know the best model is the first one.

sp <- rnorm(100)  ## just some toy data to make code work!
order.matrix <- matrix(0, nrow = 3, ncol = 4 * 2 * 4)
aic.vec <- numeric(4 * 2 * 4)
k <- 1
for (p in 1:4) for (d in 0:1) for (q in 1:4) {
  order.matrix[, k] <- c(p,d,q)
  aic.vec[k] <- AIC(arima(sp, order=c(p, d, q)))
  k <- k+1
  }
ind <- order(aic.vec, decreasing = FALSE)
aic.vec <- aic.vec[ind]
order.matrix <- order.matrix[, ind]

I did not use a list to store the ARIMA specification, because I think a matrix is better. At the moment the matrix is in wide format, i.e., with 3 rows while many columns. You can transpose it for better printing:

order.matrix <- t(order.matrix)

Maybe you also want to bind order.matrix and aic.vec together for better presentation? Do this:

result <- cbind(order.matrix, aic.vec)
colnames(result) <- c("p", "d", "q", "AIC")

I think this makes it easier for you to inspect. Example output (first 5 rows):

> result
      p d q      AIC
 [1,] 2 0 2 305.5698
 [2,] 3 0 3 305.8882
 [3,] 1 0 3 307.8365
 [4,] 2 1 3 307.9137
 [5,] 1 1 2 307.9952