magrittr in one line

Active Analytics Ltd: posted 24 July 2014 by Chibisi Chima-Okereke

Introduction

In R, programmers can create their own operators using the form %x% where x is the choice of the programmer. However, you can actually overwrite a native operator:

`*` <- function(e1, e2)e1/e2
> 2*4
[1] 0.5

We have recently seen a new R package called magrittr which made us laugh but also reminded us that operators in R are very useful and fun. So we decided to do a quick blog post writing one package in one line. Please note that this is slightly tongue-in-cheek, magrittr does have a few other features that you should check out. The code for this blog post is at github.

magrittr in one line

You can create an operator using the backtick operator to define your function, so without futher ado here is magrittr in one line:

`%>%` <- function(x, FUN)FUN(x)

That's it! Now for a quick demo:

iris %>% head
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
3          4.7         3.2          1.3         0.2  setosa
4          4.6         3.1          1.5         0.2  setosa
5          5.0         3.6          1.4         0.2  setosa
6          5.4         3.9          1.7         0.4  setosa
1E4 %>% rnorm %>% hist

As it happens you can also define the operator using either an apostrophe or a speech marks:

# Speech marks
"%>%" <- function(x, FUN)FUN(x)
# Apostrophe
'%>%' <- function(x, FUN)FUN(x)

Any three of the above implementations will do.

A paste operator

We can't leave without our own suggestion to the operator collection. In languages like Python, the "+" operator is used to concatenate strings. So what about something like this: %+%. Here is the code, again it is one line:

`%+%` <- function(x1, x2)paste0(x1, x2)

Here is an example:

"Hello " %+% "World" %+% "! Goodbye " %+% "World!"
[1] "Hello World! Goodbye World!"

Futher paste issues

We can take this futher and attempt to define a true "+" operator for character classes in R, however we run into a brick wall:

setMethod("+", c("character", "character"), function(e1, e2)paste0(e1, e2))
Error in setMethod("+", c("character", "character"), function(e1, e2) paste0(e1,  : 
  the method for function ‘+’ and signature e1="character", e2="character" is sealed and cannot be re-defined

A poor substitute is to define this for another class:

# A quick hack:

# Create a new class
setClass("string", "character")
# Set a method for the class
setMethod("+", c("string", "string"), function(e1, e2){
	x <- paste0(e1, e2); class(x) <- "string"
	return(x)
})
# Demo the class
a <- new("string", "Hello ")
b <- new("string", " World!")
cc <- new("string", " Goodbye ")
d <- new("string", "World!")
a + b + cc + d

[1] "Hello  World! Goodbye World!"
attr(,"class")
[1] "string"

For obvious reasons this is much less desireble than being able to use the "+" operator on character classes.

Conclusion

Operators in R are fun. They can be very useful and chaining is one such useful attribute.

Data Science Consulting & Software Training

Active Analytics Ltd. is a data science consultancy, and Open Source Statistical Software Training company. Please contact us for more details or to comment on the blog.

Dr. Chibisi Chima-Okereke, R Training, Statistics and Data Analysis.