How to efficiently reuse and optimize same code block in wrapper function?
2
1
Entering edit mode
7.4 years ago

Hi :

I have implemented several functions where some function behaved very similar way and share some identical structure. However, I intend to reuse the code more efficiently in my wrapper functions to make function body smaller for the sake of easy to test and debug. I am trying to find better way to construct my wrapper function as small as possible. How can I efficiently reuse the code multiple times in wrapper function easily ? What's the strategy to efficiently use same code structure in many times? Can anyone give me possible idea to overcome this issue ? Any idea ?

  • Note: among the param list, obj.List is list of peak interval as GRanges object, intList is list of integer list as overlap position index, val.List is list of pvalue, threshold could be numeric scalar.

This is the wrapper function where two small sub functions' code is shared same pattern :

myFunc <- function(obj.List, intList, threshold, ...) {
  # 
  func.1 <- function() {
    keepIdx <- lapply(intList, function(ele_) {
      keepMe <- sapply(val.List, function(x) x<=threshold)
      res <- ele_[keepMe]
    })
    expand.Keep <- Map(unlist, 
                       mapply(extractList, obj.List, keepIdx))
    return(expand.Keep)
  }
  func.2 <- function() {
    dropIdx <- lapply(intList, function(ele_) {
      drop_ <- sapply(val.List, function(x) x > threshold)
      res <- ele_[drop_]
    })
    expand.drop <- Map(unlist,
                       mapply(extractList, obj.List, keepIdx))
    return(expand.drop)
  }
  # then use the output of func.1 and func.2 as an argument for another function 
  # in this wrapper
  # how can I make this wrapper more efficient ? How to resue the code ?
}

I am just trying to make function body of this wrapper smaller, while I can call func.1, func.2 as an argument in the wrapper to trigger another sub function. How can I make this happen ? Any way efficiently optimize the code structure of above wrapper function ? Can anyone give me possible idea to make above code more efficient ? Thanks a lot

R s4 sequence • 2.7k views
ADD COMMENT
2
Entering edit mode

I'll keep this post open because there is a healthy discussion going on. I enjoy discussing programming issues also, however, this is really more suited to stackexchange as it is tangentially related to bioinformatics.

ADD REPLY
2
Entering edit mode

Agreed 100% (stackexchange)!

ADD REPLY
3
Entering edit mode
7.4 years ago
ddiez ★ 2.0k

I am not completely sure I understand what you are trying to do. Maybe an example with your desired use case and expected output would help. For more advance R programming I would recommend reading Advanced R, by Hadley Wickham (half-way to finish it myself). My guess is that you want something similar to functionals, or perhaps, a closure, but not completely sure.

Edit:

You mention that one of your objectives is to obtain code that it is easy to test and debug. I also see from your repository that you intend to create an R package. One thing I highly recommend you to do for testing is use unit testing. There are many options in R, like those provided by the packages RUnit, testit and testthat. I now use testthat because I found it easy to implement. You can know more about how to use it in the book (written by Hadley Wickham) R packages, which has a section dedicated to unit testing.

ADD COMMENT
0
Entering edit mode

Dear Diego:

Could you look up my project repository in github? In my project site, you could able to see all my workflow, and this part of code must be optimized as elegant as possible. Could you give me favor ? Thanks

ADD REPLY
2
Entering edit mode

I am not sure what I can accomplish by looking at your workflow. I still don't understand what you are trying to do. At any rate, you didn't include the link to your github and you don't show up by name.

ADD REPLY
0
Entering edit mode

Dear Diego:

Thanks again for your quick respond. Here is my project repository in github. Thanks a lot.

Best regards :

Jurat

ADD REPLY
1
Entering edit mode

May take a closer look later if I have time but in the meantime I added a small update to my answer.

ADD REPLY
0
Entering edit mode

Dear Diego :

I also intend to use testthat package for unit testing. Before unit testing, I need to make sure whole pipeline of packages is desired both in code quality and readability. How can I overcome repeated code block in my workflow ? How can I make this more efficient ? Any contribution on this packages is highly appreciated. Thank you very much :)

Best regards :

Jurat

ADD REPLY
2
Entering edit mode
7.4 years ago

Welcome to the world of functional programming. In R, a function can return a function. Yea, you heard it right: the return value can be a function :)

So you might do something like this:

and then,

func.1 = s("keepIdx")
func.2 = s("dropIdx")

Note that the two functions live in different environments; so there is no conflict between the two lapply.func, as they live in the environment of their respective functions.

> func.1
function() {
    myIdx <- lapply(intList, lapply.func)
    expand <- Map(unlist,  mapply(extractList, obj.List, myIdx))
  }
<environment: 0xe848530> 

> func.2
function() {
    myIdx <- lapply(intList, lapply.func)
    expand <- Map(unlist,  mapply(extractList, obj.List, myIdx))
  }
<environment: 0xe854840>

> get("lapply.func", env = environment(func.1))
function(ele_) {keepMe <- sapply(val.List, function(x) x<=threshold); res <- ele_[keepMe]}
<environment: 0xe848530>

> get("lapply.func", env = environment(func.2))
function(ele_) {drop_ <- sapply(val.List, function(x) x > threshold); res <- ele_[drop_]}
<environment: 0xe854840>

You might need to debug / tweak the above code according to your code-logic, but I hope you got the idea.

ADD COMMENT
0
Entering edit mode

Dear Santosh :

To keep this conversation thread clean and easy to read by others, I'll open new comment thread. To correctly use function call, I can try this way, but still no luck with this :

keepOrDropIdx <- lapply(intList, lapply.func, ele_= 1:seq_along(intList))

lapply.fun go through each element of intList , so its input could be intList[[i]], But my attempt still didn't return data object. How can I fix this issue ? Any idea?

Best regards :

Jurat

ADD REPLY
0
Entering edit mode

WTF? And you removed all the old discussions!!! The only suggestion I have is that you first go and read the fundamentals before writing complex codes.

See also the remark by Damian Kao. Mods may please close this thread.

ADD REPLY

Login before adding your answer.

Traffic: 1992 users visited in the last hour
Help About
FAQ
Access RSS
API
Stats

Use of this site constitutes acceptance of our User Agreement and Privacy Policy.

Powered by the version 2.3.6