R Pipelining functions

I think that you might just want to write a function to do the steps you desire.

complexFunction <- function(x) {
    as.character(x^2 + 5)
}

Then just call complexFunction(x).


Edit to show what R is doing internally (@mnel) -- The way R parses the and evaluates as.character(x^2 + 5) does what you want

You can use codetools to investigate what R to see how the values are being passed to eachother

flattenAssignment(quote(as.character(x^2+5)))
[[1]]
[[1]][[1]]
x

[[1]][[2]]
`*tmp*`^2

[[1]][[3]]
`*tmp*` + 5


[[2]]
[[2]][[1]]
`as.character<-`(`*tmp*`, value = `*tmpv*`)

[[2]][[2]]
`+<-`(`*tmp*`, 5, value = `*tmpv*`)

[[2]][[3]]
`^<-`(x, 2, value = `*tmpv*`)

Or you can get the Lisp style representation to see how it is parsed (and the results passed)

showTree(quote(as.character(x^2+5)))
(as.character (+ (^ x 2) 5))

Here is a functional programming approach using Reduce. It is in fact an example from ?Reduce

square <- function(x) x^2
add_5 <- function(x)  x+5
x <- 1:5
## Iterative function application:
Funcall <- function(f, ...) f(...)

Reduce(Funcall, list(as.character, add_5, square,x), right = TRUE)
## [1] "6"  "9"  "14" "21" "30"

Or even more simply using the functional package and Compose

This is nice as it will create the function for you

library(functional)
do_stuff <-   Compose(square,add_5,as.character )
do_stuff(1:5)
##  [1] "6"  "9"  "14" "21" "30"

I note that I would not consider either of these approaches idiomatically R ish (if that is even a phrase)


We can use Compose from the functional package to create our own binary operator that does something similar to what you want

# Define our helper functions
square <- function(x){x^2}
add5 <- function(x){x + 5}

# functional contains Compose
library(functional)

# Define our binary operator
"%|>%" <- Compose

# Create our complexFunction by 'piping' our functions
complexFunction <- square %|>% add5 %|>% as.character
complexFunction(1:5)
#[1] "6"  "9"  "14" "21" "30"


# previously had this until flodel pointed out
# that the above was sufficient
#"%|>%" <- function(fun1, fun2){ Compose(fun1, fun2) }

I guess we could technically do this without requiring the functional package - but it feels so right using Compose for this task.

"%|>%" <- function(fun1, fun2){
    function(x){fun2(fun1(x))}
}
complexFunction <- square %|>% add5 %|>% as.character
complexFunction(1:5)
#[1] "6"  "9"  "14" "21" "30"

Tags:

R

Pipeline