Search code examples
rpipeapplypurrrmagrittr

Call function many times without duplicate it (with %>%)


Let's assume that we have 3 functions with this minimal functionality:

func1 <- function (x) {
  x + 1
}

func2 <- function (x, plus = T) {
  if (plus == TRUE) {
    x + 2
  } else {
    x - 5 
  }
}

func3 <- function (x) {
  x + 3
}

I would like to nest this function to each other like this with the pipe (%>%) operator:

library(magrittr)

func1(0) %>% func2(plus = T) %>% func2(plus = F) %>% func3
# result: 1

Which is the equivalent version of it:

func3(func2(func2(func1(0), plus = T), plus = F))
# result: 1

I try to find a method which doesn't require to duplacate the func2() function (because I have to run it many times and also I would like to change the number of function calls and the parameter dinamically). Currently I am not a big expert of apply functions or map package but I guess at least one of it can do this job.

It is of course just a dummy example, my real code is much more complicated, I just try to simplify my problem to find a solution.

I have to use the pipe operator so I only interested in that solutions which also work with pipes.


Solution

  • Write a function that takes the initial x and the outcomes to feed to func2 and loops through those outcomes:

    func2_iterate = function(x, outcomes){
      for (i in 1:length(outcomes)){
        x = func2(x, outcomes[i])
      }
      return(x)
    }
    

    Then run (with func1, func2, func3 as above):

    func1(0) %>% func2_iterate(c(T, F)) %>% func3
    #result: 1
    

    I'd also like to point out that in this particular case the output of func2_iterate is just its input, plus 2 times the number of T in outcomes, minus 5 times the number of F in outcomes. But I assume you actually have functions that do something more complicated.