2

I would like to load an entire package apart from one function.

I see workarounds such as How to load only specific functions from a package but this does not fulfil my full needs.

The specific problem is using loading the select() function within the MASS and tidyverse packages but I would like a more general solution.

Thank you.

Hector Haffenden
  • 1,360
  • 10
  • 25
  • 3
    You can't load only part of a package's namespace. But you can prefix functions with the package name to remove any ambiguity, i.e. `MASS::select` or `dplyr::select`. – joran Oct 22 '18 at 22:39
  • 2
    Is this in the context of a package or just a script? If the former, you can selectively import functions from packages, and whilst it might be tedious to go through everything and import it explicitly, it is good practice to do so. If the latter I don't believe this is possible so you should load the packages in the order that makes sense and then explicitly use `MASS::select()` each and every time you want to use that function. – Gavin Simpson Oct 22 '18 at 22:39

2 Answers2

5

There are three nice ways to do that, rising in difficulty:

1. conflicted

It checks for name conflicts and will prevent you from using masked or masking functions by throwing an error if you do. But you can declare a session-wide preference, e.g.:

conflict_prefer("filter", "dplyr")
#> [conflicted] Will prefer dplyr::filter over any other package

conflicted on Github

2. import

It allows you to explicitly import specific functions from packages (and give them a custom name, if you like)

import::from(ggplot2, g = ggplot, aes, geom_point)
g(iris, aes(Petal.Width, Petal.Length)) + geom_point()

import on Github

3. modules

It gives you a Python-esque way of importing both modules (written as R source files) and libraries and a more cohesive fashion. The nice (but advanced) thing is that modules, if they have subgroups, can be loaded partially, e.g. str = import('tools/strings'). This does not work for packages, however, as they are written as monoliths. modules has some advantages coding guideline wise, but will force you to write:

dplyr = import_package('dplyr')
cars %>% dplyr$filter(speed > 15)

modules on Github

Roman
  • 4,744
  • 2
  • 16
  • 58
1

If you do select <- MASS::select you should be fine.

If you really don't want it in your global workspace you could do, after attaching MASS (optionally), and dplyr :

attach(list(select=MASS::select),name = "front_select")

This way it will find this one before the others because the environment front_select will be met first in the search path.

That's not very orthodox though.

This is assuming you want this for interactive use, if not by all means use :: notation.


Actually what you're asking for is possible, though it's a lot of black wizardry, and I have a feeling I'll get downvoted for this, but this answers the question :

library(dplyr)
x <- as.list(as.environment("package:dplyr"))
detach("package:dplyr")
x$select <- NULL
attach(x,name = "package:dplyr")
mutate
# function (.data, ...) 
# {
#     UseMethod("mutate")
# }
# <bytecode: 0x00000000190069c0>
# <environment: namespace:dplyr>

select
# Error: object 'select' not found

from ?search :

Names starting "package:" are reserved for library and should not be used by end users.

moodymudskipper
  • 46,417
  • 11
  • 121
  • 167