A Forward-Pipe Operator for R

Provides a mechanism for chaining commands with a new forward-pipe operator, %>%. This operator will forward a value, or the result of an expression, into the next function call/expression. There is flexible support for the type of right-hand side expressions. For more information, see package vignette. To quote Rene Magritte, "Ceci n'est pas un pipe."

magrittr - Ceci n'est pas un pipe.

The magrittr package offers a set of operators which promote semantics that will improve your code by

  • structuring sequences of data operations left-to-right (as opposed to from the inside and out),
  • avoiding nested function calls,
  • minimizing the need for local variables and function definitions, and
  • making it easy to add steps anywhere in the sequence of operations.

The operators pipe their left-hand side values forward into expressions that appear on the right-hand side, i.e. one can replace f(x) with x %>% f, where %>% is the (main) pipe-operator. When coupling several function calls with the pipe-operator, the benefit will become more apparent. Consider this pseudo example

the_data <-
  read.csv('/path/to/data/file.csv') %>%
  subset(variable_a > x) %>%
  transform(variable_c = variable_a/variable_b) %>%

Four operations are performed to arrive at the desired data set, and they are written in a natural order: the same as the order of execution. Also, no temporary variables are needed. If yet another operation is required, it is straight-forward to add to the sequence of operations wherever it may be needed.


To install the current development version use devtools:


To install the CRAN version:



  • x %>% f is equivalent to f(x)
  • x %>% f(y) is equivalent to f(x, y)
  • x %>% f %>% g %>% h is equivalent to h(g(f(x)))
  • x %>% f(y, .) is equivalent to f(y, x)
  • x %>% f(y, z = .) is equivalent to f(y, z = x)

It is straight-forward to use the placeholder several times in a right-hand side expression. However, when the placeholder only appears in a nested expressions magrittr will still apply the first-argument rule. The reason is that in most cases this results more clean code.

x %>% f(y = nrow(.), z = ncol(.)) is equivalent to f(x, y = nrow(x), z = nrow(x))

The behavior can be overruled by enclosing the right-hand side in braces:

x %>% {f(y = nrow(.), z = ncol(.))} is equivalent to f(y = nrow(x), z = nrow(x))

To define a unary function on the fly in the pipeline, enclose the body of such function in braces, and refer to the argument as ., e.g.

iris %>% 
    n <- sample(1:10, size = 1)
    H <- head(., n)
    T <- tail(., n)
    rbind(H, T)
  } %>%

Any pipeline starting with the . will return a function which can later be used to apply the pipeline to values. Building functions in magrittr is therefore similar to building other values.

f <- . %>% cos %>% sin 
# is equivalent to 
f <- function(.) sin(cos(.)) 

Some right-hand sides are used for their side effect (e.g. plotting, printing to a file, etc) and it may be convenient to be able to subsequently continue the pipeline. The "tee" operator, %T>% can be used for this purpose and works exactly like %>%, except it returns the left-hand side value, rather than the potential result of the right-hand side operation:

rnorm(200) %>%
matrix(ncol = 2) %T>%
plot %>% # plot usually does not return anything.

Many functions accept a data argument, e.g. lm and aggregate, which is very useful in a pipeline where data is first processed and then passed into such a function. There are also functions that do not have a data argument, for which it is useful to expose the variables in the data. This is done with the %$% operator:

iris %>%
  subset(Sepal.Length > mean(Sepal.Length)) %$%
  cor(Sepal.Length, Sepal.Width)

data.frame(z = rnorm(100)) %$%

There is also a pipe operator which can be used as shorthand notation in situations where the left-hand side is being "overwritten":

iris$Sepal.Length <- 
  iris$Sepal.Length %>%

To avoid the repetition of the left-hand side immediately after the assignment operator, use the %<>% operator:

iris$Sepal.Length %<>% sqrt 

This operator works exactly like %>%, except the pipeline assigns the result rather than returning it. It must be the first pipe operator in a longer chain.

Further information

For more detail, see the package vignette



Reference manual

It appears you don't have a PDF plugin for this browser. You can click here to download the reference manual.


1.5 by Stefan Milton Bache, 2 years ago

Browse source code at https://github.com/cran/magrittr

Authors: Stefan Milton Bache <stefan@stefanbache.dk> and Hadley Wickham <h.wickham@gmail.com>

Documentation:   PDF Manual  

Task views: Web Technologies and Services

MIT + file LICENSE license

Suggests testthat, knitr

Imported by ARTool, DT, DiagrammeR, FeatureHashing, FedData, GerminaR, Gmisc, Greg, HARtools, HTSSIP, HydeNet, IncucyteDRC, IsingSampler, MakefileR, Momocs, NFP, NNTbiomarker, Plasmidprofiler, QRAGadget, RevEcoR, RmarineHeatWaves, abjutils, analogsea, aoos, apa, archivist, automagic, autothresholdr, bea.R, bkmr, blkbox, blscrapeR, bpa, bsplus, carpenter, ckanr, clusternomics, corrr, curlconverter, cystiSim, dat, datacheckr, datadr, datastepr, ddpcr, dendextend, descriptr, diffrprojects, diffrprojectswidget, dlstats, dplyr, dpmr, drake, dygraphs, easyformatr, eclust, ecoengine, ecoseries, edeaR, eiCompare, elasticIsing, electionsBR, emil, engsoccerdata, episheet, eply, evaluator, eyelinker, fbar, filesstrings, flippant, flood, foghorn, forcats, forecast, fulltext, gRain, gRbase, genderizeR, geojson, geojsonio, gglogo, ggloop, ggvis, gistr, gmailr, gogamer, goldi, googleAnalyticsR, grattan, harrietr, heatmaply, highcharter, hpoPlot, htmlTable, httping, icd, igraph, inferr, jpmesh, jqr, languagelayeR, latex2exp, lawn, lazysql, leaflet, leafletCN, lexRankr, lightsout, linear.tools, lingtypology, listless, livechatR, loopr, lplyr, manhattanly, manifestoR, mason, metacoder, metricsgraphics, mglR, modelr, mousetrap, mtconnectR, multipanelfigure, musica, networkD3, nhanesA, normalr, notifyme, observer, optigrab, owmr, packagedocs, pathological, pdp, pewdata, phangorn, phylocanvas, pipefittr, pixiedust, plotly, poio, poppr, prettyunits, ptstem, purrr, rBayesianOptimization, rFTRLProximal, radiant.basics, radiant.model, radiant.multivariate, rangeMapper, rattle, rbokeh, rdrop2, request, rex, rgbif, rgeoapi, rgho, rgl, rhandsontable, rpdo, rpinterest, rprev, rrr, rscorecard, rslp, rtext, rtide, rtweet, rvest, saeRobust, scanstatistics, scrubr, searchable, simmer, simulator, spark, spongecake, srvyr, ss3sim, statisticalModeling, stringr, striprtf, subspaceMOA, superheat, survminer, taber, tableHTML, templates, testthat, text2vec, tidyRSS, tidyquant, tidyr, tidyverse, tigerhitteR, tigris, timelineS, timevis, tmaptools, unpivotr, useful, vcfR, vegalite, vembedr, visNetwork, wallace, webshot, wellknown, wfindr, widgetframe, wordbankr, wrangle, xgboost, xlutils3, ztype.

Depended on by Luminescence, cleanNLP, efreadr, forestplot, gbp, gitlabr, gwdegree, imager, jug, lidR, multiplyr, packagetrackr, radiant.data, seleniumPipes, skm, sp500SlidingWindow.

Suggested by LW1949, ReporteRs, Rga4gh, SocialMediaLab, TLMoments, WRTDStidal, assertr, backpipe, bayesAB, bossMaps, brr, checkmate, curl, eemR, ensurer, errorlocate, evolqg, exprso, fivethirtyeight, formula.tools, freesurfer, ggstance, icd9, imputeTestbench, infuser, intubate, largeVis, lettercase, magick, medicare, mosaic, mpoly, ngramrr, operator.tools, palettetown, pomp, rAmCharts, recexcavAAR, regexPipes, replyr, rio, rmapshaper, rmetasim, setter, shiny, soql, spAddins, sticky, stremr, tidyjson, toxboot, wikipediatrend, xml2.

Enhanced by cowsay.

See at CRAN