0

I noticed that some answers on SO contain the use of pkg::name where name is typically a function.

What is the advantage of this over library(pkg); ... name() or require(pkg); ... name()? R help, (help("::")) says

For a package pkg, pkg::name returns the value of the exported variable name in namespace pkg, ... The namespace will be loaded if it was not loaded before the call, but the package will not be attached to the search path.

Does this mean that the function is used without the additional memory loss of loading the entire package, (ie, is it equivalent to import <function> from <package>) in python? Or is it simply a means of telling R use the function from this package when there may be ambiguities?

My question relates the use of :: in an Rscript or directly in the console and so is not a duplicate of the linked question as the OP in that question is discussing the use of of functions from the stats4 package during a package development project. On the other hand, there appear to be answers within this post that shed some light on my question, however. Thanks for the link. (Note the following discussion on Meta: duplicates flag)

Community
  • 1
  • 1
lmo
  • 37,904
  • 9
  • 56
  • 69
  • @kristang My question is not really a duplicate of the linked question as the OP in that question is discussing the use of of functions from the `stats4` package during a package development project. On the other hand, there appear to be answers within this post that shed some light on my question, however. Thanks for the link. – lmo Apr 20 '16 at 14:15
  • 3
    Using `::` will disambiguate functions that have the same name in multiple packages, whereas normally the function from the most recently loaded package would be used. For example, `library(pryr); library(data.table)`: *"The following object is masked from ‘package:data.table’: address"*. In this case it won't really matter because the `address` function provided by each of these packages does essentially the same thing, but that is not always the case. Any memory or performance difference between `library(pkg)` vs `pkg::fun` is most likely insignificant. – nrussell Apr 20 '16 at 14:15
  • 1
    A relevant [discussion](http://r-pkgs.had.co.nz/namespace.html) of the topic. – nrussell Apr 20 '16 at 14:19
  • @nrussell So is disambiguation the only use of `::`? Is there a memory saving component as in the python example, or does using `pkg::name` load the entire package into memory. Thanks for the link. I'll take a look. – lmo Apr 20 '16 at 14:20
  • 3
    I've never heard of anyone using `::` in order to minimize R's memory footprint. The reasons are typically disambiguation and code clarity. – joran Apr 20 '16 at 14:34

2 Answers2

4

It avoids namespace collisions but it still has to load the pkg.

Example => I did this:

pryr::mem_used()
dplyr::filter(mtcars, cyl==4)
pryr::mem_used()

in one R instance and:

pryr::mem_used()
library(dplyr)
filter(mtcars, cyl==4)
pryr::mem_used()

in another.

mem before/after for the 1st was: 27.7 MB / 30.6 MB mem before/after for the 2nd was: 27.7 MB / 30.7 MB

I didn't do multiple tests or see if the difference was rounding or something else, but no there were no real savings there IMO.

hrbrmstr
  • 77,368
  • 11
  • 139
  • 205
4

There are two main reasons why I use this notation:

  • Disambiguation: Some packages provide functions that have the same name as those of base R or of functions from other packages. Loading such libraries therefore replaces certain functions. This effect is referred to as "masking". In such cases I consider it a better way of coding to use the notation package::function(), in order to clarify which of the homonymous functions is used - even if it is the function that has been loaded most recently into the namespace and it is therefore not necessary for obtaining the desired output. If a function is masked by another package it is the only way to address it.

    For example, library(raster) contains (and loads into the namespace) a function called stack() which is different from the base R function stack() in the utils package. In order to still use the function stack() from base R it should be called with utils::stack() once the raster library has been loaded.

  • Accessing functions that are not exported into the namespace: This case is much less frequent and slightly different. Some libraries foo.pkg contain functions which are not loaded into the namespace with library(foo.pkg). As a result, in such cases library(foo.pkg) does not help in order to access these functions.

    The only example where I encounter this situation on a regular basis is the quite useful function cbind.na() from the qpcR package. It can only be accessed by specifying qpcR:::cbind.na(). Note that three colons are required in this case.

Upon reconsideration, there could also be a third reason for me to use this notation: code compactness. If I know that I will only need one specific function of a package, possibly only once in the code, without being interested in the rest of the functionalities offered by that package, then I find that the notation package::function() is preferable. This may not give any tangible advantage in R, but I adopted this style from the general advice in other programming languages to avoid namespace pollution.

Community
  • 1
  • 1
RHertel
  • 23,412
  • 5
  • 38
  • 64