1

Magrittr has those different pipes:

  • %>% Pipe
  • %<>% Assignment pipe
  • %$% Exposition pipe
  • %!>% Eager pipe
  • %T>% Tee pipe

What are their differences and use cases?

GKi
  • 37,245
  • 2
  • 26
  • 48

1 Answers1

4

%>% Pipe

Pipe an object forward into a function or call expression.

library(magrittr)
1:10 %>% head()   # Basic use
#[1] 1 2 3 4 5 6
1:10 %>% head     # Works also
#[1] 1 2 3 4 5 6
#1:3 %>% approxfun(1:3, 4:6)  #But in this case empty parentheses are needed
#Error in if (is.na(method)) stop("invalid interpolation method") :
1:3 %>% approxfun(1:3, 4:6)()
#[1] 4 5 6

1:10 %>% head(3)  # Use with lhs as first argument
#[1] 1 2 3

"Ceci n'est pas une pipe" %>% gsub("une", "un", .)  # Using the dot place-holder
#[1] "Ceci n'est pas un pipe"

1:3 %>% paste0(LETTERS[.], 0)    # When dot is nested, lhs is still placed first
#[1] "1A0" "2B0" "3C0"
1:3 %>% {paste0(LETTERS[.], 0)}  # This can be avoided with {}
#[1] "A0" "B0" "C0"

See also: What are the disadvantages when using a function without empty parentheses with %>% the pipe of magrittr?.

%<>% Assignment pipe

Pipe an object forward into a function or call expression and update the lhs object with the resulting value.

x <- -2:2
x %<>% abs %>% sort
x  # 0 1 1 2 2

%$% Exposition pipe

Expose the names in lhs to the rhs expression. This is useful when functions do not have a built-in data argument.

iris %$% cor(Sepal.Length, Sepal.Width)
#[1] -0.1175698

See also: Should I use %$% instead of %>%?.

%!>% Eager pipe

Evaluate from left to right. Whereas %>% is lazy and only evaluates the piped expressions when needed, %!>% is eager and evaluates the piped input at each step. Also it evaluates in the same environment.

0 %!>% (\(x) {cat(1); x}) %!>% (\(x) cat(2))  # Evaluates from left to right
#12
0 %>% (\(x) {cat(1); x}) %>% (\(x) cat(2))    # Evaluates only cat(2) as the first result is never used
#2

1 %!>% assign("a", .)  # Work
a
#[1] 1
0 %>% assign("a", .)   # Does not work as there is an additional environment
a
#[1] 1
0 %>% assign("a", ., envir=parent.env(environment())) # Give explicitly where to evaluate
a
#[1] 0

%T>% Tee pipe

Pipe a value forward into a function- or call expression and return the original value instead of the result. This is useful when an expression is used for its side-effect, say plotting or printing.

matrix(1:4, 2) %T>% plot %>% sum  # sum gets the same data like plot
#[1] 10

See also: magrittr tee pipe %T>% equivalent.

GKi
  • 37,245
  • 2
  • 26
  • 48
  • 2
    For the “basic use” it is probably worth noting that the most widely (?) recommended convention (though the original ‘magrittr’ author does not share this preference) is to supply empty parentheses to the RHS, i.e. to write `1:10 %>% head()`, because otherwise the notation becomes confusing/inconsistent when dealing with functions that return functions. (It’s for this reason that the native pipe `|>` *requires* the parentheses). – Konrad Rudolph May 24 '23 at 19:18
  • Thanks I have changed it but they call and use it that way. See `?"%>%"` in Examples or https://magrittr.tidyverse.org/reference/pipe.html#ref-examples . Maybe it comes from as it could also be used in that form `\`%>%\`(1:5, sum)` and here it is common just to use the name of the function like in `sapply(list(1:5), sum)`. – GKi May 25 '23 at 02:06
  • Well like I said, the original package author disagrees with this widespread preference, but he is one of the few who do, and there are good technical reasons for preferring `()` after the function call, whereas the only reason *against* them are a minimal win in conciseness. And, notably, passing a function call expression to a pipe operation is fundamentally different from passing a *function* to a call. The two are conceptually very different. And in particular `sapply(1:5, f())` works and does something different from `sapply(1:5, f)`, for a suitably defined `f`. – Konrad Rudolph May 25 '23 at 07:55
  • Thanks! I have asked a question with this topic: https://stackoverflow.com/questions/76335609 – GKi May 25 '23 at 19:21