Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
What’s in a name? That which we call a rose by any other name would smell as sweet.
Normal functions
Before moving to anonymous functions, let’s start with what normal functions look like.
In R
# Define a function functionName <- function(variables) { # Function definition... do some stuff print(paste(variables, "doing stuff")) } # Call the function > functionName("boring strings") [1] "boring strings doing stuff"
In Python
# Define function def functionName(variables): # Do some stuff print variables, "doing stuff" # Call the function >>> functionName("boring strings") boring strings doing stuff
Anonymous Functions
Have no identity, no name, but still do stuff! They will not live in the global environment. Like a person without a name, you would not be able to look the person up in the address book.
The anonymous function can be called like a normal function functionName()
, except the functionName is switched for logic contained within parentheses (fn logic goes here)()
.
In R
# Doing the same stuff anonymously > (function(variables) print(paste(variables, "doing stuff")) )("code") [1] "code doing stuff"
In Python
Python introduces the lambda
keyword for anonymous functions, in contrast to R which sticks with the function
keyword.
# Doing the same stuff anonymously >>> (lambda variable: variable + " doing stuff")("code") 'code doing stuff'
R Convention
The most common convention is to use anonymous functions when using the *apply
family of functions. For example, you might want to do an operation across a set of columns in a dataset.
# Create a dataset df <- data.frame( col1 = c("element1", "element2"), col2 = c("element1", "element2"), stringsAsFactors = FALSE ) # lapply an anonymous function to the columns of the dataset > lapply(df, function(x) paste(x, "doing stuff")) $col1 [1] "element1 doing stuff" "element2 doing stuff" $col2 [1] "element1 doing stuff" "element2 doing stuff"
Python Convention
Doing the exact operation as above in python:
import pandas as pd # Create DataFrame df = pd.DataFrame([["element1", "element1"], ["element2", "element2"]], columns=['col1', 'col2']) >>> df.apply(lambda x: x + " doing stuff", axis=0) col1 col2 0 element1 doing stuff element1 doing stuff 1 element2 doing stuff element2 doing stuff
You will generally see lambdas used with higher order functions like map()
, reduce()
and filter()
. E.g.
# Map a anonymous function against all elements of df['col1'] >>> map(lambda x: x + " doing stuff", df['col1']) ['element1 doing stuff', 'element2 doing stuff']
You may also see lambda used to define a function. e.g.
functionName = lambda x: x + " doing stuff"
This is poor practice when a standard function definition would have been sufficient. The Python community has a bit of split over the use of anonymous functions (lambdas) vs. list comprehensions. The benevolent dictator of the Python community Guido van Rossum has argued for lambda’s complete removal from python 3.
In Conclusion
Anonymous functions can make your code base harder to read. It can also make debugging harder. However, they can save you time from having to define yet another function in your code base. When should you use anonymous functions? According to Hadley “when it’s not worth the effort to give it a name”. A good example is when you won’t use the function anywhere else in your code. Or when you want to apply()
a couple of pre-defined functions in one call e.g. lapply(df, function(x) secondFunction(firstFunction(x)))
.
Resources
R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.