magrittr/ 0000755 0001751 0000144 00000000000 12434151335 012122 5 ustar hornik users magrittr/inst/ 0000755 0001751 0000144 00000000000 12434047155 013103 5 ustar hornik users magrittr/inst/doc/ 0000755 0001751 0000144 00000000000 12434047155 013650 5 ustar hornik users magrittr/inst/doc/magrittr.R 0000644 0001751 0000144 00000004177 12434047155 015635 0 ustar hornik users ## ----, echo = FALSE, message = FALSE------------------------------------- library(magrittr) options(scipen = 3) knitr::opts_chunk$set( comment = NA, error = FALSE, tidy = FALSE) ## ------------------------------------------------------------------------ library(magrittr) car_data <- mtcars %>% subset(hp > 100) %>% aggregate(. ~ cyl, data = ., FUN = . %>% mean %>% round(2)) %>% transform(kpl = mpg %>% multiply_by(0.4251)) %>% print ## ------------------------------------------------------------------------ car_data <- transform(aggregate(. ~ cyl, data = subset(mtcars, hp > 100), FUN = function(x) round(mean(x, 2))), kpl = mpg*0.4251) ## ----, eval = FALSE------------------------------------------------------ # car_data %>% # (function(x) { # if (nrow(x) > 2) # rbind(head(x, 1), tail(x, 1)) # else x # }) ## ------------------------------------------------------------------------ car_data %>% { if (nrow(.) > 0) rbind(head(., 1), tail(., 1)) else . } ## ------------------------------------------------------------------------ 1:10 %>% (substitute(f(), list(f = sum))) ## ----, fig.keep='none'--------------------------------------------------- rnorm(200) %>% matrix(ncol = 2) %T>% plot %>% # plot usually does not return anything. colSums ## ----, eval = FALSE------------------------------------------------------ # iris %>% # subset(Sepal.Length > mean(Sepal.Length)) %$% # cor(Sepal.Length, Sepal.Width) # # data.frame(z = rnorm(100)) %$% # ts.plot(z) ## ----, eval = FALSE------------------------------------------------------ # iris$Sepal.Length %<>% sqrt ## ------------------------------------------------------------------------ rnorm(1000) %>% multiply_by(5) %>% add(5) %>% { cat("Mean:", mean(.), "Variance:", var(.), "\n") head(.) } ## ----, results = 'hide'-------------------------------------------------- rnorm(100) %>% `*`(5) %>% `+`(5) %>% { cat("Mean:", mean(.), "Variance:", var(.), "\n") head(.) } magrittr/inst/doc/magrittr.Rmd 0000644 0001751 0000144 00000017706 12434047155 016160 0 ustar hornik users ```{r, echo = FALSE, message = FALSE} library(magrittr) options(scipen = 3) knitr::opts_chunk$set( comment = NA, error = FALSE, tidy = FALSE) ```  *This version: November, 2014. Stefan Milton Bache* # Abstract *The magrittr* (to be pronounced with a sophisticated french accent) is a package with two aims: to decrease development time and to improve readability and maintainability of code. Or even shortr: to make your code smokin' (puff puff)! To archive its humble aims, *magrittr* (remember the accent) provides a new "pipe"-like operator, `%>%`, with which you may pipe a value forward into an expression or function call; something along the lines of ` x %>% f `, rather than ` f(x)`. This is not an unknown feature elsewhere; a prime example is the `|>` operator used extensively in `F#` (to say the least) and indeed this -- along with Unix pipes -- served as a motivation for developing the magrittr package. This vignette describes the main features of *magrittr* and demonstrates some features which has been added since the initial release. # Introduction and basics At first encounter, you may wonder whether an operator such as `%>%` can really be all that beneficial; but as you may notice, it semantically changes your code in a way that makes it more intuitive to both read and write. Consider the following example, in which the `mtcars` dataset shipped with R is munged a little. ```{r} library(magrittr) car_data <- mtcars %>% subset(hp > 100) %>% aggregate(. ~ cyl, data = ., FUN = . %>% mean %>% round(2)) %>% transform(kpl = mpg %>% multiply_by(0.4251)) %>% print ``` We start with a value, here `mtcars` (a `data.frame`). Based on this, we first extract a subset, then we aggregate the information based on the number of cylinders, and then we transform the dataset by adding a variable for kilometers per liter as supplement to miles per gallon. Finally we print the result before assigning it. Note how the code is arranged in the logical order of how you think about the task: data->transform->aggregate, which is also the same order as the code will execute. It's like a recipe -- easy to read, easy to follow! A horrific alternative would be to write ```{r} car_data <- transform(aggregate(. ~ cyl, data = subset(mtcars, hp > 100), FUN = function(x) round(mean(x, 2))), kpl = mpg*0.4251) ``` There is a lot more clutter with parentheses, and the mental task of deciphering the code is more challenging---in particular if you did not write it yourself. Note also how "building" a function on the fly for use in `aggregate` is very simple in *magrittr*: rather than an actual value as left-hand side in pipeline, just use the placeholder. This is also very useful in R's `*apply` family of functions. Granted: you may make the second example better, perhaps throw in a few temporary variables (which is often avoided to some degree when using *magrittr*), but one often sees cluttered lines like the ones presented. And here is another selling point. Suppose I want to quickly want to add another step somewhere in the process. This is very easy in the to do in the pipeline version, but a little more challenging in the "standard" example. The combined example shows a few neat features of the pipe (which it is not): 1. By default the left-hand side (LHS) will be *piped in* as the first argument of the function appearing on the right-hand side (RHS). This is the case in the `subset` and `transform` expressions. 2. `%>%` may be used in a nested fashion, e.g. it may appear in expressions within arguments. This is used in the `mpg` to `kpl` conversion. 3. When the LHS is needed at a position other than the first, one can use the dot,`'.'`, as placeholder. This is used in the `aggregate` expression. 4. The dot in e.g. a formula is *not* confused with a placeholder, which is utilized in the `aggregate` expression. 5. Whenever only *one* argument is needed, the LHS, then one can omit the empty parentheses. This is used in the call to `print` (which also returns its argument). Here, `LHS %>% print()`, or even `LHS %>% print(.)` would also work. 6. A pipeline with a dot (`.`) as LHS will create a unary function. This is used to define the aggregator function. One feature, which was not utilized above is piping into *anonymous functions*, or *lambdas*. This is possible using standard function definitions, e.g. ```{r, eval = FALSE} car_data %>% (function(x) { if (nrow(x) > 2) rbind(head(x, 1), tail(x, 1)) else x }) ``` However, *magrittr* also allows a short-hand notation: ```{r} car_data %>% { if (nrow(.) > 0) rbind(head(., 1), tail(., 1)) else . } ``` Since all right-hand sides are really "body expressions" of unary functions, this is only the natural extension the simple right-hand side expressions. Of course longer and more complex functions can be made using this approach. In the first example the anonymous function is enclosed in parentheses. Whenever you want to use a function- or call-generating statement as right-hand side, parentheses are used to evaluate the right-hand side before piping takes place. Another, less useful example is: ```{r} 1:10 %>% (substitute(f(), list(f = sum))) ``` # Additional pipe operators *magrittr* also provides three related pipe operators. These are not as common as `%>%` but they become useful in special cases. The "tee" operator, `%T>%` works like `%>%`, except it returns the left-hand side value, and not the result of the right-hand side operation. This is useful when a step in a pipeline is used for its side-effect (printing, plotting, logging, etc.). As an example (where the actual plot is omitted here): ```{r, fig.keep='none'} rnorm(200) %>% matrix(ncol = 2) %T>% plot %>% # plot usually does not return anything. colSums ``` The "exposition" pipe operator, `%$%` exposes the names within the left-hand side object to the right-hand side expression. Essentially, it is a short-hand for using the `with` functions (and the same left-hand side objects are accepted). This operator is handy when functions do not themselves have a data argument, as for example `lm` and `aggregate` do. Here are a few examples as illustration: ```{r, eval = FALSE} iris %>% subset(Sepal.Length > mean(Sepal.Length)) %$% cor(Sepal.Length, Sepal.Width) data.frame(z = rnorm(100)) %$% ts.plot(z) ``` Finally, the compound assignment pipe operator `%<>%` can be used as the first pipe in a chain. The effect will be that the result of the pipeline is assigned to the left-hand side object, rather than returning the result as usual. It is essentially shorthand notation for expressions like `foo <- foo %>% bar %>% baz`, which boils down to `foo %<>% bar %>% baz`. Another example is ```{r, eval = FALSE} iris$Sepal.Length %<>% sqrt ``` The `%<>%` can be used whenever `expr <- ...` makes sense, e.g. * `x %<>% foo %>% bar` * `x[1:10] %<>% foo %>% bar` * `x$baz %<>% foo %>% bar` # Aliases In addition to the `%>%`-operator, *magrittr* provides some aliases for other operators which make operations such as addition or multiplication fit well into the *magrittr*-syntax. As an example, consider: ```{r} rnorm(1000) %>% multiply_by(5) %>% add(5) %>% { cat("Mean:", mean(.), "Variance:", var(.), "\n") head(.) } ``` which could be written in more compact form as ```{r, results = 'hide'} rnorm(100) %>% `*`(5) %>% `+`(5) %>% { cat("Mean:", mean(.), "Variance:", var(.), "\n") head(.) } ``` To see a list of the aliases, execute e.g. `?multiply_by`. # Development The *magrittr* package is also available in a development version at the GitHub development page: [github.com/smbache/magrittr](http://github.com/smbache/magrittr). magrittr/inst/doc/magrittr.html 0000644 0001751 0000144 00000443603 12434047155 016401 0 ustar hornik users
This version: November, 2014. Stefan Milton Bache
The magrittr (to be pronounced with a sophisticated french accent) is a package with two aims: to decrease development time and to improve readability and maintainability of code. Or even shortr: to make your code smokin' (puff puff)!
To archive its humble aims, magrittr (remember the accent) provides a new
“pipe”-like operator, %>%
, with which you may pipe a value forward into an
expression or function call; something along the lines of x %>% f
, rather
than f(x)
. This is not an unknown feature
elsewhere; a prime example is the |>
operator used extensively in F#
(to say the least) and indeed this – along with Unix pipes – served as a
motivation for developing the magrittr package.
This vignette describes the main features of magrittr and demonstrates some features which has been added since the initial release.
At first encounter, you may wonder whether an operator such as %>%
can really
be all that beneficial; but as you may notice, it semantically changes your
code in a way that makes it more intuitive to both read and write.
Consider the following example, in which the mtcars
dataset shipped with
R is munged a little.
library(magrittr)
car_data <-
mtcars %>%
subset(hp > 100) %>%
aggregate(. ~ cyl, data = ., FUN = . %>% mean %>% round(2)) %>%
transform(kpl = mpg %>% multiply_by(0.4251)) %>%
print
cyl mpg disp hp drat wt qsec vs am gear carb kpl
1 4 25.90 108.0 111.0 3.94 2.15 17.75 1.00 1.00 4.50 2.00 11.010
2 6 19.74 183.3 122.3 3.59 3.12 17.98 0.57 0.43 3.86 3.43 8.391
3 8 15.10 353.1 209.2 3.23 4.00 16.77 0.00 0.14 3.29 3.50 6.419
We start with a value, here mtcars
(a data.frame
). Based on this, we
first extract a subset, then we aggregate the information based on the number
of cylinders, and then we transform the dataset by adding a variable
for kilometers per liter as supplement to miles per gallon. Finally we print
the result before assigning it.
Note how the code is arranged in the logical
order of how you think about the task: data->transform->aggregate, which
is also the same order as the code will execute. It's like a recipe – easy to
read, easy to follow!
A horrific alternative would be to write
car_data <-
transform(aggregate(. ~ cyl,
data = subset(mtcars, hp > 100),
FUN = function(x) round(mean(x, 2))),
kpl = mpg*0.4251)
There is a lot more clutter with parentheses, and the mental task of deciphering the code is more challenging—in particular if you did not write it yourself.
Note also how “building” a function on the fly for use in aggregate
is very
simple in magrittr: rather than an actual value as left-hand side in
pipeline, just use the placeholder. This is also very useful in R's
*apply
family of functions.
Granted: you may make the second example better, perhaps throw in a few temporary variables (which is often avoided to some degree when using magrittr), but one often sees cluttered lines like the ones presented.
And here is another selling point. Suppose I want to quickly want to add another step somewhere in the process. This is very easy in the to do in the pipeline version, but a little more challenging in the “standard” example.
The combined example shows a few neat features of the pipe (which it is not):
subset
and transform
expressions.%>%
may be used in a nested fashion, e.g. it may appear in expressions within
arguments. This is used in the mpg
to kpl
conversion.'.'
, as placeholder. This is used in the aggregate
expression.aggregate
expression.print
(which also returns its
argument). Here, LHS %>% print()
, or even LHS %>% print(.)
would also work..
) as LHS will create a unary function. This is
used to define the aggregator function.One feature, which was not utilized above is piping into anonymous functions, or lambdas. This is possible using standard function definitions, e.g.
car_data %>%
(function(x) {
if (nrow(x) > 2)
rbind(head(x, 1), tail(x, 1))
else x
})
However, magrittr also allows a short-hand notation:
car_data %>%
{
if (nrow(.) > 0)
rbind(head(., 1), tail(., 1))
else .
}
cyl mpg disp hp drat wt qsec vs am gear carb kpl
1 4 26 108 111 4 2 18 1 1 4 2 11.053
3 8 15 350 192 3 4 17 0 0 3 4 6.377
Since all right-hand sides are really “body expressions” of unary functions, this is only the natural extension the simple right-hand side expressions. Of course longer and more complex functions can be made using this approach.
In the first example the anonymous function is enclosed in parentheses. Whenever you want to use a function- or call-generating statement as right-hand side, parentheses are used to evaluate the right-hand side before piping takes place.
Another, less useful example is:
1:10 %>% (substitute(f(), list(f = sum)))
[1] 55
magrittr also provides three related pipe operators. These are not as
common as %>%
but they become useful in special cases.
The “tee” operator, %T>%
works like %>%
, except it returns the left-hand
side value, and not the result of the right-hand side operation.
This is useful when a step in a pipeline is used for its side-effect (printing,
plotting, logging, etc.). As an example (where the actual plot is omitted here):
rnorm(200) %>%
matrix(ncol = 2) %T>%
plot %>% # plot usually does not return anything.
colSums
[1] 6.916 -1.605
The “exposition” pipe operator, %$%
exposes the names within the left-hand side
object to the right-hand side expression. Essentially, it is a short-hand for
using the with
functions (and the same left-hand side objects are accepted).
This operator is handy when functions do not themselves have a data argument, as for
example lm
and aggregate
do. Here are a few examples as illustration:
iris %>%
subset(Sepal.Length > mean(Sepal.Length)) %$%
cor(Sepal.Length, Sepal.Width)
data.frame(z = rnorm(100)) %$%
ts.plot(z)
Finally, the compound assignment pipe operator %<>%
can be used as the first pipe
in a chain. The effect will be that the result of the pipeline is assigned to the
left-hand side object, rather than returning the result as usual. It is essentially
shorthand notation for expressions like foo <- foo %>% bar %>% baz
, which
boils down to foo %<>% bar %>% baz
. Another example is
iris$Sepal.Length %<>% sqrt
The %<>%
can be used whenever expr <- ...
makes sense, e.g.
x %<>% foo %>% bar
x[1:10] %<>% foo %>% bar
x$baz %<>% foo %>% bar
In addition to the %>%
-operator, magrittr provides some aliases for other
operators which make operations such as addition or multiplication fit well
into the magrittr-syntax. As an example, consider:
rnorm(1000) %>%
multiply_by(5) %>%
add(5) %>%
{
cat("Mean:", mean(.),
"Variance:", var(.), "\n")
head(.)
}
Mean: 5.04 Variance: 23.25
[1] 10.019 -10.231 -3.341 -4.997 -1.728 8.690
which could be written in more compact form as
rnorm(100) %>% `*`(5) %>% `+`(5) %>%
{
cat("Mean:", mean(.), "Variance:", var(.), "\n")
head(.)
}
To see a list of the aliases, execute e.g. ?multiply_by
.
The magrittr package is also available in a development version at the GitHub development page: github.com/smbache/magrittr.
magrittr/tests/ 0000755 0001751 0000144 00000000000 12434047153 013266 5 ustar hornik users magrittr/tests/testthat/ 0000755 0001751 0000144 00000000000 12434047153 015126 5 ustar hornik users magrittr/tests/testthat/test-fseq.r 0000644 0001751 0000144 00000000314 12434047153 017222 0 ustar hornik users context("functional sequences") test_that("fseq functions work", { a <- . %>% cos %>% sin %>% tan b <- function(x) tan(sin(cos(x))) expect_that(a(1:10), is_identical_to(b(1:10))) }) magrittr/tests/testthat/test-multiple-arguments.r 0000644 0001751 0000144 00000002547 12434047153 022134 0 ustar hornik users context("%>%: multi-argument functions on right-hand side") test_that("placement of lhs is correct in different situations", { # When not to be placed in first position and in the presence of # non-placeholder dots, e.g. in formulas. case0a <- lm(Sepal.Length ~ ., data = iris) %>% coef case1a <- iris %>% lm(Sepal.Length ~ ., .) %>% coef case2a <- iris %>% lm(Sepal.Length ~ ., data = .) %>% coef expect_that(case1a, is_equivalent_to(case0a)) expect_that(case2a, is_equivalent_to(case0a)) # In first position and used in arguments case0b <- transform(iris, Species = substring(Species, 1, 1)) case1b <- iris %>% transform(Species = Species %>% substr(1, 1)) case2b <- iris %>% transform(., Species = Species %>% substr(., 1, 1)) expect_that(case1b, is_equivalent_to(case0b)) expect_that(case2b, is_equivalent_to(case0b)) # LHS function values case0c <- aggregate(. ~ Species, iris, function(x) mean(x >= 5)) case1c <- (function(x) mean(x >= 5)) %>% aggregate(. ~ Species, iris, .) expect_that(case1c, is_equivalent_to(case0c)) # several placeholder dots expect_that(iris %>% identical(., .), is_true()) # "indirect" function expressions expect_that(1:100 %>% iris[., ], is_identical_to(iris[1:100, ])) }) magrittr/tests/testthat/test-anonymous-functions.r 0000644 0001751 0000144 00000003426 12434047153 022331 0 ustar hornik users context("%>%: anonymous functions on right-hand side") test_that("%>% handles anonymous functions in GlobalEnv", { # Simple vectorized function a <- (function(x) 1 + x^2/2 + x^3/9 + x^4/16)(1:100) b <- 1:100 %>% (function(x) 1 + x^2/2 + x^3/9 + x^4/16) # in principle, the dot should also work: c <- 1:100 %>% (function(x) 1 + x^2/2 + x^3/9 + x^4/16)(.) expect_that(a, is_identical_to(b)) expect_that(a, is_identical_to(c)) # Same using preferred magrittr syntax a <- (function(x) 1 + x^2/2 + x^3/9 + x^4/16)(1:100) b <- 1:100 %>% {1 + .^2/2 + .^3/9 + .^4/16} expect_that(a, is_identical_to(b)) # Simple data.frame functions ht1 <- iris %>% (function(x) rbind(head(x), tail(x))) ht2 <- rbind(head(iris), tail(iris)) expect_that(ht1, is_identical_to(ht2)) df1 <- iris[iris$Species == "setosa", 1:4] df2 <- iris %>% (function(x) x[x$Species == "setosa", 1:4]) expect_that(df1, is_identical_to(df2)) }) test_that("%>% handles anonymous functions in other situations.", { # Anonymous functions when %>% used in arguments. df1 <- transform(iris, test = (function(x) x^2)(Sepal.Length)) df2 <- iris %>% transform(test = Sepal.Length %>% (function(x) x^2)) expect_that(df1, is_identical_to(df2)) a <- sin(abs(1:10)) b <- sin(1:10 %>% (function(x) abs(x))) expect_that(a, is_identical_to(b)) # Nested anonymous functions. a <- iris %>% (function(x) x[, 1] %>% (function(y) max(y))) b <- max(iris[, 1]) expect_that(a, is_identical_to(b)) }) test_that("%>% throws error with anonymous functions when not parenthesized.", { expect_that(iris %>% function(x) { head(x) }, throws_error()) }) magrittr/tests/testthat/test-single-argument.r 0000644 0001751 0000144 00000001450 12434047153 021367 0 ustar hornik users context("%>%: one-argument function alternatives.") test_that("%>% works as expected with and without parentheses and placeholder", { expect_that(1:100 %>% sin %>% abs, is_identical_to(abs(sin(1:100)))) expect_that(1:100 %>% sin() %>% abs(), is_identical_to(abs(sin(1:100)))) expect_that(1:100 %>% sin(.) %>% abs(.), is_identical_to(abs(sin(1:100)))) expect_that(iris %>% head, is_identical_to(head(iris))) dnormsd <- function(sd) function(x) dnorm(x, sd = sd) some_x <- rnorm(20) expect_that(some_x %>% dnormsd(5)(.), is_identical_to(dnormsd(5)(some_x))) expect_that(some_x %>% (dnormsd(5)), is_identical_to(dnormsd(5)(some_x))) expect_that(some_x %>% dnormsd(5), throws_error()) expect_that(some_x %>% function(x) {x} %>% sin, throws_error()) }) magrittr/tests/testthat/test-aliases.R 0000644 0001751 0000144 00000003737 12434047153 017661 0 ustar hornik users context("magrittr aliases") test_that("the provided aliases work as intended.", { expect_that(iris %>% extract(, 1:2), is_identical_to(iris[, 1:2])) expect_that(iris %>% extract2(1), is_identical_to(iris[[1]])) expect_that(iris %>% use_series(Species), is_identical_to(iris$Species)) expect_that(1:10 %>% add(10:1), is_identical_to(1:10 + 10:1)) expect_that(1:10 %>% subtract(10:1), is_identical_to(1:10 - 10:1)) expect_that(1:10 %>% multiply_by(10:1), is_identical_to(1:10 * 10:1)) A <- matrix(1:16, 4, 4) expect_that(A %>% multiply_by_matrix(A), is_identical_to(A %*% A)) expect_that(1:10 %>% raise_to_power(10:1), is_identical_to((1:10)^(10:1))) expect_that(1:10 %>% divide_by(10:1), is_identical_to(1:10 / 10:1)) expect_that(1:10 %>% divide_by_int(10:1), is_identical_to(1:10 %/% 10:1)) expect_that(1:10 %>% mod(3), is_identical_to((1:10) %% 3)) expect_that(((1:10) > 5) %>% and((1:10) > 7), is_identical_to(((1:10) > 5) & (1:10) > 7)) expect_that(((1:10) > 5) %>% or((1:10) > 7), is_identical_to(((1:10) > 5) | (1:10) > 7)) expect_that(1:10 %>% (magrittr::equals)(5) %>% sum, is_identical_to(1L)) expect_that(1:10 %>% is_greater_than(5) %>% sum, is_identical_to(5L)) expect_that(1:10 %>% is_weakly_greater_than(5) %>% sum, is_identical_to(6L)) expect_that(1:10 %>% (magrittr::is_less_than)(5) %>% sum, is_identical_to(4L)) expect_that(1:10 %>% is_weakly_less_than(5) %>% sum, is_identical_to(5L)) expect_that(iris %>% set_colnames(LETTERS[1:ncol(iris)]), is_identical_to(`colnames<-`(iris, LETTERS[1:ncol(iris)]))) expect_that(1:10 %>% set_names(LETTERS[1:10]), is_identical_to(`names<-`(1:10, LETTERS[1:10]))) expect_that(diag(3) %>% set_rownames(c("x", "y", "z")), is_identical_to(`rownames<-`(diag(3), c("x", "y", "z")))) expect_that(1:10 %>% is_greater_than(5) %>% not, is_identical_to(1:10 %>% is_weakly_less_than(5))) }) magrittr/tests/testthat/test-compound.R 0000644 0001751 0000144 00000000724 12434047153 020055 0 ustar hornik users context("%<>%: compound assignment") test_that("Compound assignment operator works", { x <- y <- 1:10 x[1:5] <- sin(cos(x[1:5])) y[1:5] %<>% cos %>% sin expect_that(x, is_identical_to(y)) somedata <- iris somedata$Sepal.Length %<>% add(10) iris$Sepal.Length <- iris$Sepal.Length + 10 expect_that(somedata, is_identical_to(iris)) z <- 1:10 z %<>% add(2) %T>% plot expect_that(z, is_identical_to(as.numeric(3:12))) }) magrittr/tests/testthat/test-tee.r 0000644 0001751 0000144 00000000513 12434047153 017042 0 ustar hornik users context("magrittr tee") test_that("tee related functionality works.", { dim_message <- function(data.) message(sprintf("Data has dimension %d x %d", NROW(data.), NCOL(data.))) expect_that(iris %T>% dim_message, shows_message(dim_message(iris))) expect_that(iris %T>% dim_message, is_identical_to(iris)) }) magrittr/tests/test-all.R 0000644 0001751 0000144 00000000051 12434047153 015132 0 ustar hornik users library(testthat) test_check("magrittr") magrittr/NAMESPACE 0000644 0001751 0000144 00000001421 12434047153 013341 0 ustar hornik users # Generated by roxygen2 (4.0.2): do not edit by hand S3method("[",fseq) S3method("[[",fseq) S3method(print,fseq) export("%$%") export("%<>%") export("%>%") export("%T>%") export("n'est pas") export(add) export(and) export(debug_fseq) export(debug_pipe) export(divide_by) export(divide_by_int) export(equals) export(extract) export(extract2) export(freduce) export(functions) export(inset) export(inset2) export(is_greater_than) export(is_in) export(is_less_than) export(is_weakly_greater_than) export(is_weakly_less_than) export(mod) export(multiply_by) export(multiply_by_matrix) export(not) export(or) export(raise_to_power) export(set_colnames) export(set_names) export(set_rownames) export(subtract) export(undebug_fseq) export(use_series) magrittr/R/ 0000755 0001751 0000144 00000000000 12434047153 012325 5 ustar hornik users magrittr/R/split_chain.R 0000644 0001751 0000144 00000002665 12434047153 014756 0 ustar hornik users # Split a chain expression into its components. # # This function splits a chain of pipe calls into its components: its # left-hand side, a sequnce of right-hand sides, and the individual pipe # components. # # @param expr a non-evaluated pipe-line expression. # @param env an environment in which to evaluate rhs parts. # @return a list with components \code{lhs}, \code{rhss}, and \code{pipes}. split_chain <- function(expr, env) { # lists for holding the right-hand sides and the pipe operators. rhss <- list() pipes <- list() # Process the call, splitting it at each valid magrittr pipe operator. i <- 1L while(is.call(expr) && is_pipe(expr[[1L]])) { pipes[[i]] <- expr[[1L]] rhs <- expr[[3L]] if (is_parenthesized(rhs)) rhs <- eval(rhs, env, env) rhss[[i]] <- if (is_dollar(pipes[[i]]) || is_funexpr(rhs)) rhs else if (is_function(rhs)) prepare_function(rhs) else if (is_first(rhs)) prepare_first(rhs) else rhs # Make sure no anonymous functions without parentheses are used. if (is.call(rhss[[i]]) && identical(rhss[[i]][[1L]], quote(`function`))) stop("Anonymous functions myst be parenthesized", call. = FALSE) expr <- expr[[2L]] i <- i + 1L } # return the components; expr will now hold the left-most left-hand side. list(rhss = rev(rhss), pipes = rev(pipes), lhs = expr) } magrittr/R/aliases.R 0000644 0001751 0000144 00000007360 12434047153 014077 0 ustar hornik users #' Aliases #' #' magrittr provides a series of aliases which can be more pleasant to use #' when composing chains using the \code{\%>\%} operator. #' #' Currently implemented aliases are #' \tabular{ll}{ #' \code{extract} \tab \code{`[`} \cr #' \code{extract2} \tab \code{`[[`} \cr #' \code{inset} \tab \code{`[<-`} \cr #' \code{inset2} \tab \code{`[[<-`} \cr #' \code{use_series} \tab \code{`$`} \cr #' \code{add} \tab \code{`+`} \cr #' \code{subtract} \tab \code{`-`} \cr #' \code{multiply_by} \tab \code{`*`} \cr #' \code{raise_to_power} \tab \code{`^`} \cr #' \code{multiply_by_matrix} \tab \code{`\%*\%`} \cr #' \code{divide_by} \tab \code{`/`} \cr #' \code{divide_by_int} \tab \code{`\%/\%`} \cr #' \code{mod} \tab \code{`\%\%`} \cr #' \code{is_in} \tab \code{`\%in\%`} \cr #' \code{and} \tab \code{`&`} \cr #' \code{or} \tab \code{`|`} \cr #' \code{equals} \tab \code{`==`} \cr #' \code{is_greater_than} \tab \code{`>`} \cr #' \code{is_weakly_greater_than} \tab \code{`>=`} \cr #' \code{is_less_than} \tab \code{`<`} \cr #' \code{is_weakly_less_than} \tab \code{`<=`} \cr #' \code{not} (\code{`n'est pas`}) \tab \code{`!`} \cr #' \code{set_colnames} \tab \code{`colnames<-`} \cr #' \code{set_rownames} \tab \code{`rownames<-`} \cr #' \code{set_names} \tab \code{`names<-`} \cr #' } #' #' @usage NULL #' @export #' @rdname aliases #' @name extract #' @examples #' iris %>% #' extract(, 1:4) %>% #' head #' #' good.times <- #' Sys.Date() %>% #' as.POSIXct %>% #' seq(by = "15 mins", length.out = 100) %>% #' data.frame(timestamp = .) #' #' good.times$quarter <- #' good.times %>% #' use_series(timestamp) %>% #' format("%M") %>% #' as.numeric %>% #' divide_by_int(15) %>% #' add(1) extract <- `[` #' @rdname aliases #' @usage NULL #' @export extract2 <- `[[` #' @rdname aliases #' @usage NULL #' @export use_series <- `$` #' @rdname aliases #' @usage NULL #' @export add <- `+` #' @rdname aliases #' @usage NULL #' @export subtract <- `-` #' @rdname aliases #' @usage NULL #' @export multiply_by <- `*` #' @rdname aliases #' @usage NULL #' @export multiply_by_matrix <- `%*%` #' @rdname aliases #' @usage NULL #' @export divide_by <- `/` #' @rdname aliases #' @usage NULL #' @export divide_by_int <- `%/%` #' @rdname aliases #' @usage NULL #' @export raise_to_power <- `^` #' @rdname aliases #' @usage NULL #' @export and <- `&` #' @rdname aliases #' @usage NULL #' @export or <- `|` #' @rdname aliases #' @usage NULL #' @export mod <- `%%` #' @rdname aliases #' @usage NULL #' @export is_in <- `%in%` #' @rdname aliases #' @usage NULL #' @export equals <- `==` #' @rdname aliases #' @usage NULL #' @export is_greater_than <- `>` #' @rdname aliases #' @usage NULL #' @export is_weakly_greater_than <- `>=` #' @rdname aliases #' @usage NULL #' @export is_less_than <- `<` #' @rdname aliases #' @usage NULL #' @export is_weakly_less_than <- `<=` #' @rdname aliases #' @usage NULL #' @export not <- `!` #' @rdname aliases #' @usage NULL #' @export `n'est pas` <- `!` #' @rdname aliases #' @usage NULL #' @export set_colnames <- `colnames<-` #' @rdname aliases #' @usage NULL #' @export set_rownames <- `rownames<-` #' @rdname aliases #' @usage NULL #' @export set_names <- `names<-` #' @rdname aliases #' @usage NULL #' @export inset <- `[<-` #' @rdname aliases #' @usage NULL #' @export inset2 <- `[[<-` magrittr/R/first_type.R 0000644 0001751 0000144 00000001072 12434047153 014640 0 ustar hornik users # Determine whether an expression is of the type that needs a first argument. # # @param a non-evaluated expression. # @return logical - TRUE if expr is of "first-argument" type, FALSE otherwise. is_first <- function(expr) { !any(vapply(expr[-1], identical, logical(1), quote(.))) } # Prepare a magrittr rhs of "first-argument" type. # # @param a an expression which passes \code{is_first} # @return an expression prepared for functional sequence construction. prepare_first <- function(expr) { as.call(c(expr[[1L]], quote(.), as.list(expr[-1L]))) } magrittr/R/debug_pipe.R 0000644 0001751 0000144 00000002212 12434047153 014550 0 ustar hornik users #' Debugging function for magrittr pipelines. #' #' This function is a wrapper around \code{browser}, which makes it #' easier to debug at certain places in a magrittr pipe chain. #' #' @param x a value #' @return x #' #' @export debug_pipe <- function(x) { browser() x } #' Debugging function for functional sequences. #' #' This is a utility function for marking functions in a functional #' sequence for debbuging. #' #' @param fseq a functional sequence. #' @param ... indices of functions to debug. #' @return \code{invisible(NULL)}. #' #' @export debug_fseq <- function(fseq, ...) { is_valid_index <- function(i) i %in% 1:length(functions(fseq)) indices <- list(...) if (!any(vapply(indices, is.numeric, logical(1))) || !any(vapply(indices, is_valid_index, logical(1)))) stop("Index or indices invalid.", call. = FALSE) invisible(lapply(indices, function(i) debug(functions(fseq)[[i]]))) } #' @rdname debug_fseq #' @export undebug_fseq <- function(fseq) { for (i in 1:length(functions(fseq))) if (isdebugged(functions(fseq)[[i]])) undebug(functions(fseq)[[i]]) } magrittr/R/freduce.R 0000644 0001751 0000144 00000001223 12434047153 014063 0 ustar hornik users #' Apply a list of functions sequentially #' #' This function applies the first function to \code{value}, then the #' next function to the result of the previous function call, etc. #' #' @param value initial value. #' @param function_list a list of functions. #' @return The result after applying each function in turn. #' #' #' @export freduce <- function(value, function_list) { k <- length(function_list) if (k > 1) { for (i in 1:(k - 1L)) { value <- function_list[[i]](value) } } value <- withVisible(function_list[[k]](value)) if (value[["visible"]]) value[["value"]] else invisible(value[["value"]]) } magrittr/R/pipe.R 0000644 0001751 0000144 00000024353 12434047153 013414 0 ustar hornik users # Create a pipe operator. # # This function is used to create all the magrittr pipe operators. pipe <- function() { function(lhs, rhs) { # the parent environment parent <- parent.frame() # the environment in which to evaluate pipeline env <- new.env(parent = parent) # split the pipeline/chain into its parts. chain_parts <- split_chain(match.call(), env = env) pipes <- chain_parts[["pipes"]] # the pipe operators. rhss <- chain_parts[["rhss" ]] # the right-hand sides. lhs <- chain_parts[["lhs" ]] # the left-hand side. # Create the list of functions defined by the right-hand sides. env[["_function_list"]] <- lapply(1:length(rhss), function(i) wrap_function(rhss[[i]], pipes[[i]], parent)) # Create a function which applies each of the above functions in turn. env[["_fseq"]] <- `class<-`(eval(quote(function(value) freduce(value, `_function_list`)), env, env), c("fseq", "function")) # make freduce available to the resulting function # even if magrittr is not loaded. env[["freduce"]] <- freduce # Result depends on the left-hand side. if (is_placeholder(lhs)) { # return the function itself. env[["_fseq"]] } else { # evaluate the LHS env[["_lhs"]] <- eval(lhs, parent, parent) # compute the result by applying the function to the LHS result <- withVisible(eval(quote(`_fseq`(`_lhs`)), env, env)) # If compound assignment pipe operator is used, assign result if (is_compound_pipe(pipes[[1L]])) { eval(call("<-", lhs, result[["value"]]), parent, parent) # Otherwise, return it. } else { if (result[["visible"]]) result[["value"]] else invisible(result[["value"]]) } } } } #' magrittr forward-pipe operator #' #' Pipe an object forward into a function or call expression. #' #' @param lhs A value or the magrittr placeholder. #' @param rhs A function call using the magrittr semantics. #' @details #' \bold{Using \code{\%>\%} with unary function calls}\cr #' When functions require only one argument, \code{x \%>\% f} is equivalent #' to \code{f(x)} (not exactly equivalent; see technical note below.) #' \cr\cr #' \bold{Placing \code{lhs} as the first argument in \code{rhs} call}\cr #' The default behavior of \code{\%>\%} when multiple arguments are required #' in the \code{rhs} call, is to place \code{lhs} as the first argument, i.e. #' \code{x \%>\% f(y)} is equivalent to \code{f(x, y)}. #' \cr\cr #' \bold{Placing \code{lhs} elsewhere in \code{rhs} call}\cr #' Often you will want \code{lhs} to the \code{rhs} call at another position than the first. #' For this purpose you can use the dot (\code{.}) as placeholder. For example, #' \code{y \%>\% f(x, .)} is equivalent to \code{f(x, y)} and #' \code{z \%>\% f(x, y, arg = .)} is equivalent to \code{f(x, y, arg = z)}. #' \cr\cr #' \bold{Using the dot for secondary purposes}\cr #' Often, some attribute or property of \code{lhs} is desired in the \code{rhs} call in #' addition to the value of \code{lhs} itself, e.g. the number of rows or columns. #' It is perfectly valid to use the dot placeholder several times in the \code{rhs} #' call, but by design the behavior is slightly different when using it inside #' nested function calls. In particular, if the placeholder is only used #' in a nested function call, \code{lhs} will also be placed as the first argument! #' The reason for this is that in most use-cases this produces the most readable #' code. For example, \code{iris \%>\% subset(1:nrow(.) \%\% 2 == 0)} is #' equivalent to \code{iris \%>\% subset(., 1:nrow(.) \%\% 2 == 0)} but #' slightly more compact. It is possible to overrule this behavior by enclosing #' the \code{rhs} in braces. For example, \code{1:10 \%>\% {c(min(.), max(.))}} is #' equivalent to \code{c(min(1:10), max(1:10))}. #' \cr\cr #' \bold{Using \%>\% with call- or function-producing \code{rhs}}\cr #' It is possible to force evaluation of \code{rhs} before the piping of \code{lhs} takes #' place. This is useful when \code{rhs} produces the relevant call or function. #' To evaluate \code{rhs} first, enclose it in parentheses, i.e. #' \code{a \%>\% (function(x) x^2)}, and \code{1:10 \%>\% (call("sum"))}. #' Another example where this is relevant is for reference class methods #' which are accessed using the \code{$} operator, where one would do #' \code{x \%>\% (rc$f)}, and not \code{x \%>\% rc$f}. #' \cr\cr #' \bold{Using lambda expressions with \code{\%>\%}}\cr #' Each \code{rhs} is essentially a one-expression body of a unary function. #' Therefore defining lambdas in magrittr is very natural, and as #' the definitions of regular functions: if more than a single expression #' is needed one encloses the body in a pair of braces, \code{\{ rhs \}}. #' However, note that within braces there are no "first-argument rule": #' it will be exactly like writing a unary function where the argument name is #' "\code{.}" (the dot). #' \cr\cr #' \bold{Using the dot-place holder as \code{lhs}}\cr #' When the dot is used as \code{lhs}, the result will be a functional sequence, #' i.e. a function which applies the entire chain of right-hand sides in turn #' to its input. See the examples. #' #' @section Technical notes: #' The magrittr pipe operators use non-standard evaluation. They capture #' their inputs and examines them to figure out how to proceed. First a function #' is produced from all of the individual right-hand side expressions, and #' then the result is obtained by applying this function to the left-hand side. #' For most purposes, one can disregard the subtle aspects of magrittr's #' evaluation, but some functions may capture their calling environment, #' and thus using the operators will not be exactly equivalent to the #' "standard call" without pipe-operators. #' \cr\cr #' Another note is that special attention is advised when using non-magrittr #' operators in a pipe-chain (\code{+, -, $,} etc.), as operator precedence will impact how the #' chain is evaluated. In general it is advised to use the aliases provided #' by magrittr. #' #' @seealso \code{\link{\%<>\%}}, \code{\link{\%T>\%}}, \code{\link{\%$\%}} #' #' @examples #' # Basic use: #' iris %>% head #' #' # Use with lhs as first argument #' iris %>% head(10) #' #' # Using the dot place-holder #' "Ceci n'est pas une pipe" %>% gsub("une", "un", .) #' #' # When dot is nested, lhs is still placed first: #' sample(1:10) %>% paste0(LETTERS[.]) #' #' # This can be avoided: #' rnorm(100) %>% {c(min(.), mean(.), max(.))} %>% floor #' #' # Lambda expressions: #' iris %>% #' { #' size <- sample(1:10, size = 1) #' rbind(head(., size), tail(., size)) #' } #' #' # renaming in lambdas: #' iris %>% #' { #' my_data <- . #' size <- sample(1:10, size = 1) #' rbind(head(my_data, size), tail(my_data, size)) #' } #' #' # Building unary functions with %>% #' trig_fest <- . %>% tan %>% cos %>% sin #' #' 1:10 %>% trig_fest #' trig_fest(1:10) #' #' @rdname pipe #' @export `%>%` <- pipe() #' magrittr compound assignment pipe-operator #' #' Pipe an object forward into a function or call expression and update the #' \code{lhs} object with the resulting value. #' #' @param lhs An object which serves both as the initial value and as target. #' @param rhs a function call using the magrittr semantics. #' #' @details The compound assignment pipe-operator, \code{\%<>\%}, is used to #' update a value by first piping it into one or more \code{rhs} expressions, and #' then assigning the result. For example, \code{some_object \%<>\% #' foo \%>\% bar} is equivalent to \code{some_object <- some_object \%>\% foo #' \%>\% bar}. It must be the first pipe-operator in a chain, but otherwise it #' works like \code{\link{\%>\%}}. #' #' @seealso \code{\link{\%>\%}}, \code{\link{\%T>\%}}, \code{\link{\%$\%}} #' #' @examples #' iris$Sepal.Length %<>% sqrt #' #' x <- rnorm(100) #' #' x %<>% abs %>% sort #' #' is_weekend <- function(day) #' { #' # day could be e.g. character a valid representation #' day %<>% as.Date #' #' result <- day %>% format("%u") %>% as.numeric %>% is_greater_than(5) #' #' if (result) #' message(day %>% paste("is a weekend!")) #' else #' message(day %>% paste("is not a weekend!")) #' #' invisible(result) #' } #' #' @rdname compound #' @export `%<>%` <- pipe() #' magrittr tee operator #' #' 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. #' #' @param lhs A value or the magrittr placeholder. #' @param rhs A function call using the magrittr semantics. #' #' @details The tee operator works like \code{\link{\%>\%}}, except the #' return value is \code{lhs} itself, and not the result of \code{rhs} function/expression. #' #' @seealso \code{\link{\%>\%}}, \code{\link{\%<>\%}}, \code{\link{\%$\%}} #' #' @examples #' rnorm(200) %>% #' matrix(ncol = 2) %T>% #' plot %>% # plot usually does not return anything. #' colSums #' #' @rdname tee #' @export `%T>%` <- pipe() #' magrittr exposition pipe-operator #' #' Expose the names in \code{lhs} to the \code{rhs} expression. This is useful when functions #' do not have a built-in data argument. #' #' @param lhs A list, environment, or a data.frame. #' @param rhs An expression where the names in lhs is available. #' #' @details Some functions, e.g. \code{lm} and \code{aggregate}, have a #' data argument, which allows the direct use of names inside the data as part #' of the call. This operator exposes the contents of the left-hand side object #' to the expression on the right to give a similar benefit, see the examples. #' @seealso \code{\link{\%>\%}}, \code{\link{\%<>\%}}, \code{\link{\%$\%}} #' #' @examples #' iris %>% #' subset(Sepal.Length > mean(Sepal.Length)) %$% #' cor(Sepal.Length, Sepal.Width) #' #' data.frame(z = rnorm(100)) %$% #' ts.plot(z) #' #' @rdname exposition #' @export `%$%` <- pipe() magrittr/R/magrittr.R 0000644 0001751 0000144 00000003363 12434047153 014306 0 ustar hornik users #' magrittr - Ceci n'est pas un pipe #' #' The magrittr package offers a set of operators which promote semantics #' that will improve your code by #' \itemize{ #' \item structuring sequences of data operations left-to-right #' (as opposed to from the inside and out), #' \item avoiding nested function calls, #' \item minimizing the need for local variables and function definitions, and #' \item 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 \code{f(x)} with #' \code{x \%>\% f}, where \code{\%>\%} is the (main) pipe-operator. #' \cr\cr #' Consider the example below. 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 whereever it may be needed. #' \cr\cr #' For a more detailed introduction see the vignette #' (\code{vignette("magrittr")}) or the documentation pages for the #' available operators:\cr #' \tabular{ll}{ #' \code{\link{\%>\%}} \tab forward-pipe operator.\cr #' \code{\link{\%T>\%}} \tab tee operator.\cr #' \code{\link{\%<>\%}} \tab compound assignment pipe-operator.\cr #' \code{\link{\%$\%}} \tab exposition pipe-operator.\cr #' } #' #' @examples #' \dontrun{ #' #' the_data <- #' read.csv('/path/to/data/file.csv') %>% #' subset(variable_a > x) %>% #' transform(variable_c = variable_a/veraiable_b) %>% #' head(100) #' } #' @docType package #' @name magrittr NULL magrittr/R/getters.R 0000644 0001751 0000144 00000001323 12434047153 014124 0 ustar hornik users #' Extract function(s) from a functional sequence. #' #' Functional sequences can be subset using single or double brackets. #' A single-bracket subset results in a new functional sequence, and #' a double-bracket subset results in a single function. #' #' @rdname fseq #' @param x A functional sequence #' @param ... index/indices. For double brackets, the index must be of length 1. #' @return A function or functional sequence. #' @export `[[.fseq` <- function(x, ...) { functions(x)[[...]] } #' @rdname fseq #' @export `[.fseq` <- function(x, ...) { y <- x environment(y) <- new.env(parent = parent.env(environment(x))) environment(y)[["_function_list"]] <- functions(x)[...] y } magrittr/R/wrap_function.R 0000644 0001751 0000144 00000002033 12434047153 015324 0 ustar hornik users # Wrap an expression in a function # # This function takes the "body" part of a function and wraps it in # a function. The return value depends on whether the function is created # for its side effect with the tee operator. If the operator is \code{\%$\%} # then the expression will be evaluated in a \code{with(., )} statement. # # @param body an expression which will serve as function body in single-argument # function with an argument names \code{.} (a dot) # @param pipe a quoted magrittr pipe, which determines how the function is made. # @param env The environment in which to contruct the function. # @details Currently, the only distinction made is whether the pipe is a tee # or not. # # @return a function of a single argument, named \code{.}. wrap_function <- function(body, pipe, env) { if (is_tee(pipe)) { body <- call("{", body, quote(.)) } else if (is_dollar(pipe)) { body <- substitute(with(., b), list(b = body)) } eval(call("function", as.pairlist(alist(.=)), body), env, env) } magrittr/R/functions.R 0000644 0001751 0000144 00000001660 12434047153 014463 0 ustar hornik users #' Extract the function list from a functional sequence. #' #' This can be used to extract the list of functions inside a functional #' sequence created with a chain like \code{. \%>\% foo \%>\% bar}. #' #' @param fseq A functional sequence ala magrittr. #' @return a list of functions #' #' @export functions <- function(fseq) { if (!"fseq" %in% class(fseq)) stop("Object is not a functional sequence.", call. = FALSE) environment(fseq)[["_function_list"]] } #' Print method for functional sequence. #' #' @param x A functional sequence object #' @param ... not used. #' @return x #' #' @export print.fseq <- function(x, ...) { flist <- functions(x) cat("Functional sequence with the following components:\n\n") lapply(1:length(flist), function(i) cat(" ", i, ". ", deparse(body(flist[[i]])), "\n", sep = "")) cat("\nUse 'functions' to extract the individual functions.", "\n") x } magrittr/R/function_type.R 0000644 0001751 0000144 00000001003 12434047153 015330 0 ustar hornik users # Determine whether an expression counts as a function in a magrittr chain. # # @param a non-evaluated expression. # @return logical - TRUE if expr represents a function, FALSE otherwise. is_function <- function(expr) { is.symbol(expr) || is.function(expr) } # Prepare a magrittr rhs of funtion type # # @param a an expression which passes \code{is_function} # @return an expression prepared for functional sequence construction. prepare_function <- function(f) { as.call(list(f, quote(.))) } magrittr/R/is_something.R 0000644 0001751 0000144 00000003420 12434047153 015137 0 ustar hornik users # Check whether a symbol is a valid magrittr pipe. # # @param pipe A quoted symbol # @return logical - TRUE if a valid magrittr pipe, FALSE otherwise. is_pipe <- function(pipe) { identical(pipe, quote(`%>%`)) || identical(pipe, quote(`%T>%`)) || identical(pipe, quote(`%<>%`)) || identical(pipe, quote(`%$%`)) } # Determine whether an non-evaluated call is parenthesized # # @param a non-evaluated expression # @retun logical - TRUE if expression is parenthesized, FALSE otherwise. is_parenthesized <- function(expr) { is.call(expr) && identical(expr[[1]], quote(`(`)) } # Check whether a pipe is a tee. # # @param pipe A (quoted) pipe # @return logical - TRUE if pipe is a tee, FALSE otherwise. is_tee <- function(pipe) { identical(pipe, quote(`%T>%`)) } # Check whether a pipe is the dollar pipe. # # @param pipe A (quoted) pipe # @return logical - TRUE if pipe is the dollar pipe, FALSE otherwise. is_dollar <- function(pipe) { identical(pipe, quote(`%$%`)) } # Check whether a pipe is the compound assignment pipe operator # # @param pipe A (quoted) pipe # @return logical - TRUE if pipe is the compound assignment pipe, # otherwise FALSE. is_compound_pipe <- function(pipe) { identical(pipe, quote(`%<>%`)) } # Check whether expression is enclosed in curly braces. # # @param expr An expression to be tested. # @return logical - TRUE if expr is enclosed in `{`, FALSE otherwise. is_funexpr <- function(expr) { is.call(expr) && identical(expr[[1]], quote(`{`)) } # Check whether a symbol is the magrittr placeholder. # # @param symbol A (quoted) symbol # @return logical - TRUE if symbol is the magrittr placeholder, FALSE otherwise. is_placeholder <- function(symbol) { identical(symbol, quote(.)) } magrittr/vignettes/ 0000755 0001751 0000144 00000000000 12434047155 014136 5 ustar hornik users magrittr/vignettes/magrittr.jpg 0000644 0001751 0000144 00000270210 12434047153 016471 0 ustar hornik users JFIF U } !1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w !1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ? k<( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ?l+Ki, ^V k5{7]%ھ_ݗg.CwӁXx_gRs$gRI;mhE+7+;Lj~zu 7op|K f CɤwL ]2=,\(/ĝ7UNis.LJxKT1isjwP[_ͫ}xS>[JӇ5Ri8N1-*N][X Elrw[$y'8# eɦsd