grapes-greater-than-greater-than-grapes: Pipe an object forward

Description Usage Arguments Details Examples

Description

The %>>% operator pipes the object on the left-hand side to the right-hand side according to the syntax.

Usage

1
x %>>% expr

Arguments

x

object

expr

expression

Details

Pipe operator %>>% determines the piping mechanism by the syntax of the expression on the right-hand side.

%>>% supports the following syntaxes:

1. Pipe to first unnamed argument:

Whenever a function name or call with or without parameters follows the operator, the left-hand side value will be piped to the right-hand side function as the first unnamed argument.

x %>>% f evaluated as f(x)

x %>>% f(...) evaluated as f(x,...)

x %>>% package::name(...) evaluated as package::name(x, ...)

2. Pipe to . in enclosed expression:

Whenever an expression following the operator is enclosed by {}, the expression will be evaluated with . representing the left-hand side value. It is the same with expression enclosed with () unless it contains a lambda expression or assignment expression.

x %>>% { expr } evaluated as { expr } given . = x

x %>>% ( expr ) evaluated as expr given . = x

3. Pipe by lambda expression:

A lambda expression is a formula whose left-hand side is a symbol used to represent the value being piped and right-hand side is an expression to be evaluated with the symbol.

x %>>% (p ~ expr) as expr given p = x

4. Pipe for side-effect:

If one only cares about the side effect (e.g. printing intermediate results, plotting graphics, assigning value to symbol) of an expression rather than its returned value, write a lambda expression that starts with ~ indicating side effect (or branching, in the sense of pipeline building).

x %>>% (~ f(.)) evaluated as {f(x); x}.

x %>>% (~ p ~ f(p)) evaluated as {f(x); x}

5. Pipe for assignment

Equal operator (=) and assignment operators (<- and ->) perform assignment. This is particularly useful when one needs to save an intermediate value in the middle of a pipeline without breaking it.

Assignment as side-effect

In general, x %>>% (~ y = ...) is evaluated as y <- x %>>% (...) and returns x.

x %>>% (~ y) evaluated as y <- x and returns x, where y must be a symbol.

x %>>% (~ y = f(.)) evaluated as y <- f(x) and returns x.

x %>>% (~ y = p ~ f(p)) evaluated as y <- f(x) and returns x.

Piping with assignment

In general, x %>>% (y = ...) is evaluated as y <- x %>>% (...).

x %>>% (y = f(.)) evaluated as y <- f(x) and returns f(x).

x %>>% (y = p ~ f(p)) evaluated as y <- f(x) and returns f(x).

The equal sign above can be interchangeably used as the assignment operator <-. Note that the global assignment operator <<- and ->> in a pipeline also performs global assignment that is subject to side-effect outside the calling environment.

In some cases, users might need to create a group of symbols. The following code calls assign to dynamically determine the symbol name when its value is evaluated.

for (i in 1:5) rnorm(i) %>>% (assign(paste0("rnorm", i), .))

To avoid exporting a symbol to the calling environment, use a symbol name starting with . like

6. Pipe for element extraction:

If a symbol is enclosed within (), it tells the operator to extract element from the left-hand side value. It works with vector, list, environment and all other objects for which [[]] is defined. Moreover, it also works with S4 object.

x %>>% (name) as x[["name"]] when x is list, environment, data.frame, etc; and x@name when x is S4 object.

7. Pipe to string:

If an object is piped to a single character value, then the string will be cat() and starts a new paragraph. This is useful for indicating the executing process of a pipeline.

x %>>% "print something" %>>% f(y) will cat("print something") and then evaluate f(x,y).

8. Pipe for questioning:

If a lambda expression start with ?, the expression will be a side effect printing the syntax and the value of the expression. This is a light-weight version of side-effect piping and can be useful for simple inspection and debugging for pipeline operations.

x %>>% (? expr) will print the value of expr and return x, just like a question.

x %>>% ("title" ? expr) will print "title" as the question, the value of expr, and return x.

Examples

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
## Not run: 
# Pipe as first-argument to a function name
rnorm(100) %>>% plot

# Pipe as first-argument to a function call
rnorm(100) %>>% plot()
rnorm(100) %>>% plot(col="red")
rnorm(100) %>>% plot(col="red",main=length(.))

# Pipe as first-argument to a function call in namespace
# (in this case, parentheses are required)
rnorm(100) %>>% base::mean()

# Pipe to . in an expression enclosed by braces
representing the piped object
rnorm(100) %>>% { plot(.,col="red",main=length(.)) }

# Pipe to . in an expression enclosed by parentheses
representing the piped object
rnorm(100) %>>% (plot(.,col="red",main=length(.)))

# Pipe to an expression enclosed by parentheses with
lambda expression in the form of x ~ f(x).
rnorm(100) %>>% (x ~ plot(x,col="red",main=length(x)))

# Pipe to an expression for side effect and return
# the input value
rnorm(100) %>>%
  (~ cat("Number of points:",length(.))) %>>%
  summary

rnorm(100) %>>%
  (~ x ~ cat("Number of points:",length(x))) %>>%
  summary

# Assign the input value to a symbol in calling environment
# as side-effect
mtcars %>>%
  subset(mpg <= mean(mpg)) %>>%
  (~ sub_mtcars) %>>%
  summary

# Assign to a symbol the value calculated by lambda expression
# as side effect
mtcars %>>%
  (~ summary_mtcars = summary(.)) %>>%
  (~ lm_mtcars = df ~ lm(mpg ~ ., data = df)) %>>%
  subset(mpg <= mean(mpg)) %>>%
  summary

# Modifying values in calling environment
"col_" %>>%
  paste0(colnames(mtcars)) %>>%
  {names(mtcars) <- .}

rnorm(100) %>>% {
  num_mean <- mean(.)
  num_sd <- sd(.)
  num_var <- var(.)
}

rnorm(100) %>>% {
  .mean <- mean(.)
  .sd <- sd(.)
  ci <- .mean + c(-1,1) * 1.96 * .sd
}

for(i in 1:10) rnorm(i) %>>% (assign(paste0("var", i), .))

# Pipe for element extraction
mtcars %>>% (mpg)

# Pipe for questioning and printing
rnorm(100) %>>%
  (? summary(.)) %>>%
  plot(col="red")

mtcars %>>%
  "data prepared" %>>%
  lm(formula = mpg ~ wt + cyl) %>>%
  summary %>>%
  coef

mtcars %>>%
  ("Sample data" ? head(., 3)) %>>%
  lm(formula = mpg ~ wt + cyl) %>>%
  summary %>>%
  coef

# Pipe to an anomymous function
rnorm(100) %>>% (function(x) mean(x))()
rnorm(100) %>>% {function(x) mean(x)}()

# Pipe to an enclosed function to make a closure
z <- rnorm(100) %>>% (function(x) mean(x+.))
z(1) # 3

z <- rnorm(100) %>>% {function(x) mean(x+.)}
z(1) # 3

# Data manipulation with dplyr
library(dplyr)
iris %>>%
  mutate(Sepal.Size=Sepal.Length*Sepal.Width,
    Petal.Size=Petal.Length*Petal.Width) %>>%
  select(Sepal.Size,Petal.Size,Species) %>>%
  group_by(Species) %>>%
  do(arrange(.,desc(Sepal.Size+Petal.Size)) %>>% head(3))

# Data manipulation with rlist
library(rlist)
list(1,2,3) %>>%
  list.map(. + 1) %>>%
  list.filter(. <= 5) %>>%
  list.sort(.)

## End(Not run)

renkun-ken/pipeR documentation built on May 27, 2019, 4:55 a.m.