Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R: How to best import infix operators like %>% into my package?

I am making an R-Package and I'm struggling with the import of infix functions like %>%, := or %dopar%.

In the DESCRIPTION-file I use the Imports: <otherPackage> (e.g. Imports: doParallel) notion. Within the code I use the package::function() (e.g. dplyr::mutate()) notion, which seems to work (R CMD check is pleased) but how do I import infix functions?

The @importFrom (e.g #' @importFrom magrittr %>%) roxygen way seems to work for %>%, := and %dopar%. But since it is copied over into the NAMSEPACE-file, adding the @importFrom to one function solves the problem package-wide, which seems rather "hacky".

What is the best practice to import such functions into my package?

like image 342
Someone2 Avatar asked Nov 20 '25 11:11

Someone2


1 Answers

I'm not sure if there's a single best practice in this case. Using @importFrom to update the NAMESPACE file is indeed to be a package-wide directive, but I've never come across a package that had problems with that, or reasons to avoid it. You can annotate several functions with the same @importFrom directive if you like, denoting which functions use which imports, and it won't cause any conflicts; it's entirely up to you though, a single one would suffice. Using @import might be frowned upon, but I think it really depends on which package you import.

From your question I gather you use :: explicitly (which I would personally say is good practice), and then you don't even need to alter the NAMESPACE. For most cases that would be just fine, though there can be very special cases that usually need to be considered individually. These special cases, at least in my experience, are usually related with S4 generics.

Take for instance the base::rowSums function: it is not a generic function in base, but if the Matrix package is attached, rowSums is "transformed" into an S4 generic, but the generic is not in the base package. Why that's the case is beyond the scope of this answer (see ?Methods_for_Nongenerics for more information), but it means that if your package uses the notation base::rowSums, it would not dispatch to methods from Matrix. The only way to support both cases (i.e. when Matrix is not used by the user and when it is) would be to use rowSums without base::.

Now, regarding infix operators, if you wanted to use ::, you'd need something like base::`%in%`("a", c("a", "b")), which essentially entails using it as a function and losing the infix syntax, something you probably don't want.

So unless you have very specific reasons to avoid one or the other, just use whatever notation you prefer. I'd personally stick to :: as much as possible, but would never use it for infix operators.

like image 107
Alexis Avatar answered Nov 23 '25 02:11

Alexis



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!