Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to organize big R functions?

Tags:

function

r

I'm writing an R function, that is becoming quite big. It admit multiple choice, and I'm organizing it like so:

myfun <- function(y, type=c("aa", "bb", "cc", "dd" ... "zz")){

   if (type == "aa") {
      do something
      - a lot of code here -
      ....
   }

   if (type == "bb") {
      do something
      - a lot of code here -
      ....
   }

   ....
}

I have two questions:

  1. Is there a better way, in order to not use the 'if' statement, for every choice of the parameter type?
  2. Could it be more functional to write a sub-function for every "type" choice?

If I write subfunction, it would look like this:

myfun <- function(y, type=c("aa", "bb", "cc", "dd" ... "zz")){

   if (type == "aa") result <- sub_fun_aa(y)
   if (type == "bb") result <- sub_fun_bb(y)
   if (type == "cc") result <- sub_fun_cc(y)
   if (type == "dd") result <- sub_fun_dd(y)
   ....
}

Subfunction are of course defined elsewhere (in the top of myfun, or in another way).

I hope I was clear with my question. Thanks in Advance.

- Additional info -

I'm writing a function that applies some different filters to an image (different filter = different "type" parameter). Some filters share some code (for example, "aa" and "bb" are two gaussian filters, which differs only for one line code), while others are completely different.

So I'm forced to use a lot of if statement, i.e.

 if(type == "aa" | type == "bb"){
  - do something common to aa and bb -

    if(type == "aa"){
      - do something aa-related -
    }
    if(type == "bb"){
      - do something bb-related -
    }
 }

 if(type == "cc" | type == "dd"){
  - do something common to cc and dd -

    if(type == "cc"){
      - do something cc-related -
    }
    if(type == "dd"){
      - do something dd-related -
    }
 }

if(type == "zz"){
     - do something zz-related -
}

And so on. Furthermore, there are some if statement in the code "do something". I'm looking for the best way to organize my code.

like image 429
Tommaso Avatar asked Aug 31 '11 08:08

Tommaso


1 Answers

Option 1

One option is to use switch instead of multiple if statements:

myfun <- function(y, type=c("aa", "bb", "cc", "dd" ... "zz")){
  switch(type, 
    "aa" = sub_fun_aa(y),
    "bb" = sub_fun_bb(y),
    "bb" = sub_fun_cc(y),
    "dd" = sub_fun_dd(y)
  )
}  

Option 2

In your edited question you gave far more specific information. Here is a general design pattern that you might want to consider. The key element in this pattern is that there is not a single if in sight. I replace it with match.function, where the key idea is that the type in your function is itself a function (yes, since R supports functional programming, this is allowed).:

sharpening <- function(x){
  paste(x, "General sharpening", sep=" - ")
}

unsharpMask <- function(x){
  y <- sharpening(x)
  #... Some specific stuff here...
  paste(y, "Unsharp mask", sep=" - ")
}

hiPass <- function(x) {
  y <- sharpening(x)
  #... Some specific stuff here...
  paste(y, "Hipass filter", sep=" - ")
}

generalMethod <- function(x, type=c(hiPass, unsharpMask, ...)){
  match.fun(type)(x)
}

And call it like this:

> generalMethod("stuff", "unsharpMask")
[1] "stuff - General sharpening - Unsharp mask"
> hiPass("mystuff")
[1] "mystuff - General sharpening - Hipass filter"
like image 195
Andrie Avatar answered Sep 23 '22 18:09

Andrie