Piping

Nicky Wakim, Jessica Minnier, Meike Niederhausen

What is piping?

  • Pipes (and piping) are used to pass the output of one function as input into another function
  • You can think of pipes as “then” statements

I want to find my keys, then start my car, then drive to work, then park my car.

Nested

park(
  drive(
    start_car(
      find("keys")
      ),
    to = "work"
    )
  )
1
Our first action is embedded the furthest into the nested functions
2
Then the output of “find keys” in the input of “start car” which is nested as well
3
We keep working our way out to “drive”
4
Then we finally park

Piped

find("keys") |>
  start_car() |>
  drive(to = "work") |>
  park()
1
First statement is the first thing we want to do
2
Output of “find keys” is inputted into “start car”
3
Then we drive to work
4
Then we park the car
  • Pipes tend to match our sequential thoughts better

Two types of pipes you might see

  • Two types: |> vs %>%
    • %>% is the original pipe in R (requires magrittr package within tidyverse)
    • |> is a newer pipe (started in 2021 and does not require a package)
  • Both pipes are used to write code from left to right
    • by passing the result of one step into the next

Example using |>

hrs_data |> dim()
[1] 2728   32

Example using %>%

hrs_data %>% dim()
[1] 2728   32
  • You can use either! Our notes will use |> since it is generally where the field is headed.

Simple vs complicated input

Simple: when the receiving function only has one input argument, we can use:

hrs_data |> dim()
1
Just the function name dim with parentheses.
[1] 2728   32
hrs_data %>% dim()
1
Just the function name dim with parentheses.
[1] 2728   32

 

Complicated: when the receiving function has more input arguments, we need to specify where the piped input goes. We do this with a placeholder:

The placeholder for |> is _

hrs_data |>
  lm(height ~ age_yr, data = _)
1
We take the hrs_data and pipe it into a function
2
This function lm requires multiple inputs. height ~ age_yr is one input and hrs_data is the other. hrs_data is represented by _ since it is piped through.

The placeholder for %>% is .

hrs_data %>%
  lm(height ~ age_yr, data = .)
1
We take the hrs_data and pipe it into a function
2
This function lm requires multiple inputs. height ~ age_yr is one input and hrs_data is the other. hrs_data is represented by . since it is piped through.

Notice the code styling

  • We can start a new line after every pipe (|>)
    • R reads this as an incomplete line and will continue to read
hrs_data |>
  lm(height ~ age_yr, data = _)
1
With the |> R will look to the next line for where hrs_data is inputted
2
Then we follow with our desired function
  • If you have many functions in a row, putting each on a new line makes your code easy to follow!
hrs_data |>
  select(height, age_yr) |>
  lm(height ~ age_yr, data = _)
1
With the |> R will look to the next line for where hrs_data is inputted
2
Then I select certain columns of my dataset
3
Then I run that through the lm function
  • You can further style the functions to make their input readable
hrs_data |>
  select(
    height, 
    age_yr
    ) |>
  lm(
    height ~ age_yr, 
    data = _
    )
1
With the |> R will look to the next line for where hrs_data is inputted
2
select is not styled to highlight the input
3
lm is now styled to highlight the input

Resources