0

Using individual functions from an unloaded package

As time has gone by I find myself loading more and more packages at the beginning of an R session. Just loading the tidyverse loads more packages than used to be my norm. Because of this, I find myself increasingly likely to be hit by function name conflicts. Especially when I did not notice those conflicts during package loading these can create confusing results and strange errors. So I am wondering if I can, in general, just import the particular function I want to use, without loading the package from which it comes.

More precisely, if this_pack is a package that is locally installed but not loaded, and this_fn() is an exported function in this_pack, can I safely expect this_pack::this_fn() to work, and to work in the same way as it would if the entire package were loaded? I know it usually does, but I want to know if there are times I should expect it to fail.

See the answers to related questions for additional information:

I've accepted the answer of user2554330, which I think would not be an answer to the other questions referenced. Still, they provide interesting, and related, information on other reasons to or not to use ::, so I think keeping the cross-reference is probably a good idea. I've incorporated them above.

andrewH
  • 2,281
  • 2
  • 22
  • 32
  • The edge case is if that function calls another function that has a name conflict if the package maintainer there has not namespaced the functions used. That can cause problems though it is possible to get around them by importing them yourself. @DJV I don't think that's an exact duplicate. – Elin Jan 20 '19 at 16:16
  • @Elin, you're right, it's not an exact duplicate. I removed it. However, to some extent, I think it might answer some of the OP questions. https://stackoverflow.com/questions/23232791/is-it-a-good-practice-to-call-functions-in-a-package-via – DJV Jan 20 '19 at 16:29
  • 1
    Check out this related question: [«Load a package apart from one function»](https://stackoverflow.com/q/52938644/9406040). – Roman Jan 20 '19 at 16:42
  • To pythonify your imports, see [import](https://github.com/smbache/import) or [modules](https://github.com/klmr/modules) – alistaire Jan 20 '19 at 17:15
  • As for `::` failing, it really shouldn't, but occasionally does. One cause is package authors putting code in `.onAttach` that should be in `.onLoad`, or otherwise aggressively messing with the user environment. That shouldn't be too common, though. – alistaire Jan 20 '19 at 17:24
  • Possible duplicate of [Load a package apart from one function](https://stackoverflow.com/questions/52938644/load-a-package-apart-from-one-function) – Roman Jan 20 '19 at 21:11
  • @Roman I think this is the inverse of the question you link to. – Roman Luštrik Jan 20 '19 at 21:15
  • @RomanLustrik The title of the question is misleading. Check out the OP + answers. – Roman Jan 20 '19 at 21:25

1 Answers1

3

Yes, nowadays it should always be safe to call this_pack::this_fn(). If this_pack was not loaded, this will load it (all of it). (Remember that loading and attaching a package are different! Loading it gets it in memory, but not on the search list. Attaching it puts it on the search list.) This may make the first call a little slow, but the package will stay loaded, so subsequent calls will be faster. It used to be the case that evaluating :: took a noticeable amount of time in every call, but I think just-in-time compiling has mostly removed that. But if you want, you can get a local copy using

local_copy <- this_pack::this_fn

and then make calls to local_copy() without paying for the :: lookup again.

Since all packages have namespaces, any calls made by this_pack::this_fn() (or local_copy()) will go to the right place, unless the author of the package tries really hard to subvert the normal mechanisms.

If you are writing a package yourself, you can import just that one function. This will mean that loading your package will trigger a load of this_pack: so your load will be a bit slower, but the first call to this_fn() will be faster.

user2554330
  • 37,248
  • 4
  • 43
  • 90
  • this is a great answer, that answers more questions than I even knew I was ignorent about. In particular, although I knew about the difference between loading and attaching, I never actually did one without the other intentionally, or knew why I would. This makes it clear that I have already been doing sp without knowing it, and that I had a good reason to, without knowing that either, and finally, that I surely will many times in the future, except now I will know what I am doing and why. Bravo! – andrewH Jan 28 '19 at 01:35