I am fairly new to R and I am trying to understand the %>%
operator and the usage of the " .
" (dot) placeholder. As a simple example the following code works
library(magrittr)
library(ensurer)
ensure_data.frame <- ensures_that(is.data.frame(.))
data.frame(x = 5) %>% ensure_data.frame
However the following code fails
ensure_data.frame <- ensures_that(. %>% is.data.frame)
data.frame(x = 5) %>% ensure_data.frame
where I am now piping the placeholder into the is.data.frame method.
I am guessing that it is my understanding of the limitations/interpretation of the dot placeholder that is lagging, but can anyone clarify this?
The dot is called a placeholder and is telling the pipe operator to put the second argument there. So remember, the pipe automatically puts the code produced on the left-hand side of the pipe operator as a first argument into the following function on the right-hand side.
What does the pipe do? The pipe operator, written as %>% , has been a longstanding feature of the magrittr package for R. It takes the output of one function and passes it into another function as an argument. This allows us to link a sequence of analysis steps.
The magrittr (to be pronounced with a sophisticated french accent) package has two aims: decrease development time and improve readability and maintainability of code. Or even shortr: make your code smokin' (puff puff)!
The pipe operator is used to execute multiple operations that are in sequence requiring the output of the previous operation as their input argument. So, the execution starts from the left-hand side with the data as the first argument that is passed to the function on its right and so on.
The "problem" is that magrittr has a short-hand notation for anonymous functions:
. %>% is.data.frame
is roughly the same as
function(.) is.data.frame(.)
In other words, when the dot is the (left-most) left-hand side, the pipe has special behaviour.
You can escape the behaviour in a few ways, e.g.
(.) %>% is.data.frame
or any other way where the LHS is not identical to .
In this particular example, this may seem as undesirable behaviuour, but commonly in examples like this there's really no need to pipe the first expression, so is.data.frame(.)
is as expressive as . %>% is.data.frame
, and
examples like
data %>%
some_action %>%
lapply(. %>% some_other_action %>% final_action)
can be argued to be clearner than
data %>%
some_action %>%
lapply(function(.) final_action(some_other_action(.)))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With