magrittr/0000755000175100001440000000000012434151335012122 5ustar hornikusersmagrittr/inst/0000755000175100001440000000000012434047155013103 5ustar hornikusersmagrittr/inst/doc/0000755000175100001440000000000012434047155013650 5ustar hornikusersmagrittr/inst/doc/magrittr.R0000644000175100001440000000417712434047155015635 0ustar hornikusers## ----, 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.Rmd0000644000175100001440000001770612434047155016160 0ustar hornikusers ```{r, echo = FALSE, message = FALSE} library(magrittr) options(scipen = 3) knitr::opts_chunk$set( comment = NA, error = FALSE, tidy = FALSE) ``` ![magrittr-pipe](magrittr.jpg) *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.html0000644000175100001440000044360312434047155016401 0ustar hornikusers Abstract

magrittr-pipe

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.

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):

  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.

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

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):

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.

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:

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.

Development

The magrittr package is also available in a development version at the GitHub development page: github.com/smbache/magrittr.

magrittr/tests/0000755000175100001440000000000012434047153013266 5ustar hornikusersmagrittr/tests/testthat/0000755000175100001440000000000012434047153015126 5ustar hornikusersmagrittr/tests/testthat/test-fseq.r0000644000175100001440000000031412434047153017222 0ustar hornikuserscontext("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.r0000644000175100001440000000254712434047153022134 0ustar hornikuserscontext("%>%: 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.r0000644000175100001440000000342612434047153022331 0ustar hornikuserscontext("%>%: 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.r0000644000175100001440000000145012434047153021367 0ustar hornikuserscontext("%>%: 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.R0000644000175100001440000000373712434047153017661 0ustar hornikuserscontext("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.R0000644000175100001440000000072412434047153020055 0ustar hornikuserscontext("%<>%: 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.r0000644000175100001440000000051312434047153017042 0ustar hornikuserscontext("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.R0000644000175100001440000000005112434047153015132 0ustar hornikuserslibrary(testthat) test_check("magrittr")magrittr/NAMESPACE0000644000175100001440000000142112434047153013341 0ustar hornikusers# 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/0000755000175100001440000000000012434047153012325 5ustar hornikusersmagrittr/R/split_chain.R0000644000175100001440000000266512434047153014756 0ustar hornikusers# 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.R0000644000175100001440000000736012434047153014077 0ustar hornikusers#' 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.R0000644000175100001440000000107212434047153014640 0ustar hornikusers# 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.R0000644000175100001440000000221212434047153014550 0ustar hornikusers#' 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.R0000644000175100001440000000122312434047153014063 0ustar hornikusers#' 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.R0000644000175100001440000002435312434047153013414 0ustar hornikusers# 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.R0000644000175100001440000000336312434047153014306 0ustar hornikusers#' 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 NULLmagrittr/R/getters.R0000644000175100001440000000132312434047153014124 0ustar hornikusers#' 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.R0000644000175100001440000000203312434047153015324 0ustar hornikusers# 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.R0000644000175100001440000000166012434047153014463 0ustar hornikusers#' 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.R0000644000175100001440000000100312434047153015330 0ustar hornikusers# 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.R0000644000175100001440000000342012434047153015137 0ustar hornikusers# 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/0000755000175100001440000000000012434047155014136 5ustar hornikusersmagrittr/vignettes/magrittr.jpg0000644000175100001440000027021012434047153016471 0ustar hornikusersJFIFU  }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?k<( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (?l+Ki,^Vk5{7]%ھ_ݗg.CwӁXx_gRs$gRI;mhE+7+;Lj~zu 7op|Kf CɤwL ]2=,\(/ĝ7UNis.LJxKT1isjwP[_ͫ}xS>[JӇ5Ri8N1-*N][X Elrw[$y'8# eɦsd к~u|-ֵ3ZuzK%CZ k*KvxO4ɱ9w0Vye ݔ\[wbvR|3DIim/mּP ( ( (>Hm?/㧉{?xA[;CլhW7 t wjα{h:wv_ N_Wa}II$T3i.ױq/S;)&3)tisxĿtW:Χ$wa-RŧͩAm6XnRILTm+NMJQ8I;eunbKX%[k6]l )F׉'&}͐ď^:3o$Z"xB)#NKwro4R[mURj5m}VַKYJyIFA]-VXOPd7B}֣yZb4i/3] SM-D)h7N-[k.yW<&h7eZ1/jvQqn23Jj]%5OZB ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (c{Yi֗7s [;H^yP*+fRi%;秕ο7?n/ڧōKRԧMy_}"[mmx]}I,wfHOpPa)I**u撼y]Q#خ<ӕIgx,zkne-VީFOo7U|9C1ωԣxT🄼c;YYx^h,|{em&m ƾ4GP(Vxgw PIFKGdSqjw?iO~!p]+Sӵ_}u-<gޝ>i/yg:mvƙgro~ޕ\>cU"L>"N2](Ilx65fp5*SIJ.֎|JIk:XGGdp8/N _]ozusCgtB}5n7HdSo$I0Kժsvs$zXN\{KGn}k\ ( ]#=I> Me|gMCÞFak0x/Fݥ[hZյjэGF4mSOҭZpX{[ ~&~Ԃr;!Vi;ifYWrRvO~[n}S 5~P|NZ|ׄ>5XwOԧћIu]Wm?P?\MkM>T}|-S=,F4gzi)U}\Y Q/ߗNm-~ߴ_hYw ]xYScwQXO=-m_L7>ƚ̊>Gؼ%a WGW;+ҳmJR8짉{_ϧmto݌~+.+AWR2#ר篆t  (+_Yv7qis}w;൳.g 1¢< Vm/yZ{ϣzy[? /cx~ XԵ-Jj;᫉K_ 7/%m,Vڇ>%Ϯjqkkk4 $^i+ΫWU?݊s˭9TwWǭֶ^mgw[xß?n~?iF~ '3/Go߈>oy.\ָK}s ?нjW/ R?\v]q9A}eC~3Wi{M9wn[^r߷,95}}m6i r#ܿ Iͳ_m?gߟdk[R彭oeJ=81|M}oV/ulû-~]<ݾ_gϵ}7};x+ohz 'z(O*GH|-"x{ jMk ԋ牡K[k_LT孆ikXxsYrR*h&.XޗGKnSv>}~/(?a)YY՗|woׂ9-]=dҮn?5e6z,qL~iMVvMJm>YJWvҕ4yulo^ P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P{=RL-⼰m.l/'A$Vwp#覆GIdfJ8OOuVO+yCcÿeտu| 2G2i)k7n[x;ɧxL^{6?-a)֋^EBMuR~%^MX:Un/MV];gѷ"Y//>#<7.>=h>_<]V7cs A-q71}\&Yw3.N_:rw8JM]Ss9A+twge 5-FwOO#jx|=7')>ה6yIi+Nnuev)I-X}},c?<5S{,ox>3,Oj7顄{tlA0żn2'T;;9{8ZuOk;#ԧJqH}^O5 BI;M7Lm.u GQ.a-!{ۉ#Inf8`7WTVai6mWrvi(ܤwIsOZ[vuocj OZ5o=u=_VӮn`I$Y5dV#JzUբJ*SsKKiOiE?J_izuH€9x/q}I.XIiַ)vEu"{-1 %[ ԣ6oP=/ӹN*/G˶UxrP{=RL-⼰m.l/'A$Vwp#覆GIdfJ8OOuVO+yCcÿeտu| 2G2i)k7n[x;ɧxL^{6?-a)֋^EBMuR~%^MX:Un/MV];gѷ"Y//>#<7.>=h>_<]V7cs A-q71}\&Yw3.N_:rw8JM]Ss9A+twge 5-FwOO#jx|=7')>ה6yIi+Nnuev)I-X}},c?<5S{,ox>3,Oj7顄{tlA0żn2'T;;9{8ZuOk;#ԧJqH}^O5 BI;M7Lm.u GQ.a-!{ۉ#Inf8`7WTVai6mWrvi(ܤwIsOZ[vuocj OZ5o=u=_VӮn`I$Y5dV#JzUբJ*SsKKiOiE?J_izuH€ ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (>DaißmQG|;sχj䵼`+e4 bVδZeΧ]^h=ՇN\;K%RNN<]\ZnI8JUkFU'r?nK)I,4xi !EIoi^ --8#f]?Qm2 tq.Kagy]:J0%*7N)Y+K R:A-~N.ѳfݿ/> ?cj&KJ~<-mSBns#Qh,Bk_.%/eTZX\-yQv%웽Փ3Mw8v[߽}+~I%}ߍ~o/ڧU+¿i. z,|Cz9MxQ. gKXE |Gi<6kw\i1 B8jz)EQFn|/f+$S9J++IRVH w_ >2<æ̻ lmvKOG1^]ZºZ\EkJF:sZsSSWHyn3OTj.Y$ן^On_7Ǿ}S߰׊$\|zG-}=R>7_|ceuK?X&X_]js1R*MݵkpkÚ.R8 \,oGz[񗂼eڿ K^W>&.;[tۇt) "3}L*B#RR(W(K>k4Z2dת]=oO ׼'h)𮷫c5x@ԯtmwAcF魵 /To`P-XÒHg 'FIJ-5iBQwM5MYE&f4k]VZ9|hJ7lo^{p;IiK;kC VK_".!R5xc'fnj6TzS&ޮ.m(ꥊҤyk+G[޼]E? {_GHu\ozcr w5X4CQ[I,">|BLK7w:ߊ<5'RҼZ[jqˤGo-.̺~e7?e\T!Tϖu!ta*JUo;ʜRWvWtR[ɦ]gͻ~?-_|sg7q<~MŞ+x[ڧ"=6)/x}mF|s棬xUZ_oluih<ӿ<;e%777Klm&+obpX rpQ'RФZM7e*nn9NmFNUhi{rK_A'W=q ?> Eu7~'խ|][Ηysֱx<y{ Qtx4m&^>c3<&p'U'R SO^-FWjI'نR2sW"Vw}WKyaa@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P|x~  {|:}giyj7-/ci.gtVI-KԵ)-\،MXӕZ&[_ %(sI?=?IAw ׉ټS+[~xT}$Dfޓ;/妞V }GPEL? b*kS B]iH8m7\ܳj7nMn~v?QkcJmWKt_\}MΨu?xȖm'J-چԝ],Lլ+ 2KVN6"VF<8/ğ gO >7>+'-4|Hľ-)ԡŏ<Юd6iجwWZw4jU` W7ȷt'>zZFu]e''y=eKZ6yuXixS m߲^/>xfYhOx7lmJk74wKDաuCkk}5׭iκo/bq% &n'؎YJPەSi\%Y F>Կk-]~}g8J/iMW/?Zi< x:Z#]ivicioscqwmZGo^_ |sᇃ&LJx?~ ơEn>.k-VknyYaoթZթVirެRvW劔M}5knĔU]I~יԀP@P@_QO߰?_ωn_xc~ҵM[xO'ӵ;k+F$wZ>)8˱ ^Ns:SWJa]zӋv ]USqnKٯG-n3hm,xH |@Rc׊$#M7nmcյl;?^ZNummSE{]]}ῄl|4 bӥY UHe}\W#pRejnmi_eExtzω>|M?gx>ww=fQԬV+bW=Geew=SK&+Q,)PJpœٹr$;]7RV՚n:>^ToC࡟꿷<~h|/+}bo|Svt_ gA1躗|Sk+Xխ΁/ YCoRiWk/RnJWT)M.XEBqi{yD(?Ivz_mhc|x~  {|:}giyj7-/ci.gtVI-KԵ)-\ Ս=9U+h*zRj1չIm%(sI?=?IAw ׉ټS+[~xT}$Dfޓ;/妞V }GPEL? b*kS B]iH8m7\ܳj7nMn~v?QkcJmWKt_\}MΨu?xȖm'J-چԝ],Lլ+ 2KVN6"VF<8/ğ gO >7>+'-4|Hľ-)ԡŏ<Юd6iجwWZw4jU` W7ȷt'>zZFu]e''y=eKZ6yuXixS m߲^/>xfYhOx7lmJk74wKDաuCkk}5׭iκo/bq% &n'؎YJPەSi\%Y F>Կk-]~}g8J/iMW/?Zi< x:Z#]ivicioscqwmZGo^_ |sᇃ&LJx?~ ơEn>.k-VknyYaoթZթVirެRvW劔M}5knĔU]I~יԀP@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@PC Կ@M#Ǿ~w_MҵCM5+}PӵMWN+m5R8Ӯ W7VQ:M\н=╴W5u:ef.6Z}7Ti].OQW7TRWI~*E#5?IDڍZ[j_hMޗbx:&婈MҦ6]WK^h?䗚-<oO#G<-C)E, C\skj\5e5S_|-"ۇ!ofX(s(asgx%VQ{~OIC Fa?9{=^ܮV]~>SZ&~^9o3]՞~ 2j Z\xȐޜ,Ul/ծӣEݶQKNu(0E^3Z*_Tmrj*C]n. {˪[w\zhfh'txwSִiօi)yj>kX] ͝O 4sC*HVu(.Q$e{٩/jmޞѫ O/o>04xKö Gu};дUs:ޫsgiv#IF95rۖ);QQR]t6j)nދ|7}SOl4xmu}+&sxsG&mX^ VR(nSnO&6kRiY'd*7&k^-m4xet_`oKS6"_ O? D6K5j ֡j~8M_ z~owڏ c4?Cnֱ׋oxPx:Yom6c}w)I"l?gG OOrJt+1SvM-ZHRM^qqes%7g56k^15Y|Gˣ&w5Ǎ ]i_FAZ-:?]jɛeRc dU5eUKFڷ,߽t:&~%uhZ}G'u;-kAahZƙrvꖱ_iڕ ʹG42`OR^MQq/I&m ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (?Fo3XH|4Yp[!𦩮, `W8cXT)*؊mZwt>YKMtz+_);FN+Ꭳݿ9]߇5}]xE^t`Kba+<(fSU VєN[+y1Doy&dO3<> |q;,W𯀼h&e Q_ckiC2}炼9gŧVZkUn@ծ4xvv{a"a>G7 mե7Fm2vN3zy(MYG5uoK~/[֯W ]{C_m;T{VmKd$s^n-MG$CJ4s*ҊҤiֶה拟{t߳ FM-c?d+6 Ie(Y^86I$`gwv`3IPg<KOڇrڭυ5tdžo[{g5^A_ #zݍjzk0xT_ IyvpZYJ,ԣ GW>Xo¾}{t~׿Opx?>%59? 0 !Tk/%ΣYkW5KqhxS$`&mcqJ~Kin^jOWqGGn=[ῂ[ ^p$%S’9oziW6~ u=YV^.اf; T(Ria-/N},<)KzGUYշ?_k6 (<f?/?ńO7O #JH/axfԶBH_ΑkZl+*M-ޑ}ƕhױèڭޛwk$K]zp%BjS|ӽq,ZѴzђRiYywv70YXA5ZZF\\L ’K4ҼqlʪMJMmY%輿!_a^&_MN{? ;9^]?V5_].{Co\Ddt+ Z+<XBjYOG(1Py6cMNj8)kK^V u_Mwz$Y׌$Ӆ] A{oz4m03XiZ>W.5&*RNIS4Si-[+s=IEJyw%|=NcV_.~ok5 (o`9g>#ji^]nu S !k";45$׺9y+Φ=bz?弴rɯTds`j%G5Gkhu׋|gw,eY58 X>u nS%>&~ܾ9ğ3B՞~3iw_Ex#ɐ-ޢ//J:/!խ"dEoKNt3IZ0ZW_VM+rn.ܗcAnN {ϫ[\zjft wLt.giZ>kZ@ [A pFU~u)JNR&ܥ'+ݹ?nmѫW ]g~2)s~/k[~xnP|E xN5{ hZxm]n*-*T'Nt6:8LUhהaOUJ0{MIi}7*u&Sm읛n'i_/ρ k;5Zim<:Cx\._2ϯxTt[Iۻ}|V O׭N5VըEsJ`';$7|%Zln~+_j9CkvMזj >ӴkJ1W#j<;,EETwktڔ"ۏؤKk#ݽ_},իH|o|5^π$%Lφkyn& 3C-lm-InyK,/9άRRrԜ'gIIj$KP  ( (mx|y≥վ:!֡$4<A$"׋D4Ώia)]cO }vCӍ8qsPZw9~k_w9>VniAs)/zT_{[s+m?ڣC/5Og~.ϪRuˋ5Χ|>e]cWUY<;wiwhT0\N IbhSeR*gZ{J)LS^o};Qi꿴< o!x"_=u ?~!dk_|0σ`R[\*]b#waootJqe9v~Ҏ6=ڼ9[Z6rV' ,eߛFmJo$ۗ>Aּ&hZxwBM.k跂|92E3i^!ugE6ڵZ(_6`iΝFx+F UJ։nX?zMےt(:Ayz+~˚OU-O д=.Z.2Eд}2,+GbӴ Hakh!UbH Υ)IR۔}'6m-5`P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@|I@6aڋS^5|:'/5q~2mo:KI|Q㟆Z]#Hz֩c;UH0? hb 8JJ#US7f2JS}oYus |F|U_'zt7|dIo,'~.QG d4V7EwtiS;/gό[{-dx‘j(ћ]a4Uլm*gye猨IS-.Jk5xsYu+" +]vw6LQEopAp i0ċQE8@#X0@UP@PGP@P@P@ : ~,gxCž+g w$}clW>[haV'^7c'Z;U˦W}"綏wO_s;W?kB-l/}>PjөRIB%{7vJϫ̓i( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (.n>/| ۿ+;o3Vloa-?|iÚ}I#_=m6so4s|N!BQmYӧ(kݜX5*TSy[vu|C/Ygx {]iw-gE𦕦jvj׶KY -7Wg^gթ(T'gZ)ؤ?@P@_ߎ~~_> Cwx㧀|!!<'4 t/xK&{P|1}%Oy 2e{s |;B#^+B*Ba8s)F \8])^7NR0ƕni]Ko~_<]S%"xY<_3޵o_0{oZu[z"}R; pRqU"{Yl4ۧ3qWnXP@b:\ 7ґE|[tύ}>txzQnmkkyf 4R"Js?gRN*BP^\ڧ+So[hOTԗtsa@8cIcRߟI ߶ л,R#)#bG$o FWg~?qM[#Cx 'q~YJQ}} ݽ͍]זhENtgR)HJkkT%umm)4MIwNW:P@|~'5[ e_u+[&hƗu5eӵ-> +![{7A0TJ2JQ0՜e+49ZkTգ('Z:M}⯅|/߃$x+V{Ҽ_/h~0&{>~<=}7ocmscxr5)yS:JpREtZ8]jzFzum ( (|:~ >o^ou/-xRW׵+M{Y!(5*4VqNڌayS+ݍI-c>5~7D| { 2mr -Ǻ행ougcs[p^Z}ڄiJl&*SѦ*uhri*SvNM Oɧ{f0 ( (VG@>+׿_3 [NP9_~0_oGk5;«l҇ivמjP@5տ ]>ZnO|3ԫ%}*n>9rLk ( (>!~߲?\+5>2wwǂOiiB..txM t[4Y"/uVRbjB)ҡV$բ\SWZEeJPd{gABѼQmoH/|Gk+=gC״MV+3Wѵ}:[?T+) -fi#('B\%%(ŧfM6[]Ɲ1P@P@P@P@P@P@P@P@P@P@0O6Ss.g&.qgzfښ捨ff:AtW6l~ ,]Woe&)>E\UԹ%#EuÞ.7gFZó> /O]5+BͷJN _.јAs_eȿ{G=?}}myGrMKYGku}w}_|B?nc߆Ziuo^4"k=;FO ZogjBh:f}ZayV% t+M7w))W8srl\K|},~g-侽?o>>e~*mcw^x ZaM觗|X>'RAPh9ь2I9ƤF/&nWk{'J7uggwiEk ?j(c мE.m~ᶇ 4 ߦ}&x<kWGaI~"^}'jbJ0A)eʡKߴ'̝H$QϑG\ܼoOM=6zb~ͿnVcEbH"O!5?hZ֢o~ W%Dl Ma|eGaÊeFJ[cRd(TiʗzŹ&XSI=t~Ӭծߏo]__O_ZKZ(l%7]E5#0Ӽ5_V:~n1ZWKK=wD0GNt$%-jMыJ'd)KDJ2IJ 7w-|1֣B6i7jbXqc}o $7`;ӦT9N&sCv3;%W_?sG>*}>i_M=7%梗 mTSU\rT+^˗is^tcWeֿm(I׼IM;RimKnKw>+xE&]3H,/pK/0-w+rZ)rхe=-ddכ%nzϙz_hHEk$4IFH_TldRiό }JTy~_L6i?(3:6ִ~lu/kV/DnA(3L-8§ԣQnFIy3N ԥ7̞K^mct۾+EmZ8}g?-t_Cm[=:cCKQir\+,Cyd~ 'I3e*M ֋zrZ95dޅojgk(I|_^%XgUy Ŵz5I'OuoVtFl&7 =Ǽ|T1NJ6RB.R~/gGiT?/5F+.I jk:g=:XЧmCV[>&6l^'W&[kuτ#ѴV)< 6h2ㅥ&-(8*2KƖ?w嵯'hH]#{lGyei_ mCw3yh־|B4;_$|iԒo`̗~fTIN5h;[T{6RneR~[l|3W~ΥC6?iO$ė_<zO [hö~+o/PGῇiPv'Kmﮇ`a<58ӟ*yiIKP|9Ԛm*i9,熜=2wvu8<Lgjߵleޗb? |\eúq?"mVnmg›ɾa1XY{\OjtyIǚIZt%Ks4e&ڜU54)YVwq????ijU^1  ?.B~0x@?l0a}?rclˈ_`$a.{? \kwܚXokMKZnܷWζwfΑJ'u[#])d\.lr%ws +G > ԙ xsŖo|ICvIxcZT{womïV:Υ:~?_82,.[Bj'8>Z\;{Ju1!'$yd'Щ[ޫ&E+6׻m~m? o_ZOh jUѮCEφzQ/4KVX5m|Ƶ'6Z0AѫJt?qJ/էRu})^Is5Q*xK+Ҕҽ4+d?|p~0m%W?GDx>*xa{kMsVtWdO66iO_3>+VJUF:3R%4/Ϳu-r"Mfm_{={kSzSO|/~? kxRO o>רh>ݦmؿ|S_xfW-xbb=jOg'/{PL BVl]Q,'1Bq}E?.ਟHOv߀?,jM +E۾ 3_>~/i5eYJ{8Fw嵽7~UR|Wukemݯ& ȯA*O#Ӓ=(1i();;ijM w"wejo;XVa VdnXe.}R8iQOVT~?eS-~^TµU4嵹?)oC C 3 go _x\_;}?"/?ۡ02OS-cio{+[k[CZ((S|ד[o>ܿiǿlC?n|<׏?z>+^2_n~ѷؠˋo+ʟ;(riwV.G(~ӗFy9_uuF/(Z[/?>IۇB#-wA{W?sNg?d٧/ ?Wv]@ls>jMa{HÚ~i_/KWq5^QUeu)[r曔m#qϥ++p~+~f -n#S#CH5O/ZuNѴG|+Xd{)s{*RN\O˕I;4MH꿭{Y͛%U;Pf,g'q}E? ?Kxύ>9xC)S~g OHu_i^_?`x`}uo?Fydif۹{_eNk\fTg5ʒKo?_Gk[/?+~,'1B^}E?N??GwĿᦼE3+_-[ֿǿk?dݤ`j' Cs sJTi}R4=GSU},_ʝR:ƞ7E ŷ̭k[( c9~1>Ohֺ.56'ZHuAlT൵]Hyf"uktyq>IZ+K;ε/mg ;tZǿsflOMGOk7Oxs[?7{vmԼIxN&.*aks4\L'$g>{ʢҗM+{5%_,d߃<|KMNZ[+h?a9mgSxtB-/sS BO+hVЄ֖8/zn0JҔRMfiмe.fW_Q vorxk? X~,񍮱wn}BF?G'!|Kd>(ЗĩxPh.MJ_>$R&|Ư:U|NUjTJFKTTӔ"Et4$ݡ8La[4Jrz;[M,Wk5:0 ( ( ( ( ( ( ( ( ( ( G]őH@i~pFpxʑ'cP|4ek+^ς<K<;SZn#mG]׵Kc\'_jZtW*֭'R6{nTB (%ʕgtb$UÿNjxAU~]|GA*Bt KG``e}GL./YCZkw?nO^ ZSNOFהcIOwIᢝjk.m7'{H!bo9ek;ch2QUW _#6s,w.j).f?O(͂ ( } ^ZzVeHZOo`HEN6轁3_pSk/K?#|-?W/< 8ǍVτO g߄ھxm6y%Pm{r|;Sžգִ˫9Mr2ʲzٔXBtЧͤ]KNZݦ+G [֯ JF_+>l|G᷂>|?w߆'_:1i$z~İħh qw;/2^j:֡{43'ԫRI֫'RudR[IӪѥRIZ+Dր A?g/ý.ovZmqZZŅׁ!c_/P#e?*,wk߱ee#pQM*SoOln,e$jY)lw1~VO+/xoG5zg%x@P@_g]+Gox?_ ~ µ>$V4|Wk|3g\_Smkesx#ucz4jdcoka`|ʹ{yؗjÛе}o˦ɴ~*zG3,m~&:xJ|_|%oT}s>iC]x{7LJ&5 _?gK'=4*Zr,4sj.P7\.罞TeN ( /_w_Y88q& ȯA*O#Ӓ;#= {o0|?{5#7`( Qٽ6~ָ3_c*(my@P_[ '+%7?J"WOp~$0 ( # (M]?_-???'!RHm;+.Q_>.T-3ƺ.x+HqoioZP'?qf8<ʷ$*cӌ!:qoԖ4T.UgQn.Pө[)M;Ngmy-y_OG[|}3~҂^oM\ha_/.uMAiaife+[ZU{_zSv 4K]zqiX+G}v{b0 ( V ϰ[/ ,_/ ϰ[/ i[~P@P@P@P@P@P@P@P@?O7m} o ʱŎXg/inB/GocnȇR ?켯e8oKG_vΗ&GK?~$_ r?o@aзLҴ6c8χQ9J-J2yy\&q8(ٽovRh@bwNyدZݥ(֮6[iڗpNL|!Fy._i%gf}&vMZ4ӳnEho]=:_/7Q??|A^wޯ{9+_?i+: D?oX3ٟS?LÈq8'O~L (?:H'e-}g ?ǎ!_C_g/" ?Ы?8WNH~ (|g9PVӔlgWL/GifQZe[4Gݵ皅P@ o&O lۓ *_g?yOܓ?ø( (*_75w2T?g/n:7ĿG^=?.?ߚӨ( ( ( ( ( ( ( ( ( ( (i~xýZVl]/ Wci :]մC6O=ok* E7Fl|ve J6{GFk.ѭe#]g%Wko [N@ _3?>6_AiWo?>\xGU]2}JM_xJl6⁥\ VҴ53b;VfQ7*wKtʥV,)VJ߮n~xZ'ğ߉aO|{//^h(ѮMR g}:@kYҩN\R2(MIzݨϧD2iM?5#l?[kR /Pu)h_W~*t 3¿|aףk˛ҭ<]G[k%cx[mo.Y)aQ\?Q\5y_湹j%zh# m}[n> f5!ks[j:yVZp.]TWĺ|_ŎP˲슚F+jmV~ܟ/GR"\,.&;6K/?&?nI|UD_ G [x+ƚž}'ƞӭ%׃4k0F#4S[ZGwzۚ¾k煣Rb=N<96(Eۙ.ByFn6/Ꮜ,Ta/ |Fntq>C=O5旤x{7éuɴZy 硃zUsWS[(5R$ UN7MT-ŷm;|Gg%~ŸWԵWx'U5[x`x⇃E𵾝-WH}' ӧ~<@ޭڍL)ӟ,)_WMKޕGI(zx2PJyo~j+'QF//0|ޯ{9у J񎃅G?>x?X;4Kĺ]KmV`oZ[]7SZie楪_oww6(ԯVhέI(ӂݺeo&dz( vKw*3{q@O 0c?+eo?Yٗ//nIL:Bx;ĺ3 ?ƗN%~7~g`.G~PX9%7RT}NT{9gV仳KW_J:a??_5 W~? ?fu|@>%-kgZѼQCIⴵ&~Ogyw)a'+QSt(Iӟ4S%(eujFjw[=J#a@S%j9~Z#fxb?m.l/t=C>Fa\ؼW7ZZ6WVW6q[_Y7v)qt JMԡOGJQnti>h*IJK7E)U1g9WQ>_7߶//|zl&+] z?‘|pYCB(ƛfաVZnTv}|MJu"gF[+}m??L|C/~ xw]ӿKЗatO :fg6W?fY\ZͰIo<2H%l6zX4:%Fӳnn:#$粊dޱ]O*3GŒ'4>jo_߀&:F$&\ixvZ^hmyg{n5 &/lnx3{U'FNJIŦR]4e+5$k Ƣ]K_Gf{dPP/w??mس?OEm?ĝK aP~$: [)Sk ;fhm!h :iI:UU,ܔnP|j:)jYׇ(u|߅I,?eޖ.I|u /z|QI0H|ošԗ6kB}&Ax O5{I$P:s7 k+ae}P cq.l4i:d~G='~Os6KضYsc; WT]^|)GoZ~ ^]xėVxkfAЕlqi{&9j2J_tkcTa[jݴO}]Xm;xoy\tcSpAk<6imm0@c_[v&ҿu}$Zj`8C  uV L xP~qn|5NzilZCռ/wMROP$U*T^V/iF3JR|&M]qJJq^;}v%Xr"5ؿ5k-GR]&,OwOisx%<}Zok*6iz2]_}rOU<"-+aʤR6Srݬף GKHu? ~eoƭ:_ֿ:xK_ @𦍨oW%`AkEP{ Og µFQ~ֲ[Μ$SqZs\qdeK)M0ؼN:3շ] j;=(FqMyu?|U>C=g[pɪ~6լfL|qiV6JT=GGY_TJ%(IoᄣӓEei GcGGÿx_^ !B+-.fGt;K+Mkˋb$wYevjTVSVsRJue6kMk$})$J;%? o5 o/^1 ֕Oj3ƣ|Qt}?3=3OcK;RB+(F!0RWt\[=팰ܜnmiֿ T_?~:4+ [K-ͭgm$K"d{)yViixGr*toR쥤Z~F5'ߧ}\f@|<{S>%+TR/u:=EciWr_Iqi# ;%]:(TRE:r%?~ Z{Qijzk߲_jאh~;sGQ-'haR|mVu].hk|IKZ^O2. aj) + x87uԭnJdrҌX+IF)1KW_7wv%K^m¸bS̙.x#dQ8j.YpzpB1?So2&źo v܍~& |ʸ}nҤC$Z _tHzgxIR]<_⟆l|cz%ׇWE47..m5 %H5=2R4Kk{P fVYJqITDҚi~eÉ_k#ς8Og1?ia%UѬ>g> ? _?>O_É_k#ς8Oga&&_%WF`?5>ɥɟr7x3U8|4x[]ץ6ioikaG>31䋒X'eF1JMٸ_y3hӌ{GU€?>h%_ R|J0rt|G4;X=+x&]^ Yijz|y}PHu9lo%>m){ >%”[qB+Z4S\vT)|妷kYr*u-}޷[? Eg8J?֜| G4R>?M_ps x_C5 ?;I{ƶo.'ԩ:*άo~:ɥ7͢Q&(Y}[@€ ~|w>/<'+zeu Ft8h5IkOI6ir:5َK)ҩW':u"8M4qw5+WhqRVMv vĒkK|nnՖmB;>y~XIvxkdQccdѽ\OӅV:owxZmsC2~7߇m^&^%wLOCi/.~ᇌVO--^/aUx3k KTJtER5WnPXZjZOR^'?I%VQ~Ͽ>|7ltOE/8o6m:/>lv%F 2(,4:xӉU9)(9(RyW-J.4 ɾi7|1K+]]PV /`ߵ?ZXhw-)x&J ٱvDž4NSl5Ჰ߷ cTr7NEysQͣm9QQQվ?ĿJ5]qA G0Kq/d?Qg L?KY|?h|'8}S43/g ~e O/]M۽Wލwww|J|9,'P_:b)Μm¢䒍49+QiFQХjVk_oC,( ( ( ( ( ( ( ( ( ( ( ( ( ( ( k˹m$i$FweE&'um$ylI/@;߷M3O'71,Xx u |F3'Ju>m;Qg9u?Wo xKjrLejZ,)Կ5*nQqQCYۚ\EY4|<5G<_W{g | hz52 ǯPu跡fw~O.%{JM Ze+^ʚ,F1Ue3Ġ ( ( ( ( ( ( ( ( ( ( ( ( ([ql#uP}s8a Ǫ+(Kj$k]8B}MnWĭDP@P@P@P@P@P@P@P@P@P?:ثy#x^W=NFHֿ!Ij~&mm.lCD樰zF7.*>):rtk>hՔy3MI&墕jufOu(nדZtݟO/$f#ӛb?VRzWOũֺK㬺m݅f5_[mIy[;[{\Aa2 ZM:eRZBM]J[NRW͟_?+m}xZH>➻g㵸񿉢DWNؼ5(šEMVoGOf9+2ޕ^4쒗GRZEsr(FN/Zj}s2  ( ( ( ( ( ( ( ( ( ( ( ( ( (z'd`ۀ=j\WWJ$%P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@ ^pP@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P\\Ak 7Smo4\\:C 1I,2hg!51ܝ۲M9oV77m审ep༲uWh١i"++vՔ(2N>T女5PP@P@P@P@P@P@P@P@P@P@P@P@P@P@ ?3E}>+|1~ j tψ> >%:UzU׋4*PР}F)$Mno*Csm$ FЫ 5p(8QMMsYm5RܒwQi$ԯiEJ;5kmz#iuP@P@P@P@P@P@P@P@P@y% J/m/ZJ|y_i{).l|/CvxRH6q4cg5(gԔ]Z* Pnգ5:s&fqT*qcv}K-I=Wy>?ҿQ.G.~|{x84Z|'SS[*FNc<2,K-r*NSfNkRuRMʥG7fܚQӚR>;տAo/~z/⦣uxR~? ?G#ZLZ7IDx巸EȒ2Ѽ42ɝJS7ɫh/,$*Fy5íRP@P@P@P@|[tݿ`/w?o! Gmuo뗂YHcI획2j$9ώGUN!*\ϕ!g;M\Z¨.GRu].WjьS)JRIE$'Ũ;{>&-_[xMmVĺf4i-٩Ŵڎ]J8% evehGdK[s]wtV0 ( ( ( (l>˒0z {O9Y]MvѻKG!P@P@. Ǿ~ދ0ߧjW뾿֗x:g;w9Zϳj !8[[𧉴mZz毠k:^x{U4]?Z&K wT 5TV9Ǟ%85(qm4ީV7 JQbVmY;UjZM#O?~5h/43G ǯj玿/mK?xA{(;\6aY hvʟCg1G {>HFZ+F O%ͻ`N*BudRRy`|׳J_7r?/'Ark׺ezk ǯ}N(_Zol'?Ӏ}Kitpip>S^vKߠiGQZ9_m8?縡.M/;۰iN;בwmS#~%P@P@P@P@P@P@P@yߊ#_<ǣx?5kWSFMo,ڇ IwNYL0*۔s| ):JNӞRT\猤scqtXZQۋh-FN{>V)/O%?Q~ԟ|9p~ag%{݂hYhb[M +8o \ z"ʤTRM')jPbƜT}~b)op"r]-rr=&j7:VizEnbדXYI%h72E]_+_aNz4VThԩUqfRNR䬓nY~SK^bI$; OLͪx_ /> O// Vk]OLy"o!{tK2C_b>8UNrT%RՕޑRnъzBXuAQv~Ό*ъqZ9>f&ah9F( Z-Wf6v,['j*5gRr匛j)hch`Y%H!_jRbw[uN'v:.J|9izEƋZjU6P{[["oFLB)ԣ9SNtj.^jU!(TӒiKM5tMKd4|L~ȟ}O k~I-2H_fK-Ͱ[{e/ 'zֆ*TT߹QG3Iߕ~i&ӲFuFJNJ^>{ ~7b;UC,mRpiGIeٳJ7R-.]I%~*Y"bO}vuP@y 2 J"CY[Rkk;u-O7 k=/OCoOg4~ξT?>8|7ky>#J7-u&CID`:ؔM^.,-iA6ڔ5>U)FQZi/{]E:e5+zkug/_/m??<+7I]bT/;q/"CsM*3 p-z2wehM' I]5y4TW_ 赘w:鵏kz?tw9MwS4^fK}=o+Jc(Ӕ߹Jr|]֚|厡aZZ]^ŕ7Wv kunA42),R:0XN.)&o:;k|VY(>!4iz^Ȳ<9ejW/%Ɇʼr]#~Wdo(,#^\Vחk*T]&dT[m6Օ;_Oً Կ𶀱<;}&AamzG,v-PiWW+q~" m8V9s9T,-i)NS-{i>R'QBPMm\o~kDCOk~(]9.cEizw};MV T+O*@빶<]']qpn[m'gm. 8f5Ei^Ib`6ōA #p,E:*qIGF1rycהrU(QNR"mɷ[$c} w߳~Yxv5OeOA@Ƶyᨴ 4\L|?,2^fZy2JptqNiF2q58UMƵJiY/bUlbrHݦ'mtS;_߈-xXU>M @jX2CNPnMA%jfO죏H)K[\Ki)'ﭗ m 5~ u<Ae?ZkwVVבE%kJEazI$QѾj##6e82K}cy%k[UܯxT_cyjzn}:սM5ԑ[[%YcE*>l>:VjӜvZvi!J<'A4Ҏޖ۲gw/,GcK 2k?޻f0k3K|9ӿt}m S,n_B_RM>WRjY_ezpvm4T\_.cO)Fum&;Z&[g㧇>#H~o2]I/>P#I]J kWZF^&Hn`a3%bp45.x.iaǙHV|ғ(=Ij:prBm)6rZKVtMo|1rM(U/\u-gD/}Z'дgBƨ`ˠxH찗\ST5Ie/)7S.X ,BI.uVWN.VPWO ^'Fot6hM.MZugJ׵ﹴ5! ^\w9km*ul`U%q Ѵ-|;qnRj2qO~TM뭮ܯe}]ߟSg  'kZOq}wö>&oWf%'zw'irk4}6-*_L__iϷTM4Q偓sܷ,F+ .qTj׭iQp3sU(&v2c1QFN4g9{.k5)&phOK ?t,4Oط Ix]+7O!Z k-e].@DCӯmh?;dY\ry['*\*>;攔uxBQթAsba)Fl$ӏ,c[WSj~㳌⿤S>O=9K>K+-,k,ƿe $L .&䵲^[_׮ҦBfȕ5Ølqӧzjt)SU'8(ԩ)ƛSiN3ss)ObGBRZvd!{iF2挒/Aw|xAqoWѠuAEmfO*-En|~#G^4(SUg''ʵ֭VsӥV}+[o-=QtLuoRѴmV}Nmt/Kme5[8&6`S4((J!J R+$vݨv,S*cBJӿ%(JbzvI>-[i+r<; &;Y7~%z5=*-gRt_L&Ѵ -t^=BOYV|¬JkW* T5'(YJ.h|9U*]%cJ^ ˷3rN|{֍4?pn?fWD־bԼ?_? sJ$ x[^K3kvAX"G pŸ 𔾭VZR*Ug(ӌ\RI{SьƪnUI4`F2hII7dܚG/ %wJtύ?5;J>0oIɧyIlkk;-VtK[8%˭ SՋ\iQSmi7mTeSP=I ĦN/ZߙhӼvHԼq&+x!A/,p31$SV:VJU:PqfҿNQ ԛQ8sЊrIV=oƺũe&G.~ w|9k4$],js7:w$dvSI-꿥 xJrNTwJҌ$4|LsQN92+kdI6*|C 'pI!@P@P@P@P@P@P@P?)~xSo/K⟌YtFdhV{}G[I  ̋|:O [Tgx{ zsvRK^'̭8?bxi56ܩS[_ݵK+_I?ي]xj{{SOh|U0\:-jw}N`vMQ$J|&mqxSQU*NnV"smyhF1TbbRIz%d~W|Q ?d/%\Iχmc mx=c#2xmbUW"ɫ繅, :QwW({XQ,g8sJzYFk%&҅4)&YF-M%{7MG?\xx-WIPEhZA &{?WN)usyݟl"aax qV3<^ Kv.$ѫNR+B2hťctOw_ſ\KīRHmWRϋ~U]_Դ+5-*[YM{*Jxmai`,- 2[J =w惡t嘉c֢= >qRIB7䊜fT#yJ&Pp[5w^⋓Mz]e׫~)zզwWuOFrz~Et{{FL=+G->ԢZg/3VilvZWt{yMhO!B-\m<Zv&XxҒTI'WFNM~n{Je/:35tۋ"Ğ3շXV7["jP#rM[6Sj8+FQIFSΜkFfzmq 9SRV Sݽt+N. Tݽr/̿!Gi?'/?_ zƣkhu; 5֝#Gm(Qb1X<6 ӣF$ZЍ׮5wttpV󪤜MM5ngwGsl(#įy^=Ko4 xPR4L1Owu3c{,{Z&*=GdJF7I(i%%)(E]??3o[ ?{,? ]K(m}WA|_{aMŚ*lCJyoej8cJ:9yKuI%QJ4i]IC˨/B)=y5Y8N*1v|IV؏Wwrf;ψ^9"MK-yj54O iv:4څiחU-+6V5o|i#5ޏVЯ]+- ~ ӝV7\$,GR:fܷrg'ԨDՔs6I]$Jь]QKo)j? @5{C|9<;+?x?,m]FÝZYu4;+{'p.ʦ+ZbwSKZݼxngX}<4tFMʒmhMg+Z1Q[HsG΍W:3kcp̬0Č~dXL&'Q#F5NoG)7)^ 9F7>HQ:dNr/%odnMm#`-ҟV_gǟٗ—?a>Ɵi&mH֠׵"uZ M|8hbj`'GO1ic.(ѫV4ԭF3 v~V__S4_Rn4+4aSnqIEsiJRG~f|rU:!_Q4 ZnVtӠ WI'B^<j{z>C'RtHwٵt)$~XnkWYf|}]cUڕ֓|VaW񇋼Ea,Oij ;I`n"c*1\RicqjanT-rQjݵ(F:>e)(RP_,1y5Voܴ ?us;^6ro r|$ைχď i4gq|#"݊]Bo/kz^-|Gg}5i"as1kK:NS9$ TcOu7qizl-ҝ~hB-I\/LѬ-tMtZ[p.Jmgkp[œh ,&zVyJukTZjMԛQ\{Y-֔RRKV_tK4!Jo|?/u7F񆃨wQ|/xoVv[Kuc}jP+pʈNʳVt*Ƭ,NkXZ'&zN 8M;4M=WToceѿd?3x"Rյ n{~=湭_ [\w_Y[Țn"OBSu9UiNY[ZNk~?L3>kG_𗄴}6_O#ԅ{wK\gOQϲE3z8Z89Ƶ9+BU%N-=>UPgfux')GF0aQIk>iKsn8Ú<gf]o_/~-k{JWx'ڜ:Ƨ[}ŷwwv(T 0eٕ|^Tj^HsqN0IєTR3m7`ףAR&G本eCൿo}Oso mW[α^ѳʑ9DT$!51u!VXPq*RRu$٧.Iq^-xh洣NRҝ7)s|#ew/їm&|2~SF׉d9jVNk]/i_MvwXIxjq*J܊\rJ:r[\ /?ƗWOS ۯ+o/Œjn%ys OqFȌ2_u_m7wk;Cn}+9:\ IZ^~Ț௉߶_|QxMvգ4dk5HD(5 9PS8<#J( Jmх wMF[7{{8\R|ѫ i/%km6k-ѥ"HgH8]Jc?y+5ùxRI*)Js,#EJ򔚌TRҎҔ`()6ܚI$n$mWgM OGu SWc SmO`6Z?ku5jWzyx[Kbu^?ⷊ#KO$m7ANi $$RxOE(kMGxI2֔&FqN3I>T(JI71 4okfҋqo]c%+p3[J` <[O>+ S⇇<k>έkYo:Y8{=41][4c)C`ؗ8ѯBjJq.>#k>ԣiĿ|RWg]mMƷH۪B8CܿҤC/gntJ;IsJҩ+oky=],m:ƭFwVZjw-4/HQ/'l6vJ\%ЂjӍ:P:%>i)NRJiJMEnՅsR\q˖)˖+ޓI)Yo Eo? |4_kp_u7AiuLwj:[,WWyPv?iyv qPD*F1PI-9Ui+AS\"y[tq Qr%6=j~'/W6xOD}GͭE` y5M'kdNp٦oX䧃7Z4ESTQ8ԽiP|˞RНFʬЌiҝYJ5>EWiԒ;]o_YOsQ~Agk}Q?O> x.g4_ [ OhڅBE8IǗŸ}T֞U/fV[ouOO*%m |?'G㱶Ҵح]:8 Va'.u[Q%fgoqucu+TVi:qnU&߳Z88H/gN*M^0\򾍨i9;7vrw~#o/g>8 |AzDi᷀ӝy(DO$prC^X -?WT8**}R999Mܪ7vx*پ2&#Q4T n(A($:Wr1)5~ {ik=Y *}C=m%KyűsQwxH yQ[8NhmTpFWwN'4,S|n7P_\R6vǚ*.)N˞k45ƊTPBT(03_wt7&މ>kig%6Kc>%iZKmF$>heq q|FmM&K Mp? ԰2FNhNsjNnr7hFU*¥774㈪Tt%VrXB%'FRdpM6s!_+?7 c_w E}x/G/4+I-*ݤ`=:(>ix1Ŝ[_5JJ9=#(΢4ctW,8J+m8?vIr[m7.|Qiwcz/z_qgklw0!/Gx <-ҵў^ \ENUWU'RN*(TR]% F.QR1 [5QqJNmKT7,ۋqk> Ÿu]U 5֡n.x3N&^C:]O*CWc#S2NexAiVΖ[ͶRmZsrivt}wC3v~_;o/tZ`4"=O֝)|C]AmhݼNVt*up0595*QpS4&Nr5bʑN|uIbq<>zم:4g$f䓔$eAfo wz'OV4œR:8Ctz-Ȼڋ:Req.\ʞ3*Zq)TrœM(Y/2~M+ocͧƍ9J2 V#rZ5>WyI4^OڻᧄfGDӤߎ4 ZbMoR58KWHq]蚆LWikpUkb8Y2`F2 Ur>W*xq\O1O9ɋrE (.m#g7ZW?ScoGyE[xC0 ( ( (g6IJ.rx\%YJL˗I5ʯi$OjL՝;koj( ( (*ꚦiƱ}iZe{*ZYFO)U(Y،`vөZQJJ&ҍ:krvRQ M薉©R*%B*򔝒^%vKVn۾R|4/ !JjgŞ񯈚KGco ~% O$B}3|V4 ݛmy!e?,')x:Y:_,K7{'RVZNQMY;%o)ya)ᩨ›<b$g$rsYݮg7X+?ҿ`%߆.fD-7EŶ_xjqxHd/9?ndkƟ}wepbg5eRh˾UUJ]Ph3J0xL#V\ܪRn)Z7i^|X'k7$2 >goYtxwI׼I-}/o(NjK2$ )5ۈO \љbjd9F'C:xB*Qks7()݂J2oXq98E(-."we>uxCӼK_iNjujuڅ 7H9 >J*Fu!$ԎiJ-%u+-QUiSNTNRkTVi4M5|ry0| \=է/o;1s{4+}\]\44횝rZYYX ⵵ :e&I>i;՞ֽ,ԺTFܪM:Jܥ$)4%{X],࠿R/ Xk|;idT5}WN_it[4 xZ#2Goz.eYk.RO(4Ԩ҄U*8k 4Պiʴs'9xUqќ9a%+ukK%X=>| Gt oK`t8-PDIBk%772Ks!2K!o%'99I9ۓn5ݫhע=Vrog]LA@2{+-, -#h--W{ywheFfGFVBn-J-Qi~kךOF &OFޭ߇ֵ<)-`4-OSxmɶ [+Y q"EGW6RHAJRrWT6aNJ䝣'm R+m%ԞY/XQd:_H?-=0Tb+l_l]__eYE>2R+1NғԛRmr9]=U,ֽE SRkVK(5U_ddyw}IqGۯiKt*%*srrqM$W(iYೋxsAԿcػAOiYj~"Ki|2PO:٥X56z4 U'J}TFuf9;9IuV  BҦ*N=E(ʓN\'$Ӈ*M? +xjONEkgH|K~-; Q"V 'g\GkF>SQ'zSHr8FW{FqyLXpj))Ɯ=vIiYEg~Ɵ_?Eğ ~ԧկt'Z>U+t[zޟKz KtۛbۢbL8ΨSB(hSRIq4I>^nmyaƒx:߼UsT5iwzjӊ=~~f|-aoOiхfԼ]!<_Oyhod);߮[zJVC / uLxæݽ xKȂK{ xU:L^ɬHR =˧g .dQ8-5$ԥ-corYV&%8T((;?}i*Qkf7Ko ^x[k׮/SRGox>6mJmt42$̇ݝHVj> i߳;Aៅ<9pYV]P˝nmBiY&i%|*\S^qu8.iv}j"[(zs %t&e~5 OtSqOo4 exY U|3k&i巃.*f0*W :< ӫFu&ԩԥ ojB#qF.PH(*G>*!%MzSR9ZJMg? x$_X#<]AjZhyZͯ-ζ[vxx42bseL~%beҝ^S_q)O./Q5Z} iBR%Tp uȹc)'tw*ij-zL] /xF2m7Em7mX~ɩJ`j5B*Ig J3N)ŸOS7:CissZ9d;86tu~5y>0k_ ?9<=|`>r{Ě\xm\Ǝx$I!E/76Tq*MUn?TSqrRt饆Ib!A¥())+8{&s_C?wO爖Ŀo/>-xhD[m@.]YDld Z+o2?28NWB0NRiJbIQ./^ӗƷ}Vv_Ty's1xt)>;КD ]]yτ~j8X-iVYޘSԵ Q^"_+x֮>c6 R4IZjMFjuS哧h>>m:x&Uj-J߹G^_hZN3%%ܺo ?qK<_Mx-ī; -#6z@Žȕgy b1.q3Jqu*>ҫm{s-:iW{GNf읽!u(ҥUNm(SSF2rPLsA<$x/]9o;m> y<5k--PX.e(c_²7S"px<<L~:*jPYO9:ҫSN׽5;B*u#r} r%ڌ8NRS'nFug:|sgwoM _'NkT־ >ͭl-CVh{tGQAuey=KV?GfAejեba 6"WgzVیI|NIc \0J9ܰ_&}pz~ʹUn[+fI4xrtOj09 Fi:\xԢhXzwjҼ'P%9Cr½JR\PI K)'QƜeUܯ(-Fpu{ݦk ?+H:/#H \k,dt5Rh?{6q,#%iue:RR|Ѕ8IYMkMҠɥmkfzeDfK0ZIaIw2oqsm4fx%TcV֝9FgQQQ94uuJrFQu):NәÛi^5vT=zo2>•K%![/9? ?>/rYg[`wˍR)KնsxSv?2^#.XRp\Ө}Ȼk{Uœ'5ˍ}W izT5wѴU7hB.RI#F>0࡞=7xg.SZIe{9'khw4 k`i-[+ OBrP(QKR%9r˝rӦe):o7'Teխ9__)#nX*߸X/:_8[_¯9; WpZDDž"q%հ̙78 .XN(Uar3RRZrܩ79Ԍ*USQ$TRVi/qi}qoayoYև%.ɼ 6LM4\;$ImFYqpԣ 1M8JV-qm].dGU՞.7d.O~;vZ?V|-af:?5eOxy;Mn,AKǿeA!:*cqV,,jJ81TBj|ybRoxTˁZ8{JsMRy^sRTSn?wS:$~~V fWlğ$Vج_ |sw.d.c6~gڱH f0̅K 9Ҧ)B3`-)JO߻_(C ڂ"KK_dOkM?V3_;m|U>%4T*|'ZR(4Ihl_^0?k3-3QgMkK&Kkku4$w0AٶʚUC_ SjXwNՍ\i$j1Jk+%&1F9GXnܪ6<_z5xƒ[Kzcexk[{ɡtK쨐( :T+ԥR(T.j}ئo4~n1iQRQm^Wm;;\슑G~u6׾A@zG2˦m!u={_p @ ( ( (B;@.w9f#*NN^S[ﵿڠ ( ( (̡䟕) ' FʶpxzJ6z^NݵV'j35_j?M؊ž#៎Wvdwյ- ؝{Ry5X~_/_9].&u6Qr )˒iWrm/ztO5bYF6zΚ%_(W[MFoV▿jGѣz6]Pҋ[Iss>d 8U!*RR|ZJ:)?yY;O-aa8Ty}N.ZYM=ѿ`?ۇoþ-/l5/Г⇁n?K)izĺJgjyL ]_K~SxWZeB=,Kj5wihNVm._}ץ]t&cIE5y7(},A<jZIee59iQK4ԫ8ӧ ԩ?vS'&'זͯ"[QMɤ%ވ?ିW_fs?gDiTuIb?c^Ӧ沙B;w'#2b1o*U09z|F"ybӓS;5wQ3c?iiKXzNOٿQpJ&O٣}υ^#/I޿Eݧ{mWLsM~ɷ =hV68C*O_(-j$$\Қ撌~)4G 2TR.wM;ek,aN ^F~8_4k֦WGyŚEoqpiB䙚C;NJi[1θs 1UhII7\c$_ m$9~8nUXxsv~"֬4xTZX:ԫ=G_/|TX|Ѧ8W|~iUvVINHKr+7wfխf֗J>n.7 (m9~~_fǿḱ^l\/Zbx]|D OKۙ?s#_rld,ƍ:|,Nڛ9E)*s\$ Y.iRJ$go:J j.nINԜF6+$ҔeN9{Jf?ػI;M7]~*x-4(crU{mg+tfK#9::RueRRoj)+>mծRW-nt;ǚo_Q\Ϧ|+/ks BKF/~0L\ZL$*ƻ~ׂ]'gp)̡Ν9F\J5e(ԌG5 NU%S`V :N즹䤹 7ȟg)%h# ^?ec_w x? > GSּSֿ:׈b/m43C}FP/'&y#Odj*e8*m^XՕhΛ)5nIKJQN>,%hUUt[?t̪Xe`Y\` CpbM馝kXMKN?$-M~)/e?Z/^6*|Amvw)-tIq۷?hH5NMUp52ʒiZZڜe>Ug0PRe)rCxl5,lqX4qTkхU kI?/VkoO;о1x {kZ?+xDQY_h≥^Ѯ/{#V_ lȴ9#CUKy>ۅ|!egĐqiWmrTu)TwpwFQXml3Ԋus:39s'P9jBsY͹A%M9U>?kjo >:i.QYRKK~ks=}J?Q[}OXx|AY~]/iVtܰ?u(*rW+&Ӌ<<#BPp*\J*77>y'y)Hp?oo oQS~Ծ/<n >ǩuu xS $iijHخYpC(rJX<5g9CRĪ3I sINβV<\c$z˚.<Ѫ״ӛZI)F/Wt}~[s5*t|ͪiZy|5-+ំ^ мJkشkyn}N̒4׷s$3oq别SRGvܴK&vI{oOyF1J0cW*]lI.gs_W_(7 k?ռu^i߇-|Kqo :dWhƟm4o/lVN[1}e\.qϲYMjprS)Ɗ;*RQRaFexNl3(rs\b4/X@?Qo/)o(~w_z֟uz7m[Bm;xukSyqF<hSĺ~+n1e|#RU0NN+⥤yy(A˪e7 >ZbO' H%Bt7;+ΜVMss]ӄyo_CeGeI_96x\оѬy4__}˧tftQygJ8F2M)J"Tڄԧ:7xFƌuwj|<\47+'kdkW(N|eW(b־6]c[>r]ު1Տ+$IVɶ\YLqc}l'^X湬RxIh%;&\wPZc{jCw=x=?Ú]k|E"MovkDjWy~/XOKGJTQnqҝ7xp匒Sp(`.HS8R^<ܜmK+^|%|`~>%xKJEx@]]5 n49]i/|E?_9ɱئT8Y*g*[u**n+*q%_SR*RFrN\$I׌9\Q\Y8I?W|~xr?^?:{Gn|Gq?;Ge73r4c:1jjKIrœzqn ss֝q/9oQSݻEtQ.H^5Ai3H|eS~Q# Ykz(xsX|Iz/tnFh>5t$:iYH[%aZ6J4NW%8ܔT"Z<&2jz/g8ڔꦥ4쮤n(YBߴ߄g-E/1N6K}";Z+Y(5 7SV/zܪ_Ji6VPnǕUug# 㗰Tzs+ +FkE5x)~ϕmJ+EǬ~U??f-Vƛ:|WaexOĺXMqq}5sv/e$F5,cxSFJ5e9RJSi:K/u;E5wʄ0*p$eM{qv^D73_/ j6Zo-"6?ϩ~!`O.9GνO' RR[' Sj2+{5+)FShFХB 1N1ZB>TcOT_k؃G ZW~1cwk]R䔝NMNSIss kpeC+)5eJ,MI)(.rp EQ!:(r*Sj)+OkwM_ Z~şc  _ 5?G߉MRv?$5]?P}z)A4$:i5 -r6eBjJUVy}J~TRQoJx~USt3ܤi]K[rIC 1ۺ[_궟>>_|><Yo~/LJy[K{4׼.moep'YajSnPܜdͭ5)JRrm uV_v9{>tEZ+K%edPݿײikgmZso;MF 'm&p<=k]I㾞H`ȼu J8!QBO>P*r5HTMIԅu5iu0f-IRO2Td(|6:wl%GrfxgV4on1TRDԬc<3RUkFZ6Y*8R p,b,_.U$Х4N6V]gW+7OO Şm M^&F&jvEI[=IV$3ݠ}f\14ԣNsR^FPRqR+^牛´4T)NP(ǟhF|;VRj՟>|R9| ,|<s{owk6iOm/O+;b[BT.P/[ӯ+JTpѪ QM)snJ3IAOsQ2aaS &)JJ.2NIDk߇?Qo wƽ}cđoO_5/'hu9&nV 0^<^Mvm҄rkpnUҜU9΋)a^F)F1٨(`~6]ZP5r5(άⒽDZM;FRwQU//iǀ|K5 ce|,,(Vɭc廞+i;=кHcpoo8{!"+b*5#VUT8ҕTBt)ԛ|[^R嚍ZJ>,^Ҳ?P~gſs⮱aOz'h|nHׅ<wx6mtHVX,YH2<¼#&G9GYEB p\R圽8Fhey|Z7s5 67GXkޯGZSJ^үWK|OJEs?:݅nO;j 6ףpT_9:QR%75&s%'q߳\;;r;4JJ\'#n8@{sojOij]mӫH//A5tx~-yu=fÖ {{ 6;{IK즒dS e8.ôraK#SU Pef/i x^N|0昜F"R̜RMwh{-)rI / x:t:NZsbVh5c ~>r̅&kg? a\ƶ..nz:Pt*k㋔ckWQхZ2Oߕӎf<ͦjN'?WZR|b?5U&?/]xϫxO-?k:Z|ᴛD#UC}< t.M{~`hS1 qJTkӤ:mA{ = ]T4_ĜWMOV[BH  1<E9|vq7zjݗf|Z&ߡ~D[3'_?Z{_rC?^ ռ_ ;\\|UskH ϑ%Y[Gl 2"YU ѕ?m "jּڌ$SaNrڵqVjS4=HB"ӝܭ}&}O~n}?HJb ( ( ( ( ( (8|2s/x~tquh4x, ͭq:d9Nu7 %׭:q:tnJs7N6VIFM$ҽ-ҖZSUSrʢTvr3WIٶ]W/ߴ|QvZj V76|<^i<+-i[mv,̱Y>28HZj?糯 Qq*nt۴ 8)N5Mh^.IUFS ~|}x=$0^_TڏV/4Zd6RZ4koquq,#yOpm⩺ UUG$Ռjui]*Pѧ/MTI5>MZM,K.|#c㷉4ij>3Դ+ Y/–o07$B|҆@lGpXr 1&,buZj2^nwo{sYoMCCǏj7>tfտ>G(7͠OL`,:2:HZ΄yfY(Cpo[5(ҋ(qԽtu.1^T{t]OV|]xAG?o); ?N񷅬NOuKFo|?J[OncmEoO^/~$thզ𶙧kwciaؾ!J^/3lRVPٹN*ټuzҍyU:oRMnk?o>|I61 )d+iNaO.;F4kZ"c.o/BDn/8kbj/u:%.TSqM ʗ3W}Z҅(*1ZY|ޭ~O|S)x Tߎ+AW#=} \nin%JRO)y~?13#ZT]9OZַ+׼fE1AGF*ʹXg?#g_~3|^~(2 k5y6;+E]Fѧr4DRm~1]QXX>nZMCcNij⮢(=|€ ( *~%h/j&~i֋ۍ7ĺi-[ȑjvM:41c eAʰxhp[MՇO߃Ş:5֑h?4_Cl$Nr$2`Ύ fxܺsPOU w抜ud/GR/9ҧU8Fn9E7=߲?He5? ѼI$P?m0Kknc|l`;8T5 IM.iTnZ]FNI1taF6}^qP_=@ּ+MG^hi:Γ@fat[^YBżr)/X|N# 8WQJIҋMŤ'}TqT?+k ~ QGuk/|3f0Gj:p)[܄cou/wC ෻[{a9" hdXb),2R)WH*%7(-4ӕx%kTe4ItWVjG6kw{]r/}-^>)<:P|+ӴO[tgݢGfy2o8.X*Qteov8I nD9V7+rwrwWw{~vi:NcgZ]iuZ~@֖66Q0qDj[wzۻow[>%߲-޷xJ^(е :%-1-ŝŴƗP\~-^SyKN, hӧVj(s5;FN A4ۊPtr0K|*ni4Ҕ&նlɿOW'ԠÚW^w>B͎[Ë-=e-/t{g #+Ɏ1ٌUsNe.Kǚߔﮎ\I&,=::]3+%6}\Kg~ |:_/~(&xci.$Xn4ӭC]_\[+ٖeճ\e­U>I%tQJ8Ũr?zJ.mg^0Vcm#g&۲I6zuo +AI(ڷ#~յ&xŸO>w|Z8{'9E<:^yhY?Dlm,Od4W%<<%M9:tജtܹ&9ORrgR+MFUg6S*r|\*:&nTQIh]\tH ghk[Dz&xbE,3F" GS;Jt'N4$e~՚MiI֏I=E(a(% QFR8E*/ʠswyJMRnSiWm[{ik42[mo-E< &%ܱcpfg"P5q%(QpqvjQ^앗2o+iz5.][=2dyqFncĶhVYU*ںmemdk٭o."5Nw"..Xc=UrppADVvQ} Hr_ɵ;x˹%7>2D9:YS&Iɷ[zc.X1]_r%P@P@iK4bG# @$1"8ϊWK~zj֕K)t['*tӅ5IiwAD;w1-@U`[ (/sRnRr-99KI.ozMRzY$V)%in2 (F2"wv 37TIuMFscrcEsc&I]Mdn%{+u?o4V?-֡\u |]}%l-~Y5"Ya6Ikqmi 2_ PV-G 0J1*Z mhA+G˨*i7,L%MFRQQM]sm_V Xa+kkxc` QFEjhTU Wnmmm~=H)`4cIb),r22e%XH&OK[NVO5'}ﮝpOυ׷:hm'ӥIg3ӴeA 01Ni[FJᄎrN˧INK|)_S,;gte]]Xp@9;6WPmwhU0bQi|6\\RI)sI(Ek+;}nw]wztj[e!O4b4|mt{MZm%-+[9=%?h7 O:KԩB:v)OANsԹU r\6Ibecqbjӄ$w5VIF*Ҽ"G~͚/3|&ǂ<3kxjk/O+wqh6Eւ#EY*̯H1ycqu'kRnT.uY%&-/m]Ss?hGӿ_?}ZWS=;ѵMc\<7z׈d}XӴ}>T'JC.kwz)+N!F*Ra:)FSҌSI%-"Vohv۲Zݒ}^ =}3T+躿? ( ( (.x=9*$ `Q_-VIofw%  ( ( ( ( ( ( ( ( ( ( _|n~^/uCÞ/.Kco.[jFki,;cm\OC(ӧ Se)EɪiIFJqq\ydڒB~{))-WQkTR ,|gwj~uMs[5 5k_kOQ8$#Fe|Φmҍ598]^rv˫TiF5^E%^K]MP@P@P@P@P@PƟP/h.)rĿZψ~ x[msŚ-ayon-/Om牪cp(MOU9gc-y!ͼe%r`Cs9E^ 8t9r2V{_[V_w=)( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (WNNhIm,Jb (>\tmZ_^-_@GϷ83ס+}'?ߟLBP@P@P@P@P@P@F!u9_2 ɿXp_3?lNQˈ?+&œo;aϬWKF!u9GC. q>_ /\3oD o)?4pbL!_?2 ɿXp_b_LVVrAw `K)>̧ } _OC D7gr\AAY7 }b_?1&gۯ ?qdSp8/i?Cn6?'(eN7+˃#f 蜣!VM8wÂX.C D7gr\AAY7 }b_?1&gۯ ?qdSp8/i?Cn6?'(eN7+˃#f 蜣!VM8wÂX.C D7gr\AAY7 }b_?1&gۯ ?qdSp8/i?Cn6?'(eN7+˃#f 蜣!VM8wÂX.C D7gr\AAY7 }b_?1&gۯ ?qdSp8/i?Cn6?'(eN7+˃#f 蜣!VM8wÂX.C D7gr\AAY7 }b_?1&gۯ ?qdSp8/i?Cn6?'(eN7+˃#f 蜣!VM8wÂX.C D7gr\AAY7 }b_?1&gۯ ?qdSp8/i?Cn6?'(eN7+˃#f 蜣!VM8wÂX.C D7gr\AAY7 }b_?1&gۯ ?qdSp8/i?Cn6?'(eN7+˃#f 蜣!VM8wÂX.C D7gr\AAY7 }b_?1&gۯ ?qdSp8/i?Cn6?'(eN7+˃#f 蜣!VM8wÂX.C D7gr\AAY7 }b_?1&gۯ ?qdSp8/i?Cn6?'(eN7+˃#f 蜣!VM8wÂX.C D7gr\AAY7 }b_?1&gۯ ?qdSp8/i?Cn6?'(eN7+˃#f 蜣!VM8wÂX.C D7gr\AAY7 }b_?1&gۯ ?qdSp8/i?Cn6?'(eN7+˃#f 蜣!VM8wÂX.C D7gr\AAY7 }b_?1&gۯ ?qdSp8/i?Cn6?'(eN7+˃#f 蜣!VM8wÂX.C D7gr\AAY7 }b_?1&gۯ ?qdSp8/i?Cn6?'(eN7+˃#f 蜣!VM8wÂX.C D7gr\AAY7 }b_?1&gۯ ?qdSp8/i?Cn6?'(eN7+˃#f 蜣!VM8wÂX.C D7gr\AAY7 }b_?1&gۯ ?qdSp8/i?Cn6?'(eN7+˃#f 蜣!VM8wÂX.C D7gr\AAY7 }b_?1&o۫ 9\^Oc_8/)?1&o۫  s ?+#f 蜣!}AyGc?x3oD/\AAY7 }b_?1&gۯ ?qdSp8/i?Cn6?'(eN7+˃#f 蜣!VM8wÂX.C D7gr\AAY7 }b_?1&gۯ ?qdSp8/i?Cn6?'(eN7+˃#f 蜣!VM8wÂX.C D7gr\AAY7 }b_?1&gۯ ?qdSp8/i?Cn6?'(eN7+˃#f 蜣!VM8wÂX.C D7gr\AAY7 }b_?1&gۯ ?qdSp8/i?Cn6?'(eN7+˃#f 蜣!VM8wÂX.C D7gr\AAY7 }b_OC D7grC(8/)?Cn6?'(c^Q`>_/^7oD s ?+#f 蜣!}AyGc?xbL!W?1Ͽ/(Œo0ÂX/#f 蜣!AyGc }b _?1&gۯ _ o)?4pbL!_?2 ɿXp_3?lNQˈ?+&œo;aϬWKF!u9GC. q>_ /\3oD o)?4pbL!_?2 ɿXp_3?lNQˈ?+&œo;aϬWKmagrittr/vignettes/magrittr.Rmd0000644000175100001440000001770612434047153016444 0ustar hornikusers ```{r, echo = FALSE, message = FALSE} library(magrittr) options(scipen = 3) knitr::opts_chunk$set( comment = NA, error = FALSE, tidy = FALSE) ``` ![magrittr-pipe](magrittr.jpg) *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/README.md0000644000175100001440000001151212434047153013403 0ustar hornikusersmagrittr - Ceci n'est pas un pipe. ==================================== [![Build Status](https://travis-ci.org/smbache/magrittr.png?branch=dev)](https://travis-ci.org/smbache/magrittr) # Introduction 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) %>% head(100) 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. # Installation To install the current development version use devtools: devtools::install_github("smbache/magrittr") To install the CRAN version: install.packages("magrittr") # Features ### Basic piping: * `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)))` ### The argument placeholder * `x %>% f(y, .)` is equivalent to `f(y, x)` * `x %>% f(y, z = .)` is equivalent to `f(y, z = x)` ### Re-using the placeholder for attributes 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))` ### More advanced right-hand sides and lambdas 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) } %>% summary ### Building (unary) functions 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(.)) ### Tee operations 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. colSums ### Pipe with exposition of variables 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)) %$% ts.plot(z) ### Compound assignment pipe operations 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 %>% sqrt 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 vignette("magrittr") magrittr/MD50000644000175100001440000000423712434151335012440 0ustar hornikusers9c0b8a1b0db74f48c62fd20cead4ee9d *DESCRIPTION a085c7c24ade7b2da1aabe7068a47a49 *LICENSE 4713058135841cd36e63debfcbdee1b3 *NAMESPACE 339b223c3e7543f9ff84612ef9020d48 *R/aliases.R 4c559680ce313887c9a4a030e7288d08 *R/debug_pipe.R c57bee0db55713b32a479a9eddf42126 *R/first_type.R 085fecfbcdf1709260ba6022f886085d *R/freduce.R 2f1141b88747f0eae21efa41d4312308 *R/function_type.R 70b7526a11508ac16ebcef4aec6b1ef1 *R/functions.R 73f90406e59484f27461cd6d9fa8befa *R/getters.R cdea686298324dff73d97579be426f6c *R/is_something.R f74ea4cf8f6afd8474a13695c56d6ad8 *R/magrittr.R 58671c36b9290b95797166e59a7f8773 *R/pipe.R 925c408caac6b5555bf7ca19f3fe5d14 *R/split_chain.R 761fbdcdf240c19efc40b266c657527a *R/wrap_function.R c0a8b34896112d5cd8e5ef7b500c4d3c *README.md e6afd78ac4185a0808a2f1a5ba183961 *build/vignette.rds 083617b1c3cac5f5926325c536019ea0 *inst/doc/magrittr.R 3d83e4728a3669156481faa4e48aec0d *inst/doc/magrittr.Rmd d412378d3f4b00c0fbc78a3bbd82d7ac *inst/doc/magrittr.html 9b61084fde0047a022938c17e5dd28ac *man/aliases.Rd 25168a657341fa779300e16adad8d2a8 *man/compound.Rd bb6ddcb2585511a2b11bcf255a5cb34d *man/debug_fseq.Rd 1a90577e8606d5254c62ee607228e6e1 *man/debug_pipe.Rd cad11ff20cac264dd14f4f0b2ca51c1f *man/exposition.Rd 14d43d276195d127b4bb3b920a3fe5a3 *man/freduce.Rd 4d05a1e25179e4b5c8b54d5076ee843e *man/fseq.Rd b67091c9e405ac51d223799a0ebf95e4 *man/functions.Rd 2b4d1b41136b536f467c0ec3ef6a0df3 *man/magrittr.Rd a92ef98880933848688ccb9b0a2c1c48 *man/pipe.Rd 705c8b3737616993c1e4d39df1f6b184 *man/print.fseq.Rd 3c49d7774ce9f965413c0bfcf6eef55f *man/tee.Rd 955e258593aa6ff551e639514066bfb0 *tests/test-all.R 1240dcc13fb6eb83d1d09d00fe6f8a2c *tests/testthat/test-aliases.R c34ba775b25e1b4ba15d465faa82fd6c *tests/testthat/test-anonymous-functions.r 67d71033b672e1d1e3f429837cbe05bc *tests/testthat/test-compound.R 7a15de588a5ce2c952a20b406d0278fb *tests/testthat/test-fseq.r 7ce9041aa19d5ccd29c7938877bbc25c *tests/testthat/test-multiple-arguments.r 668a7efdfa43fe9e4fb42da69251e932 *tests/testthat/test-single-argument.r b71f24b1fdb5cfa83c7276def4534ce9 *tests/testthat/test-tee.r 3d83e4728a3669156481faa4e48aec0d *vignettes/magrittr.Rmd 561cc58e6362ebd922d69884e825c808 *vignettes/magrittr.jpg magrittr/build/0000755000175100001440000000000012434047155013225 5ustar hornikusersmagrittr/build/vignette.rds0000644000175100001440000000032112434047155015560 0ustar hornikusersb```b`fdd`b2 1# 'ML/,)) MA+)O)MKWCS ןQ&Ʌ0a D0!dKM-FZ]?4-ީE0=(jؠjX2sRad9.nP&c0Gq?gQ~poݣ9JI,IK+}hmagrittr/DESCRIPTION0000644000175100001440000000150412434151335013630 0ustar hornikusersPackage: magrittr Type: Package Title: A Forward-Pipe Operator for R Version: 1.5 Author: Stefan Milton Bache and Hadley Wickham Maintainer: Stefan Milton Bache Description: 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." Suggests: testthat, knitr VignetteBuilder: knitr License: MIT + file LICENSE ByteCompile: Yes Packaged: 2014-11-22 08:50:53 UTC; shb NeedsCompilation: no Repository: CRAN Date/Publication: 2014-11-22 19:15:57 magrittr/man/0000755000175100001440000000000012434047153012677 5ustar hornikusersmagrittr/man/print.fseq.Rd0000644000175100001440000000052112434047153015255 0ustar hornikusers% Generated by roxygen2 (4.0.2): do not edit by hand \name{print.fseq} \alias{print.fseq} \title{Print method for functional sequence.} \usage{ \method{print}{fseq}(x, ...) } \arguments{ \item{x}{A functional sequence object} \item{...}{not used.} } \value{ x } \description{ Print method for functional sequence. } magrittr/man/pipe.Rd0000644000175100001440000001212012434047153014117 0ustar hornikusers% Generated by roxygen2 (4.0.2): do not edit by hand \name{\%>\%} \alias{\%>\%} \title{magrittr forward-pipe operator} \usage{ lhs \%>\% rhs } \arguments{ \item{lhs}{A value or the magrittr placeholder.} \item{rhs}{A function call using the magrittr semantics.} } \description{ Pipe an object forward into a function or call expression. } \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. } \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) } \seealso{ \code{\link{\%<>\%}}, \code{\link{\%T>\%}}, \code{\link{\%$\%}} } magrittr/man/tee.Rd0000644000175100001440000000153012434047153013742 0ustar hornikusers% Generated by roxygen2 (4.0.2): do not edit by hand \name{\%T>\%} \alias{\%T>\%} \title{magrittr tee operator} \usage{ lhs \%T>\% rhs } \arguments{ \item{lhs}{A value or the magrittr placeholder.} \item{rhs}{A function call using the magrittr semantics.} } \description{ 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. } \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. } \examples{ rnorm(200) \%>\% matrix(ncol = 2) \%T>\% plot \%>\% # plot usually does not return anything. colSums } \seealso{ \code{\link{\%>\%}}, \code{\link{\%<>\%}}, \code{\link{\%$\%}} } magrittr/man/debug_pipe.Rd0000644000175100001440000000056112434047153015273 0ustar hornikusers% Generated by roxygen2 (4.0.2): do not edit by hand \name{debug_pipe} \alias{debug_pipe} \title{Debugging function for magrittr pipelines.} \usage{ debug_pipe(x) } \arguments{ \item{x}{a value} } \value{ x } \description{ This function is a wrapper around \code{browser}, which makes it easier to debug at certain places in a magrittr pipe chain. } magrittr/man/magrittr.Rd0000644000175100001440000000336212434047153015023 0ustar hornikusers% Generated by roxygen2 (4.0.2): do not edit by hand \docType{package} \name{magrittr} \alias{magrittr} \alias{magrittr-package} \title{magrittr - Ceci n'est pas un pipe} \description{ 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) } } magrittr/man/exposition.Rd0000644000175100001440000000173012434047153015370 0ustar hornikusers% Generated by roxygen2 (4.0.2): do not edit by hand \name{\%$\%} \alias{\%$\%} \title{magrittr exposition pipe-operator} \usage{ lhs \%$\% rhs } \arguments{ \item{lhs}{A list, environment, or a data.frame.} \item{rhs}{An expression where the names in lhs is available.} } \description{ Expose the names in \code{lhs} to the \code{rhs} expression. This is useful when functions do not have a built-in data argument. } \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. } \examples{ iris \%>\% subset(Sepal.Length > mean(Sepal.Length)) \%$\% cor(Sepal.Length, Sepal.Width) data.frame(z = rnorm(100)) \%$\% ts.plot(z) } \seealso{ \code{\link{\%>\%}}, \code{\link{\%<>\%}}, \code{\link{\%$\%}} } magrittr/man/freduce.Rd0000644000175100001440000000074512434047153014611 0ustar hornikusers% Generated by roxygen2 (4.0.2): do not edit by hand \name{freduce} \alias{freduce} \title{Apply a list of functions sequentially} \usage{ freduce(value, function_list) } \arguments{ \item{value}{initial value.} \item{function_list}{a list of functions.} } \value{ The result after applying each function in turn. } \description{ This function applies the first function to \code{value}, then the next function to the result of the previous function call, etc. } magrittr/man/fseq.Rd0000644000175100001440000000115112434047153014122 0ustar hornikusers% Generated by roxygen2 (4.0.2): do not edit by hand \name{[[.fseq} \alias{[.fseq} \alias{[[.fseq} \title{Extract function(s) from a functional sequence.} \usage{ \method{[[}{fseq}(x, ...) \method{[}{fseq}(x, ...) } \arguments{ \item{x}{A functional sequence} \item{...}{index/indices. For double brackets, the index must be of length 1.} } \value{ A function or functional sequence. } \description{ 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. } magrittr/man/debug_fseq.Rd0000644000175100001440000000073112434047153015273 0ustar hornikusers% Generated by roxygen2 (4.0.2): do not edit by hand \name{debug_fseq} \alias{debug_fseq} \alias{undebug_fseq} \title{Debugging function for functional sequences.} \usage{ debug_fseq(fseq, ...) undebug_fseq(fseq) } \arguments{ \item{fseq}{a functional sequence.} \item{...}{indices of functions to debug.} } \value{ \code{invisible(NULL)}. } \description{ This is a utility function for marking functions in a functional sequence for debbuging. } magrittr/man/functions.Rd0000644000175100001440000000066712434047153015207 0ustar hornikusers% Generated by roxygen2 (4.0.2): do not edit by hand \name{functions} \alias{functions} \title{Extract the function list from a functional sequence.} \usage{ functions(fseq) } \arguments{ \item{fseq}{A functional sequence ala magrittr.} } \value{ a list of functions } \description{ This can be used to extract the list of functions inside a functional sequence created with a chain like \code{. \%>\% foo \%>\% bar}. } magrittr/man/compound.Rd0000644000175100001440000000255612434047153015022 0ustar hornikusers% Generated by roxygen2 (4.0.2): do not edit by hand \name{\%<>\%} \alias{\%<>\%} \title{magrittr compound assignment pipe-operator} \usage{ lhs \%<>\% rhs } \arguments{ \item{lhs}{An object which serves both as the initial value and as target.} \item{rhs}{a function call using the magrittr semantics.} } \description{ Pipe an object forward into a function or call expression and update the \code{lhs} object with the resulting value. } \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{\%>\%}}. } \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) } } \seealso{ \code{\link{\%>\%}}, \code{\link{\%T>\%}}, \code{\link{\%$\%}} } magrittr/man/aliases.Rd0000644000175100001440000000464412434047153014617 0ustar hornikusers% Generated by roxygen2 (4.0.2): do not edit by hand \name{extract} \alias{add} \alias{and} \alias{divide_by} \alias{divide_by_int} \alias{equals} \alias{extract} \alias{extract2} \alias{inset} \alias{inset2} \alias{is_greater_than} \alias{is_in} \alias{is_less_than} \alias{is_weakly_greater_than} \alias{is_weakly_less_than} \alias{mod} \alias{multiply_by} \alias{multiply_by_matrix} \alias{n'est pas} \alias{not} \alias{or} \alias{raise_to_power} \alias{set_colnames} \alias{set_names} \alias{set_rownames} \alias{subtract} \alias{use_series} \title{Aliases} \description{ magrittr provides a series of aliases which can be more pleasant to use when composing chains using the \code{\%>\%} operator. } \details{ 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 } } \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) } magrittr/LICENSE0000644000175100001440000000010412434047153013124 0ustar hornikusersYEAR: 2014 COPYRIGHT HOLDER: Stefan Milton Bache and Hadley Wickham