Playing with R, infix functions, and pizza
Digging into a not so special type of R functions, in order to make an emoji-pizza-dplyr-slice one.
What are infix functions?
In R, most of the functions are “prefix” - meaning that the function name comes before the arguments, which are put between parentheses : fun(a,b)
. With infix functions, the name comes between the arguments a fun b
. In fact, you use this type on a daily basis with :
, +
, and so on.
So, how can you create your own infix functions?
As an R user (and even if you come from another language), you’re used to write your functions in this form :
a_function <- function(some_variable, another_one) {
do_some_stuffs(some_variable,another_one)
}
# And write a function call this way:
a_function(some_variable,another_one)
But if your function has only two operators, you can write it this way :
`%some_function%` <- function(some_variable,another_one) {
do_some_stuffs(some_variable,another_one)
}
# And use it with:
some_variable %a_function% another_one
At this point, you’ve noticed two things :
Back ticks
Back ticks are R way to denote a special name. You can in fact put any characters between them (even emoji, as we’ll see later on):
# Impossible
123 <- function(a,b){a+b}
_some_function <- function(a,b){a+b}
#Possible
`123` <- function(a,b){a+b}
`_some_function` <- function(a,b){a+b}
Percent sign %
The two %
surrounding the function name are necessary if you want to create your own infix functions. As %
is a special character, you need to use it inside back ticks. Note that basic infix functions in R don’t need the percent sign, but user generated one do.
1:10
# is equivalent to
`:`(1,10)
2+3
# is equivalent to
`+`(2,3)
Good thing (or maybe not) is that you can override the default functions, if you want to drive someone mad:
# Warning : don't try this at home
`+` <- function(a,b){a*b}
2+10
[1] 20
`<-` <- .Primitive("+")
2 <- 3
[1] 5
`:` <- .Primitive("*")
2:10
[1] 20
# Restore cosmic ordeR
`<-` = .Primitive("<-")
`+` <- .Primitive("+")
`:` <- .Primitive(":")
Some examples
`%oh_wait%` <- function(a,b) {
print(a);Sys.sleep(3);print(b)
}
Sys.time() %oh_wait% Sys.time()
[1] "2017-06-28 23:01:43 CEST"
[1] "2017-06-28 23:01:46 CEST"
This first function does nothing but printing the time twice, with 3 seconds of pause in-between. Needless to say that’s useless, but that was just an example :)
Let’s do something more tidyverse friendly. For example, let’s try a function %select%
which will be the equivalent to %>% select()
.
library(tidyverse)
`%select%` <- dplyr::select
iris %select% "Species"
# Is equivalent to
iris %>% select("Species")
And now, the cool stuffs
You can use (almost) any character you like between the two %
, except %, of course. But… really ANYTHING? Because, you know, sometimes you just need to make some pizza function calls, or maybe you just like emojis.
# Not working
🍕 <- dplyr::slice
> Erreur : unexpected input in "�"
# Working
`%🍕%` <- dplyr::slice
iris %🍕% 2
# A tibble: 1 x 5
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
<dbl> <dbl> <dbl> <dbl> <fctr>
1 5.1 3.5 1.4 0.2 setosa
So, anybody has some spare time to recode the whole tidyverse in emojis? 😃
More on infix functions :
What do you think?