I like the pipe (in dplyr or magrittr as mentioned in the comments) a lot but sometimes I run into errors which show me that I lack some understanding. In case of other functions or operators I mostly have at least some idea how they may be defined, but in case of the pipe I do not have even a clue where to start if I want to define it.
I am really curious how the pipe is defined. So far I simply tried to assign it to an own operator but even this does not work. See here:
library(dplyr)
`%pipe%` <- `%>%`
data.frame() %pipe% class(.)
# gives an error: subscript out of bounds
What magical ingredients make a pipe work? How could we define it ourselves? Thanks.
magrittr's code itself checks if the pipe you used is named as one of the few allowed names, as seen at the top here: https://github.com/tidyverse/magrittr/blob/master/R/is_something.R .
In fact all pipes have the same code, copied from magrittr:::pipe
as seen as the bottom of this script :
https://github.com/tidyverse/magrittr/blob/master/R/pipe.R
The behavior depends on the name of the pipe, it's really odd and I've never seen this anywhere else.
I'll try to make it less confusing by inventing a fake function behaving likewise, forgive the silliness of the example.
concat <- function(x,y) {
# extract quoted function name from call
fun <- sys.call()[[1]]
# check if it's one of our possible names, and act accordingly
if(identical(fun, quote(`%upconcat>%`))) {
return(toupper(paste0(x,y)))
}
if(identical(fun, quote(`%lowconcat>%`))) {
return(tolower(paste0(x,y)))
}
stop("Unsupported operator!")
}
`%upconcat>%` <- `%lowconcat>%` <- concat
"XoX" %upconcat>% "oXo"
#> [1] "XOXOXO"
"XoX" %lowconcat>% "oXo"
#> [1] "xoxoxo"
`%foo>%` <- `%upconcat>%`
"XoX" %foo>% "oXo"
#> Error in "XoX" %foo>% "oXo": Unsupported operator!
You see there's no way to copy the pipe unless you modify the is_pipe
function itself, which you can't do...
Just kidding, of course you can, but probably you shouldn't ?
library(magrittr)
is_pipe <- function(pipe) {
identical(pipe, quote(`%>%`)) ||
identical(pipe, quote(`%T>%`)) ||
identical(pipe, quote(`%<>%`)) ||
identical(pipe, quote(`%$%`)) ||
identical(pipe, quote(`%pipe%`)) # <- added line
}
assignInNamespace("is_pipe", is_pipe, "magrittr")
`%pipe%` <- `%>%`
data.frame() %pipe% class(.)
#> [1] "data.frame"
Created on 2020-05-29 by the reprex package (v0.3.0)