4 Pipes

4.1 Introduction

Use %>% when you find yourself composing three or more functions together into a nested call, or creating intermediate objects that you don’t care about. Put each verb on its own line. This makes it simpler to rearrange them later, and makes it harder to overlook a step. It is ok to keep a one-step pipe in one line.

# Good
foo_foo %>%
  hop(through = forest) %>%
  scoop(up = field_mouse) %>%
  bop(on = head)

# Bad
foo_foo <- hop(foo_foo, through = forest)
foo_foo <- scoop(foo_foo, up = field_mice)
foo_foo <- bop(foo_foo, on = head)

iris %>% group_by(up) %>% summarize_all(mean) %>%
  ungroup %>% gather(field_mice, foo_foo, -on) %>%

    hop(foo_foo, through = forest),
    up = field_mice
  on = head

(If you’re not familiar with Litte)

Avoid using the pipe when:

  • You need to manipulate more than one object at a time. Reserve pipes for a sequence of steps applied to one primary object.

  • There are meaningful intermediate objects that could be given informative names.

4.2 Spacing and indenting

%>% should always have a space before it and a new line after it. After the first step, each line should be indented by two spaces.

# Good
iris %>%
  group_by(Species) %>%
  summarize_if(is.numeric, mean) %>%
  ungroup() %>%
  gather(measure, value, -Species) %>%

# Bad
iris %>% group_by(Species) %>% summarize_all(mean) %>%
ungroup %>% gather(measure, value, -Species) %>%

It is ok to keep a one-step pipe on one line, although depending on the context, you may want to rewrite to remove the pipe.

# Good
iris %>% arrange(Petal.Width)
arrange(iris, Petal.Width)

4.3 No arguments

magrittr allows you to omit () on functions that don’t have arguments. Avoid this.

# Good
x %>% 
  unique() %>%

# Bad
x %>% 
  unique %>%

4.4 Long lines

If the arguments to a function don’t all fit on one line, put each argument on its own line and indent:

iris %>%
  group_by(Species) %>%
    Sepal.Length = mean(Sepal.Length),
    Sepal.Width = mean(Sepal.Width),
    Sepcies = n_distinct(Species)

4.5 Assignment

You can use -> to create an object at the end of the pipe.

Personally, I think you should avoid this technique. While starting with the assignment is a little more work when writing the code, it makes reading the code easier. This is because the name acts as a heading, which reminds you of the purpose of the pipe.


In data analysis code, use comments to record important findings and analysis decisions. If you need comments to explain what your code is doing, consider rewriting your code to be clearer. If you discover that you have more comments than code, considering switching to RMarkdown.