Differences between %.% (dplyr) and %% (magrittr)
dplyr now imports %>%
from magrittr and uses it by default. See this answer for details.
Differences include
you can use a
.
as placeholder for the left-hand side, e.g.iris %>% plot(Sepal.Length ~ Sepal.Width, data = .)
%>%
respects(rhs)
, e.g.1:10 %>% (call("sum"))
1:10 %>% (function(x) x^2 + 2*x)For a more useful
example of this, see
https://gist.github.com/anonymous/0c69b019d0b4f6ae5050For
single argument function calls, you can omit parens:"2014-05-18" %>% as.Date
What is the difference between %% and %,% in magrittr?
The normal piping operator is %>%
. You can use %,%
to create a reusable pipe, a pipe without data. Then later you can use the same pipe with various data sets. Here is an example.
library(magrittr)
library(dplyr)
library(Lahman)
Suppose you want to calculate the top 5 baseball players, according to total hits. Then you can do something like this (taken from the magrittr README):
Batting %>%
group_by(playerID) %>%
summarise(total = sum(G)) %>%
arrange(desc(total)) %>%
head(5)
# Source: local data frame [5 x 2]
#
# playerID total
# 1 rosepe01 3562
# 2 yastrca01 3308
# 3 aaronha01 3298
# 4 henderi01 3081
# 5 cobbty01 3035
So far so good. Now let's assume that you have several data sets in the same format as Batting
, so you could just reuse the same pipe again. %,%
helps you create, save and reuse the pipe:
top_total <- group_by(playerID) %,%
summarise(total = sum(G)) %,%
arrange(desc(total)) %,%
head(5)
top_total(Batting)
# Source: local data frame [5 x 2]
#
# playerID total
# 1 rosepe01 3562
# 2 yastrca01 3308
# 3 aaronha01 3298
# 4 henderi01 3081
# 5 cobbty01 3035
Of course you could also create a function the regular R way, i.e. top_total <- function(...) ...
, but %,%
is a more concise way.
Dplyr or Magrittr - tolower?
Using magrittr
's "compound assignment pipe-operator" %<>%
might be, if I understand your question correctly, an even more succinct option.
library("magrittr")
names(iris) %<>% tolower
?`%<>%` # for more
What does %% function mean in R?
%...% operators
%>%
has no builtin meaning but the user (or a package) is free to define operators of the form %whatever%
in any way they like. For example, this function will return a string consisting of its left argument followed by a comma and space and then it's right argument.
"%,%" <- function(x, y) paste0(x, ", ", y)
# test run
"Hello" %,% "World"
## [1] "Hello, World"
The base of R provides %*%
(matrix mulitiplication), %/%
(integer division), %in%
(is lhs a component of the rhs?), %o%
(outer product) and %x%
(kronecker product). It is not clear whether %%
falls in this category or not but it represents modulo.
expm The R package, expm, defines a matrix power operator %^%
. For an example see Matrix power in R .
operators The operators R package has defined a large number of such operators such as %!in%
(for not %in%
). See http://cran.r-project.org/web/packages/operators/operators.pdf
igraph This package defines %--% , %->% and %<-% to select edges.
lubridate This package defines %m+% and %m-% to add and subtract months and %--% to define an interval. igraph also defines %--% .
Pipes
magrittr In the case of %>%
the magrittr R package has defined it as discussed in the magrittr vignette. See http://cran.r-project.org/web/packages/magrittr/vignettes/magrittr.html
magittr has also defined a number of other such operators too. See the Additional Pipe Operators section of the prior link which discusses %T>%
, %<>%
and %$%
and http://cran.r-project.org/web/packages/magrittr/magrittr.pdf for even more details.
dplyr The dplyr R package used to define a %.%
operator which is similar; however, it has been deprecated and dplyr now recommends that users use %>%
which dplyr imports from magrittr and makes available to the dplyr user. As David Arenburg has mentioned in the comments this SO question discusses the differences between it and magrittr's %>%
: Differences between %.% (dplyr) and %>% (magrittr)
pipeR The R package, pipeR, defines a %>>%
operator that is similar to magrittr's %>% and can be used as an alternative to it. See http://renkun.me/pipeR-tutorial/
The pipeR package also has defined a number of other such operators too. See: http://cran.r-project.org/web/packages/pipeR/pipeR.pdf
postlogic The postlogic package defined %if%
and %unless%
operators.
wrapr The R package, wrapr, defines a dot pipe %.>%
that is an explicit version of %>%
in that it does not do implicit insertion of arguments but only substitutes explicit uses of dot on the right hand side. This can be considered as another alternative to %>%
. See https://winvector.github.io/wrapr/articles/dot_pipe.html
Bizarro pipe. This is not really a pipe but rather some clever base syntax to work in a way similar to pipes without actually using pipes. It is discussed in http://www.win-vector.com/blog/2017/01/using-the-bizarro-pipe-to-debug-magrittr-pipelines-in-r/ The idea is that instead of writing:
1:8 %>% sum %>% sqrt
## [1] 6
one writes the following. In this case we explicitly use dot rather than eliding the dot argument and end each component of the pipeline with an assignment to the variable whose name is dot (.
) . We follow that with a semicolon.
1:8 ->.; sum(.) ->.; sqrt(.)
## [1] 6
Update Added info on expm package and simplified example at top. Added postlogic package.
Update 2 The development version of R has defined a |>
pipe. Unlike magrittr's %>%
it can only substitute into the first argument of the right hand side. Although limited, it works via syntax transformation so it has no performance impact.
What does %% mean in R
The infix operator %>%
is not part of base R, but is in fact defined by the package magrittr
(CRAN) and is heavily used by dplyr
(CRAN).
It works like a pipe, hence the reference to Magritte's famous painting The Treachery of Images.
What the function does is to pass the left hand side of the operator to the first argument of the right hand side of the operator. In the following example, the data frame iris
gets passed to head()
:
library(magrittr)
iris %>% head()
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.1 3.5 1.4 0.2 setosa
2 4.9 3.0 1.4 0.2 setosa
3 4.7 3.2 1.3 0.2 setosa
4 4.6 3.1 1.5 0.2 setosa
5 5.0 3.6 1.4 0.2 setosa
6 5.4 3.9 1.7 0.4 setosa
Thus, iris %>% head()
is equivalent to head(iris)
.
Often, %>%
is called multiple times to "chain" functions together, which accomplishes the same result as nesting. For example in the chain below, iris
is passed to head()
, then the result of that is passed to summary()
.
iris %>% head() %>% summary()
Thus iris %>% head() %>% summary()
is equivalent to summary(head(iris))
. Some people prefer chaining to nesting because the functions applied can be read from left to right rather than from inside out.
Should I use %$% instead of %%?
No, you shouldn't use %$%
routinely. It is like using the with()
function, i.e. it exposes the component parts of the LHS when evaluating the RHS. But it only works when the value on the left has names like a list or dataframe, so you can't always use it. For example,
library(magrittr)
x <- 1:10
x %>% mean()
#> [1] 5.5
x %$% mean()
#> Error in eval(substitute(expr), data, enclos = parent.frame()): numeric 'envir' arg not of length one
Created on 2022-02-06 by the reprex package (v2.0.1.9000)
You'd get a similar error with x %$% mean(.)
.
Even when the LHS has names, it doesn't automatically put the .
argument in the first position. For example,
mtcars %>% nrow()
#> [1] 32
mtcars %$% nrow()
#> Error in nrow(): argument "x" is missing, with no default
Created on 2022-02-06 by the reprex package (v2.0.1.9000)
In this case mtcars %$% nrow(.)
would work, because mtcars
has names.
Your example involving .$hp
and .$mpg
is illustrating one of the oddities of magrittr
pipes. Because the .
is only used in expressions, not alone as an argument, it is passed as the first argument as well as being passed in those expressions. You can avoid this using braces, e.g.
mtcars %>% {plot(.$hp, .$mpg)}
dplyr piping data - difference between `.` and `.x`
The .
is the basic unit of transfer for the magrittr
pipelines (which dplyr
imports). It contains the value coming from the pipe.
The .x
value is something that the tidyverse world added. It's used then you have anonymous functions created with the ~
(tilde) syntax. This calls rlang::as_function
to turn that formula into a function. It's basically a short cut so rather than having to type out function(x) x+5
, you can just write ~.x+5
. Since functions can have more than one parameter, it can be helpful to use names for that parameter so .x
refers to the first parameter (and .y
the second). The as_function
also allows you to use .
as an alias for the first parameter. It can do this because the ~
creates a formula and magrittr
doesn't generally replaces .
in formulas so the mapper is free to re-interpret the .
. You can see the function signature here
f <- rlang::as_function(~.x+5)
f
# <lambda>
# function (..., .x = ..1, .y = ..2, . = ..1)
# .x + 5
# attr(,"class")
# [1] "rlang_lambda_function"
You can see how both .
and .x
are alias for ..1
which is the first parameter passed to the function.
How to avoid matrix/dataframe being piped (%%) into list as an element in R
So, after I posted, I realised I hadn't really considered to check if there are other operators that might work. According to magrittr
's introduction page, "the “exposition” pipe, %$%
exposes the names within the left-hand side object to the right-hand side expression." It seems it wasn't necessarily intended for this purpose, but I replaced %>%
with %$%
, and now it works! (I am still unaware of potentioal drawback to using %$%
, so any comments on this is appreciated.)
library(magrittr)
matrix(1:16, ncol = 4) %>% as.data.frame() %$%
list(
a = list(
cor(.[,1:2]),
cov(.[,1:2])
),
b = list(
cor(.[,3:4]),
cov(.[,3:4])
)
)
# $a
# A matrix: 2 × 2 of type dbl
# V1 V2
# V1 1 1
# V2 1 1
# A matrix: 2 × 2 of type dbl
# V1 V2
# V1 1.666667 1.666667
# V2 1.666667 1.666667
# $b
# A matrix: 2 × 2 of type dbl
# V3 V4
# V3 1 1
# V4 1 1
# A matrix: 2 × 2 of type dbl
# V3 V4
# V3 1.666667 1.666667
# V4 1.666667 1.666667
R combinations with dot (.), ~, and pipe (%%) operator
That line uses the .
in three different ways.
[1] [2] [3]
aggregate(. ~ cyl, data = ., FUN = . %>% mean %>% round(2))
Generally speaking you pass in the value from the pipe into your function at a specific location with .
but there are some exceptions. One exception is when the .
is in a formula. The ~
is used to create formulas in R. The pipe wont change the meaning of the formula, so it behaves like it would without any escaping. For example
aggregate(. ~ cyl, data=mydata)
And that's just because aggregate
requires a formula with both a left and right hand side. So the .
at [1]
just means "all the other columns in the dataset." This use is not at all related to magrittr.
The .
at [2]
is the value that's being passed in as the pipe. If you have a plain .
as a parameter to the function, that's there the value will be placed. So the result of the subset()
will go to the data=
parameter.
The magrittr
library also allows you to define anonymous functions with the .
variable. If you have a chain that starts with a .
, it's treated like a function. so
. %>% mean %>% round(2)
is the same as
function(x) round(mean(x), 2)
so you're just creating a custom function with the .
at [3]
Related Topics
Download Attachment from an Outlook Email Using R
Change the Color of Action Button in Shiny
What's the Difference Between Facet_Wrap() and Facet_Grid() in Ggplot2
Add Author Affiliation in R Markdown Beamer Presentation
R- Shiny Webserver on a Local Server
Knitr: Run All Chunks in an Rmarkdown Document
Dply: Order Columns Alphabetically in R
Putting X-Axis at Top of Ggplot2 Chart
Plot Mixed Effects Model in Ggplot
R: Legend with Points and Lines Being Different Colors (For the Same Legend Item)
Fastest Way to Detect If Vector Has at Least 1 Na
Quickly Remove Zero Variance Variables from a Data.Frame
Save All Plots Already Present in the Panel of Rstudio
Use R to Convert PDF Files to Text Files for Text Mining
Trying to Find Row Associated with Max Value in Dataframe R
Combine Multiple Plots, Generated Using the "By" R Function, in One Figure