[R] new syntax: bash-like pipe operator

Gabor Grothendieck ggrothendieck at gmail.com
Tue Mar 29 18:00:29 CEST 2011


On Tue, Mar 29, 2011 at 9:56 AM, Robert Sugar <robert.sugar at ebi.ac.uk> wrote:
> Dear R Community,
>
> One thing that always bugged me about R is the abundance of multi-level nested statements, like:
>
> cumsum(ifelse(c(1,diff(v)),1,0))
>
> because:
>
> a) you have to read them inside out as opposed to left-to-right
> b) in the console you always have to go back and type the parenthesis if you want to nest your statement
> I kind of like the UNIX pipe operator as a very good abstraction of a data flow and would fancy to have something like this in R:
> v %|% diff %|% c(1, value) %|% ifelse(value, 1, 0) %|% cumsum
> so I went ahead and wrote it:
>
> "%|%" <- function(x,y)
> {
> # Operator similar to the UNIX pipe operator. Allows to set up a chain of functions
> # where the result of one function will be the input of the next.
> #
> # x: any R statement. will be passed to y as a parameter
> # y: either a) the name of a single-parameter function or b) a function call, where "value"
> # will be replaced with the x parameter
> #
> # Example use 1: > c(1,2,3) %|% sum
> #   results in [1] 6
> # Example use 2: > c(1,2,3) %|% rep(value, 10)
> #   results in [1] 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3
>
>        thecall<-match.call() #get call
>
>        #for functions with one parameter call it with x. Example: "c(1,2,3) %|% sum" -> 6
>        if(is.name(thecall$y) || is.function(thecall$y)) return (y(x))
>
>        #instead of value use x
>        value <- eval(thecall$x)
>
>        return(eval(thecall$y)) #evaluate
> }
>
> would be happy to receive some feedback on
>
> 1. Would you find this useful?
> 2. Is there any bugs/features that you'd like to mention?
> 3. Should I go ahead and make an R package on that?

That is interesting although note that a simple way to get that order
without introducing new features is to use intermediate variables.
Here we use the variable . in order to save space and use .= to assign
to it.

# Example 1 above
.= c(1, 2, 3); sum(.)

# Example 2 above
.= c(1, 2, 3); rep(., 10)

# example in preamble
v <- c(1, 2, 3)
.= diff(v); .= c(1, .); .= ifelse(., 1, 0); cumsum(.)


-- 
Statistics & Software Consulting
GKX Group, GKX Associates Inc.
tel: 1-877-GKX-GROUP
email: ggrothendieck at gmail.com



More information about the R-help mailing list