Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove (or exclude) one function from imported package

Tags:

r

Is there a way to exclude a function from an imported package. For example, I use almost all of dplyr but recently, they added a new function called recode that overwrites a function that I have from a proprietary package (that I can't make changes to).

Is there a way to exclude the s3 function from the namespace so it only sees the function from my package and ignores the one from dplyr.

I'm aware that we can import one-off functions from a package with ease, but in this case, I'm looking to exclude - just one.

like image 303
Brandon Bertelsen Avatar asked Jul 10 '16 20:07

Brandon Bertelsen


4 Answers

R 3.3.0 or later now support "import all but x,y,z from foo" statements:

  \item The \code{import()} namespace directive now accepts an
  argument \code{except} which names symbols to exclude from the
  imports. The \code{except} expression should evaluate to a
  character vector (after substituting symbols for strings). See
  Writing R Extensions.

Methinks that is exactly what you want here, and want most people want who do not intend to have dplyr clobber over functions from the stats package included with R such as filter or lag.

Edited based on later discussion in comments:

Example usage example in file NAMESPACE per Section 1.5.1 of WRE is as follows:

import(dplyr, except = c(recode, lag, filter))
like image 199
Dirk Eddelbuettel Avatar answered Nov 10 '22 02:11

Dirk Eddelbuettel


The other alternative would be to use

recode <- SILLY_PROPRIETARY_PACKAGENAME::recode

at the head of your code (with an explanatory comment) to create a copy of recode in the global workspace (which should then mask the version from dplyr). This could prevent future confusion when you hand your code to someone who has the stock dplyr, rather than your personally hacked version, installed.

like image 44
Ben Bolker Avatar answered Nov 10 '22 03:11

Ben Bolker


Use the Hack-R version of dplyr instead of the Hadley version. Given that I created this in the past 2 minutes, you could also easily make your own version.

require(devtools)
install_github("hack-r/dplyr")
require(dplyr)

All I did was fork it, open the project in RStudio via version control, remove recode, commit, and push it back to my GitHub.

like image 24
Hack-R Avatar answered Nov 10 '22 04:11

Hack-R


It looks like library() gained this functionality in version 3.6, in the form of the exclude and include.only parameters.

See https://developer.r-project.org/Blog/public/2019/03/19/managing-search-path-conflicts/

library(digest, exclude="sha1")
digest(letters)
#> [1] "5cab7c8e9f3d7042d6146f98602c88d2"
sha1(letters)
#> Error in sha1(letters): could not find function "sha1"

or:

library(digest, include.only="sha1")
digest(letters)
#> Error in digest(letters): could not find function "digest"
sha1(letters)
#> [1] "005ae317c931561a05b53fcfa860d7ac61dfec85"

As compared to how it would appear without either of the options:

library(digest)
digest(letters)
#> [1] "5cab7c8e9f3d7042d6146f98602c88d2"
sha1(letters)
#> [1] "005ae317c931561a05b53fcfa860d7ac61dfec85"

Very neat!

(R.4.0.3 was used for the reprexes above)

like image 28
Magnus Avatar answered Nov 10 '22 04:11

Magnus