Pipes no R: qual usar?

Comparação detalhada entre o pipe nativo |> e o pipe do magrittr %>%, com exemplos práticos e recomendações de uso para cada situação.
R
data-science
pipes
Published

July 17, 2025

Qual pipe usar?

Como comentei acima, o pipe nativo do R foi inspirado no pipe do pacote magrittr, um dos mais populares pacotes criados. Há algumas pequenas diferenças entre o %>% e o |>.

Primeiro, em termos de eficiência, o |> é levemente mais rápido, mas a diferença é praticamente imperceptível.

library(microbenchmark)
library(magrittr)
library(dplyr)

microbenchmark(
  {rnorm(n = 1000) |> mean()},
  {rnorm(n = 1000) %>% mean()}
  )
Unit: microseconds
                               expr   min    lq  mean median    uq    max neval
      {     mean(rnorm(n = 1000)) } 14.68 15.29 16.11  15.76 16.42  28.13   100
 {     rnorm(n = 1000) %>% mean() } 15.29 16.09 18.27  16.85 17.51 127.22   100
 cld
   a
   a

A principal diferença entre os dois é o uso do placeholder. O operador placeholder do magrittr é o ponto . e é mais versátil que o _.

De maneira geral, eles possuem a mesma função

mtcars |>
  filter(cyl == 6) |>
  lm(mpg ~ wt, data = _)

mtcars %>%
  filter(cyl == 6) %>%
  lm(mpg ~ wt, dat = .)

No exemplo abaixo, eu consigo colocar a tabela filtrada dentro da função rownames durante o pipe.

mtcars %>%
  filter(cyl == 6) %>%
  mutate(label = rownames(.))

Isto não funciona com o pipe nativo.

mtcars |>
  filter(cyl == 6) |>
  mutate(label = rownames(_))
Error in mutate(filter(mtcars, cyl == 6), label = rownames("_")): invalid use of pipe placeholder (<input>:3:0)

Isto pode ser bastante conveniente quando se lida com objetos espaciais. Imagine o caso em que se tem um objeto criado com sf que guarda polígonos e se quer encontrar as coordenadas dos centróides destes polígonos.

dat %>%
  st_transform(crs = 4674) %>%
  mutate(
    center = st_centroid(.),
    coords = st_coordinates(center)
    )

Também consegue-se usar o . junto com operadores e não apenas com funções. O código abaixo calcula a raiz do erro quadrado médio dos resíduos da regressão. Isto não é possível com o pipe nativo e exigiria uma função anônima.

fit <- lm(mpg ~ wt, data = mtcars)

fit %>%
  residuals() %>%
  .^2 %>%
  mean() %>%
  sqrt()

O . pode ser seguido de outros operadores como o $1. Assim pode-se extrair uma coluna específica depois de filtrar uma tabela.

mtcars %>%
  filter(cyl == 6) %>%
  .$mpg

O . também pode ser fornecido para múltiplos argumentos como no exemplo abaixo.

mtcars %>%
  anti_join(x = ., y = .)
 [1] mpg  cyl  disp hp   drat wt   qsec vs   am   gear carb
<0 rows> (or 0-length row.names)
mtcars |>
  anti_join(x = _, y = _)
Error in anti_join(x = "_", y = "_"): pipe placeholder may only appear once (<input>:2:3)

Resumo

O pipe é um operador simples que serve para deixar o código mais limpo. Sempre é uma boa escolha usar pipes quando se quer aplicar múltiplas funções num mesmo objeto. O custo do |> é mínimo em termos de eficiência; além disso, ele diminui a necessidade de criar objetos intermediários o que poupa memória do sistema.

O pipe nativo é embutido no R a partir da versão 4.1.0 enquanto o %>% exige library(magrittr). Vale notar que muitos pacotes carregam o %>% automaticamente. De fato, pacotes como dplyr, leaflet, mapview, rvest, gt, flextable e tantos outros são praticamente inutilizáveis sem pipes2.

Antes de pensar em usar o pipe nativo, vale a pena reforçar que ele foi criado recentemente. Isto significa que qualquer código ou pacote desenvolvido com uso de pipes vai exigir a versão 4.1.0 ou superior, o que pode exigir que o usuário atualize a sua versão do R. Além disso, algumas funcionalidades do pipe nativo mudaram nas versões 4.2 e 4.3 o que pode complicar ainda mais o uso do pipe. Em contrapartida, o pipe do magrittr é bastante estável e seu comportamento é consistente há muitos anos.

Qual pipe usar

Para a maioria dos casos, vale usar o pipe nativo do R, já que o %>% exige carregar um pacote adicional. Quando o placeholder for necessário, vale usar o %>% em vez do pipe nativo, devido à sua maior flexibilidade.


Próximos passos na série “Fundamentos do R”

Parabéns! Você completou a série de fundamentos do R. Agora você entende como definir objetos, usar pipes matematicamente e escolher o pipe certo para cada situação.

Continue aprendendo

Próximas séries recomendadas: - Tidyverse: o melhor caminho para começar? - Inicie a série sobre tidyverse - Dicas e truques do R - Série de produtividade (em breve)

Referências

Footnotes

  1. Vale notar que este comportamento foi introduzido também no placeholder do pipe nativo a partir da versão 4.3.0 do R. Contudo, este comportamento ainda está em fase experimental. “As an experimental feature the placeholder _ can now also be used in the rhs of a forward pipe |> expression as the first argument in an extraction call, such as _$coef.”. Link Original.↩︎

  2. Uma quantidade enorme de pacotes utiliza o magrittr como dependência. Veja a página do CRAN.↩︎