Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Additional function name but with fewer arguments [duplicate]

Tags:

function

r

assign

I need to create additional name for my_function(i,x) (where i can be an integer from 1 to 25). I'd like it to work like this

  • my_function1(x) sames as my_function(1,x)
  • my_function2(x) sames as my_function(2,x)
  • my_function3(x) sames as my_function(3,x)
  • ...
  • my_function25(x) sames as my_function(25,x)

One way to do achieve this would be:

my_function1 <- function (x) my_function(1, x)
my_function2 <- function (x) my_function(2, x)
my_function3 <- function (x) my_function(3, x)
...

But since there are 25 of them it would be reasonable to make it in a loop. For this I've tried:

for(i in 1:25){
  assign(paste("my_function",i,sep=""),function(x) my_function(i,x))
}

but it doesn't work since i is passed by reference and in the end the result was

  • my_function1(x) sames as my_function(25,x)
  • my_function2(x) sames as my_function(25,x)
  • my_function3(x) sames as my_function(25,x)
  • ...

How can I pass "i" by value? Or perhaps there is some other way...

Why would I want to do this? I'm improving someones else R package in terms of efficiency but at the same time I need it to be compatible with old version.

like image 640
LukaszJ Avatar asked May 05 '13 12:05

LukaszJ


3 Answers

This is called currying, and is a part of functional programming.

library(functional)

myf <- function(a,x) cat(a,x,"\n")
myf1 <- Curry(myf, a=1)
myf1(5)
for(i in seq(25)) assign(paste0("myf",i), Curry(myf,a=i) )
> myf15(5)
15 5

I guess there's an important question here as to why you'd want to do this. This seems like exactly the kind of thing you'd want arguments not many related functions for.

like image 106
Ari B. Friedman Avatar answered Nov 17 '22 07:11

Ari B. Friedman


Well, you can achieve the same result, using base functions too.

The trick is to force (force) the evaluation of i at each iteration and assign your function in the .Globalenv (or the environment you like)

my_function <- function(a, b) a + b


lapply(1:10, function(i) {
    force(i)
    assign(paste0("my_function", i), function(x) my_function(i, x), envir = .GlobalEnv)
}
       )


my_function1(10)
## [1] 11

my_function9(10)
## [1] 19
like image 4
dickoa Avatar answered Nov 17 '22 08:11

dickoa


I think bquote will help here:

for(i in 1:2){
  assign(paste("my_function",i,sep=""), bquote( function(x) my_function( i = .(i) , x ) ) )
}

>my_function2
# function(x) my_function(i = 2L, x)

But the point still stands - why would you want to do this?

like image 2
Simon O'Hanlon Avatar answered Nov 17 '22 06:11

Simon O'Hanlon