0

I have two functions with different parameters, let say function f and function g:

f <- function(a1, a2, a3, a4, a5) {  
      w <- a1+a2+a3+a4+a5 
}

and

g <- function(x, y) { 
      z <- w*x*y 
      print(z)
}

I am trying to merge this two functions into one and all I can think is doing it like this:

m <- function(a1,a2,a3,a4,a5,x,y) {
        w <- a1+a2+a3+a4+a5
        z <- w*x*y
        print(z) 
}

The problem with function m is that I find it too messy because of too much parameters.

My goal is that to create a function that will go through f first and then go through g and finally print the answer.

The reason that I want to do this is that, in my code there will be almost 3 to 5 functions (let say g,h,i,j,k) all with different parameters. However, these functions will undergo the primary function first (function f), and then will execute either one of g,h,i,j,k, based on users input. I have the idea of using loop, but I didn't know which loop to apply.

For example, I have another function h and i:

h <- function(b,c) { 
      t <- w*b/c 
      print(z)
}

i <- function(d, e) { 
      v <- w+d*e 
      print(z)
}

The thing that I wanna do is that to create a single function (maybe using loop) from all this function. Function f is the primary function (which means that this is the first thing to be execute) and then based on user input, it will either execute function g,h, or i.

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
mojek
  • 195
  • 1
  • 9
  • 1
    It's not clear to me exactly what you want to happen here. I mean, when you assign values to variables inside functions, those variables disappear after the function exits. Functions in R should return values and not run with side effects. What are these functions really supposed to do? Maybe there's a better design for the long term. – MrFlick Mar 07 '19 at 03:00
  • 1
    @MrFlick I had edit some new information on my post. I hope it helps. – mojek Mar 07 '19 at 03:33
  • What is the ultimate goal of all these functions? – NelsonGon Mar 07 '19 at 03:36
  • 1
    @NelsonGon the goal is that, user will choose the functions they prefer and input the values. – mojek Mar 07 '19 at 03:38

3 Answers3

2

Create a function main which accepts g, x, y and the f arguments. The f arguments will be passed via .... Now since g refers to w which is not defined in g it will look to the lexical parent of g for w so either g must be defined within f or else we must reset the environment of g to that within f so that w can be found when g is run. We do the latter.

If it were possible to redefine g so that w is explicitly passed to it via an argument then we can remove the line that resets the environment of g and modify the call to g to add w in the argument list.

f <- function(a1, a2, a3, a4, a5) {  
      w <- a1+a2+a3+a4+a5 
}

g <- function(x, y) { 
      z <- w*x*y 
      print(z)
}

h <- function(b,c) { 
      t <- w*b/c 
      print(t)
}

i <- function(d, e) { 
      v <- w+d*e 
      print(v)
}

main <- function(FUN, x, y, ...) {
  environment(FUN) <- environment()
  w <- f(...)
  FUN(x, y)
}

# tests
a1 <- a2 <- a3 <- a4 <- a5 <- x <- y <- 1

main(g, x, y, a1, a2, a3, a4, a5)
## [1] 5

main(h, x, y, a1, a2, a3, a4, a5)
## [1] 5

main(i, x, y, a1, a2, a3, a4, a5)
## [1] 6
G. Grothendieck
  • 254,981
  • 17
  • 203
  • 341
  • This seems robust. Out of curiosity, could there be a way to build something like a function factory or use such calls as `force`? – NelsonGon Mar 07 '19 at 05:07
  • 1
    One could curry `main` like this: `library(purrr); main_g <- partial(main, FUN = g)` although note the minor bug in `partial` https://github.com/tidyverse/purrr/issues/656 – G. Grothendieck Mar 07 '19 at 12:50
0

Not sure I got the aim well but we could use:

Edit:

After reading about the dangers of eval(parse()) thanks to @Maurits Evers, we could use get instead:

 combfn1<-function(x,y,func,...){
      w<-do.call(get(func),list(c(...)))
      z<-w*x*y
      print(z)
    }
   combfn1(1,2,"sum",3,4,6)

The dangers of the function below have been answered in several posts, one of which is this.

 combfn<-function(x,y,func,...){
      w<-do.call(eval(parse(text=quote(func))),list(c(...)))
      z<-w*x*y
      print(z)
    }
    combfn(1,2,"sum",3,4)
Community
  • 1
  • 1
NelsonGon
  • 13,015
  • 7
  • 27
  • 57
  • 1
    Perhaps relevant here is [What specifically are the dangers of eval(parse(…))?](https://stackoverflow.com/questions/13649979/what-specifically-are-the-dangers-of-evalparse). – Maurits Evers Mar 07 '19 at 04:40
  • Thanks @MauritsEvers. I'll leave the answer here for historical purposes. – NelsonGon Mar 07 '19 at 04:42
-2

What if you just put f and g inside m? Would this work? I dont have R in front of me atm.

m <- function(f, g) {


f <- function(a1, a2, a3, a4, a5) {  
      w <- a1+a2+a3+a4+a5 
}

g <- function(x, y) { 
      z <- w*x*y 
      print(z)
}
f()
g()

}
hs0orc
  • 1
  • 1