0

I'm trying use expand.grid to create all combinations of 3 order parameters ranging as shown below. I'm then trying to create all models for the combinations of parameters using Arima and apply. I have pseudo code below outlining what I'm trying to do and an attempt I made below that. The attempt returned an error. If anyone can see what I'm doing wrong, point out how to fix the code, or a similar example, it would be greatly appreciated.

Pseudo Code:

library("fpp")

h <- 5
dataTraiz <- window(hsales,end=1989.99)

##Create models for all combinations of p 10 to 0, d 2 to 0, q 5 to 0

Mod1 <- Arima(dataTraiz, order=c(10,2,5)
Mod2 <- Arima(dataTraiz, order=c(9,2,5)
Mod3 <- Arima(dataTraiz, order=c(8,2,5)
.
.
.
Mod5 <- Arima(dataTraiz, order=c(10,2,0)

Attempt:

x<-1:10
y<-1:2
z<-1:5

dfG<-expand.grid(x,y,z)


n <-function(a,b,c,dat){
          m=Arima(dataTraiz, order=c(a,b,c))
          return(m)
                        } 


mod<-apply(dfG,1,n)

Error:

Error in Arima(dataTraiz, order = c(a, b, c)) : argument "c" is missing, with no default

2 Answers 2

2

I would suggest avoiding apply with data.frames objects (such as those returned from expand.grid. You can use Map to call a function for different sets of parameter values

mod <- with(dfG, Map(function(a,b,c) {
    Arima(dataTraiz, order=c(a,b,c))
}, Var1, Var2, Var3))

Using with() allows us to access the Var columns of dfG without directly without dfG$Var. Then we just pass in the values to Map which passes them along to each parameter in the function we supply in the order given.

An alternative would be to Vectorize your function so it would iterate over parameter tuples. For example

n <- function(a,b,c) {Arima(dataTraiz, order=c(a,b,c))}
mod <- do.call(Vectorize(n, SIMPLIFY=FALSE), unname(dfG))
Sign up to request clarification or add additional context in comments.

4 Comments

Thank you! This is very helpful. I'm trying to understand in the 2nd vectorize example, what is the structure of mod? Does it create a model and save it for each order combination? If so, how do you select one of the models?
Both create a list of models. You extract them with mod[[1]], mod[[2]], etc
Thank you for getting back to me so quickly. Your code worked just fine for me this morning. I tried running it again just a short time ago and now I'm getting the error below. Do you get the same issue when you run the code now? Do you have any idea what could be causing it? Error: Error in stats::arima(x = x, order = order, seasonal = seasonal, include.mean = include.mean, : non-stationary AR part from CSS
If I specify the method="ML" it gets rid of the error. Arima(dataTraiz, order=c(a,b,c),method="ML") your code worked just fine this morning. I don't know what changed throughout the day, but like I said, if you specify the method as ML your code works fine again. Thanks.
0

I have a follow-up to using map for passing parameters to a function. The following is a simplified example. I create a simple data file for use...and I have a function that I want to pass two lists to, but also some single parameters (dat and x). I combine the lists using exapnd.grid and use map with the simple function.

fake_dat <-  as.data.frame(matrix(c(1, 2, 3, 4), nrow = 2, byrow = TRUE))

one_lst <- c("a","b")
two_lst <- c("aa","bb")
all_lst <- expand.grid(one_lst, two_lst)

with(all_lst, Map(function(var1, var2, dat, x) {
  print(var1)
  print(var2)
  print(dat[[x]])
}, Var1, Var2, dat=list(fake_dat), x=list("V2")))

Using it this way I get the error:

Error in (function (cond) : 
error in evaluating the argument 'x' in selecting a method for function 'print': subscript out of bounds

However, if I embed the single parameters within list, it seems to work:

with(all_lst, Map(function(var1, var2, dat, x) {
  print(var1)
  print(var2)
  print(dat[[x]])
}, Var1, Var2, dat=list(fake_dat), x=list("V2")))

Is this the appropriate way to use map for my scenario...or is there a better way to accomplish passing some lists (potentially of varying lengths) and some single parameter arguments to a function?

2 Comments

It is probably better to post this as a separate question rather than an answer to the present query. In addition, I think the with() functions in the first and second code blocks are identical?
Agreed...and yes i see i didn't post the correct first attempt. Separate question now posted

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.