Search code examples
rmagrittr

How can I declare an anonymous function


I would like to know if there are concise way to deal to declare an anonymous function

Say I want to declare function(x){ return (x=='a') }, I'd love to be able, I'd like to be able to do f <- {.=='a'}

I know that magrittr allows you to do

library(magrittr)
{. %>% `==`(.,'a')} # or even . %>% `==`('a')  
{. %>% `==`(.,'a')}('b')
[1] FALSE

In the same way if f = function(x,y,z){return(x+y+z)} I'd like something like {f(.$x,3,.$z)}

When I have {...} why do I need {. %>% } it looks spurious to me


Solution

  • pryr is a package that implements a function that does something like this:

    f() takes an expression and tries to parse it to a function. This doesn't work perfectly 100% of the time, so it is definitely adviced to check the produced function.

    To take your example:

    > pryr::f(.=="a")
    function (.) 
    . == "a"
    

    Which you can call directly as follows:

    > f(.=="a")("b")
    [1] FALSE
    > f(.=="a")("a")
    [1] TRUE
    

    This works with multiple arguments:

    > f(a+b+c)
    function (a, b, c) 
    a + b + c
    

    and

    > f(a+b+c)(1,2,3)
    [1] 6
    

    When does it not work?

    f() doesn't seem to be able to tell variable names and functionnames apart when the functionnames are not called directly. Take the following function for example:

    function(x){
      apply(x, 1, sum)
    }
    

    Here sum is interpreted as a variable, so parsed to an argument in the anonymous function:

    > f(apply(x, 1, sum))
    function (sum, x) 
    apply(x, 1, sum)
    

    This can be fixed by explicitly passing the intended arguments for the function in the call:

    > f(x, apply(x, 1, sum))
    function (x) 
    apply(x, 1, sum)