I have come across this concept a couple of times, but don't know the name for it so cannot google it to learn more. Basically, when looking through functions or even simple commands others have written I will often see something similar to this:

apply(dataset, 1:2, function(x) 10 * x)

In this case, I was able to figure out that somehow this "fake function" function(x) would just multiply each element of the dataset by 10. This seems like a useful feature, but I'm still not certain when or how you use it. Is it really a function? Or does it just work within the apply family of functions? Is there a name for this thing?

3

Best Answer


Those are called "anonymous functions", and yes, they are real function objects, which just happen to have not been assigned to any symbol before being used.

Here's the relevant bit from the R language documentation:

Generally functions are assigned to symbols but they don’t need to be. The value returned by the call to function is a function. If this is not given a name it is referred to as an anonymous function. Anonymous functions are most frequently used as arguments to other functions such as the apply family or outer.

Although they are most typically used in *apply() functions, they need not be, as can be seen here, for example

(function(x,y){x*y + x/y})(2,5)# [1] 10.4

As of R 4.1.0, it is now possible to natively use \(x) {} instead of function(x) {} for anonymous function.

The apply code can be written as

dataset |>apply(1:2, \(x) {10 * x})

You mean a lambda (anonymous function)? You could put something like this in your ~/.Rprofile file:

`{` <- function(...)base::`{`(if (length(sys.calls()) >= 4 &&identical(as.character(sys.call()[[1]]), "{") &&identical(as.character(sys.call(-4)[[1]]), "{"))base::`{`(fn <- new('function'),formals(fn) <- alist(x=), body(fn) <- sys.call(), fn)else eval.parent(substitute(base::`{`(...))))

Then you can do things like:

sapply(1:10, {{x + 5}})# [1] 6 7 8 9 10 11 12 13 14 15

This is closer to languages like Ruby or Coffeescript which don't need to invoke a keyword to make a lambda (there they use -> but this is already taken in R so I used double braces). I just came up with this so if there are bugs let me know.