user6183069
user6183069

Reputation: 5

passing parameters from expand.grid to function using apply

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

Upvotes: 0

Views: 1314

Answers (2)

Jason Schoeneberger
Jason Schoeneberger

Reputation: 83

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?

Upvotes: 0

MrFlick
MrFlick

Reputation: 206516

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))

Upvotes: 2

Related Questions