This doesn't work unless the code using the package has loaded magrittr.
What is the syntax for doing this so that the package does not depend on magrittr?
Here are some details...
A package cannot depend on a library being loaded, it must just import the library in it's DESCRIPTION file. This isn't a problem for functions because the package name can be used to scope the function as it is for purrr::flatten in the example above.
However the syntax to scope a user defined operator isn't obvious (to me :-()
What is the syntax to scope operators like %>%?
For example this, and a number of variations, does not work
Alternatively, you could potentially define a new %>% function in your package that just passes arguments along to magrittr::`%>%`. As far as I can tell, there is no way to use a function referenced with the :: operator in an infix manner (and of course, not using %>% as an infix operator defeats the point).
Thanks @mara, @nick. Updating the IMPORTS file to importFrom(magrittr,"%>%") fixes the problem but....
This won't work if I want to use %>% from more than one namespace. I don't need to for the particular package I am working on but I would l like is a more general solution.
But as @nick points out there doesn't seem to be a way to scope the namespace of an infix operator, so importFrom() is the only solution available and I'll have to use @nick 's suggestion of wrapper function if I run into the problem of colliding infix operators.
I knew when I first saw the comment "Everything in R is a function..." there had to be a catch... just kidding I'm really liking R the more I dig into it. And it looks like I will have to dig into user defined operators and namespaces a bit more.
Note that @nick said that there isn't a way to incorporate the namespace when the operator is used in an infix manner. You should be able to use the same function name (which is what an infix operator is) from more than one namespace, so long is it's qualified by ::.
As in work regardless of whether the user has magrittr loaded, not the formal DESCRIPTION Depends, correct? If the former, @mara's solution—or quite likely the roxygen2 equivalent:
#' @importFrom magrittr "%>%"
—will work. If the latter, magrittr needs to end up in Imports unless you deliberately want to auto-load the whole package for users by putting it in Depends (likely a bad idea due to name clashes). If you want to avoid any dependency, well, you'd have to rewrite the functionality, which would be a waste of effort.
In practice, %>% tends to be re-exported, which can be done in a couple ways, e.g. dplyr/R/utils.r's concise
I did look at that but magrittr::%>%(lhs, rhs) isn't as easy to use as just passing in what is on either side of the operator.
I had hoped something as simple as
`%m>%` <- function (lhs, rhs) {
magrittr::`%>%`(lhs, rhs)
}
would work and let me have an alias for the operator but it didn't because the operators in magrittr are doing some clever code interpretation, I think.
I looked at the source for %>% but didn't take the time to fully understand it and figure out what is really needed.
Just using the magrittr::%>%(lhs,rhs) on it's own, even if it did work, would kinda' kill the idea of using fluent programming which is what I was going for. C# LINQ supports supports this and it really makes things a lot more readable (once the syntax sinks in) when you have to pour data into sequence of functions.
The solution from @alistaire basically summarizes how this is handled within tidyverse packages, which often import and re-export the %>% for the user's convenience. They are less likely to actually use the pipe internally.
usethis::use_pipe() does the necessary mechanics (caveat: usethis isn't on CRAN yet, but will be). That's about as close as you'll get to an "official" solution.
Maybe I've missed something in the impl but the suggestion for the alias doesn't seem to work, it doesn't process the rhs properly.
And here is some code to impl and try it out... note that in the package I am working on everything prefaced by hd_ is exported. So this example code is inside the package I am working on.
@mara 's suggestion to importFrom(magrittr,"%>%") in the NAMESPACE file works as expected for what I'm trying to do. Sorry I wasn't clear in my explanation.
I'm using %>% inside my package, in it's impl,. I've no need to export it for the user of the package.
My comment
"This won’t work if I want to use %>% from more than one namespace"
was just a hypothetical about how to disambiguate inline operators from with the same name but from different namespaces. I don't need to somehow export functions from two different namespaces as is possible in, for example, C# or C++.