Search code examples
rfunctionif-statementoptional-parametersoptional-arguments

Optional arguments in function-R


This is a reproducible example-

cars<-data.frame(mtcars)
cars_function<-function(mpg,data, parameter1, parameter2=NULL) {
   if(is.null(parameter2)) {
       a<- aggregate(mpg ~parameter1,data,mean )
       a<-round(a, digits = 0)
   } else {
       a<- aggregate(mpg ~parameter1+parameter2,data,mean)
       a<-round(a, digits = 0)
   }
}

cars_res1 <- cars_function(mpg=cars$mpg, parameter1 = cars$vs, data = cars)
cars_res2 <- cars_function(mpg=cars$mpg, parameter1 = cars$vs, parameter2 = cars$am,data = cars)

Here parameter 2 is an optional argument. The step after computing the mean using aggregate is the same i.e rounding off. In case of my actual data, I perform multiple calculations, after which there are additional steps which are common (rounding off, changing the column names, etc) which makes the code really long, even though the steps are repetitive.

How can I avoid that?

In this case, both if-else give me the same output i.e. mean. So is it possible to do something like this?

cars_function1<-function(mpg,data, parameter1,parameter2=NULL){
   a <- aggregate(mpg ~parameter1+parameter2,data,mean)
   a <- round(a, digits = 0) 
}

cars_new_res1 <- cars_function1(mpg=cars$mpg, parameter1 =    cars$vs, parameter2 = NULL, data = cars) 
##It ignores parameter 2 here
cars_new_res2 <- cars_function1(mpg=cars$mpg, parameter1 = cars$vs, parameter2 = cars$am, data = cars)

Solution

  • This approach is a bit more flexible-

    cars_function<-function(data,y,x){
      f <- as.formula(paste(y,"~", paste(x, collapse="+")))
      a <- aggregate(f,data,mean)
      a <- round(a, digits = 0) 
    }
    
    out1 <- cars_function(data=mtcars,y="mpg",x=c("vs"))
    out2 <- cars_function(data=mtcars,y="mpg",x=c("vs","am"))