grapes-greater-than-greater-than-grapes: PipeOp Composition Operator

%>>%R Documentation

PipeOp Composition Operator


These operators creates a connection that "pipes" data from the source g1 into the sink g2. Both source and sink can either be a Graph or a PipeOp (or an object that can be automatically converted into a Graph or PipeOp, see as_graph() and as_pipeop()).

⁠%>>%⁠ and ⁠%>>!%⁠ try to automatically match output channels of g1 to input channels of g2; this is only possible if either

  • the number of output channels of g1 (as given by g1$output) is equal to the number of input channels of g2 (as given by g2$input), or

  • g1 has only one output channel (i.e. g1$output has one line), or

  • g2 has only one input channel, which is a vararg channel (i.e. g2$input has one line, with name entry "...").

Connections between channels are created in the order in which they occur in g1 and g2, respectively: g1's output channel 1 is connected to g2's input channel 1, channel 2 to 2 etc.

⁠%>>%⁠ always creates deep copies of its input arguments, so they cannot be modified by reference afterwards. To access individual PipeOps after composition, use the resulting Graph's ⁠$pipeops⁠ list. ⁠%>>!%⁠, on the other hand, tries to avoid cloning its first argument: If it is a Graph, then this Graph will be modified in-place.

When ⁠%>>!%⁠ fails, then it leaves g1 in an incompletely modified state. It is therefore usually recommended to use ⁠%>>%⁠, since the very marginal gain of performance from using ⁠%>>!%⁠ often does not outweigh the risk of either modifying objects by-reference that should not be modified or getting graphs that are in an incompletely modified state. However, when creating long Graphs, chaining with ⁠%>>!%⁠ instead of ⁠%>>%⁠ can give noticeable performance benefits because ⁠%>>%⁠ makes a number of clone()-calls that is quadratic in chain length, ⁠%>>!%⁠ only linear.

concat_graphs(g1, g2, in_place = FALSE) is equivalent to g1 %>>% g2. concat_graphs(g1, g2, in_place = TRUE) is equivalent to g1 %>>!% g2.

Both arguments of ⁠%>>%⁠ are automatically converted to Graphs using as_graph(); this means that objects on either side may be objects that can be automatically converted to PipeOps (such as Learners or Filters), or that can be converted to Graphs. This means, in particular, lists of Graphs, PipeOps or objects convertible to that, because as_graph() automatically applies gunion() to lists. See examples. If the first argument of ⁠%>>!%⁠ is not a Graph, then it is cloned just as when ⁠%>>%⁠ is used; ⁠%>>!%⁠ only avoids clone() if the first argument is a Graph.

Note that if g1 is NULL, g2 converted to a Graph will be returned. Analogously, if g2 is NULL, g1 converted to a Graph will be returned.


g1 %>>% g2

concat_graphs(g1, g2, in_place = FALSE)

g1 %>>!% g2



(Graph | PipeOp | Learner | Filter | list | ...)
Graph / PipeOp / object-convertible-to-PipeOp to put in front of g2.


(Graph | PipeOp | Learner | Filter | list | ...)
Graph / PipeOp / object-convertible-to-PipeOp to put after g1.


Whether to try to avoid cloning g1. If g1 is not a Graph, then it is cloned regardless.


Graph: the constructed Graph.

See Also

Other Graph operators: as_graph(), as_pipeop(), assert_graph(), assert_pipeop(), chain_graphs(), greplicate(), gunion(), mlr_graphs_greplicate


o1 = PipeOpScale$new()
o2 = PipeOpPCA$new()
o3 = PipeOpFeatureUnion$new(2)

# The following two are equivalent:
pipe1 = o1 %>>% o2

pipe2 = Graph$new()$
  add_edge(o1$id, o2$id)

# Note automatical gunion() of lists.
# The following three are equivalent:
graph1 = list(o1, o2) %>>% o3

graph2 = gunion(list(o1, o2)) %>>% o3

graph3 = Graph$new()$
  add_edge(o1$id, o3$id, dst_channel = 1)$
  add_edge(o2$id, o3$id, dst_channel = 2)

pipe1 %>>!% o3  # modify pipe1 in-place

pipe1  # contains o1, o2, and o3 now.

o1 %>>!% o2

o1  # not changed, becuase not a Graph.

mlr3pipelines documentation built on May 31, 2023, 9:26 p.m.