In python I can load a specific function or functionality with:
from x import y as z
How can I replicate this in R?
For instance, I want to load just the count
function from plyr
,
instead of loading the entire package with library(plyr)
In python I can load a specific function or functionality with:
from x import y as z
How can I replicate this in R?
For instance, I want to load just the count
function from plyr
,
instead of loading the entire package with library(plyr)
I'd probably just do count <- plyr::count
, so I wouldn't have to bother with ensuring I get the arguments correct.
And you might want to wrap that definition in an if statement, in case plyr isn't installed:
if (requireNamespace("plyr"))
count <- plyr::count
else
stop("plyr is not installed.")
Also you might be interested in the import and/or modules packages, which provide python-like import/module mechanisms for R.
Also heed the warning from the Adding new generics section of Writing R Extensions (original emphasis):
Earlier versions of this manual suggested assigning
foo.default <- base::foo
. This is not a good idea, as it captures the base function at the time of [package] installation and it might be changed as R is patched or updated.
So it would be okay to use the count <- plyr::count
syntax if it's defined in a script you're source
ing, but you should explicitly define a new function and specify all the arguments if you do this in a package.
from plyr import count as count
could look like this:
count <- function(x) {
plyr::count(x)
}
Simplified:
count <- plyr::count
More complete:
if (requireNamespace("plyr"))
count <- plyr::count
EDIT:
I was inspired by @eipi10's comment. I was unaware of ::
Thanks @Joshua Ulrich for the suggestions!
There is no directly equivalent functionality in R, though as the other answers have noted, you can obtain similar results.
The library
argument both loads the package namespace and attaches it to the search list. As noted by Joshua Ulrich it is possible to load a package namespace without attaching the namespace to the search list. Using library
actually calls both loadNamespace
and attachNamespace
.
The distinction of loading vs. attaching is best explained by someone who has extensive package development expertise (the aforementioned Mr. Ulrich comes to mind) so I suggest reading further in this write-up on namespaces by Hadley Wickham.
Worth noting, however, is that you can use the pos
argument in library()
to define where you are attaching the package namespace, as explained in the documentation for the library statement.
I just stumbled across this question looking for the same functionality and using the approach described above, wrote a quick function to generalize the idea. I wanted to post it here for anyone who came across this question in the future.
import <- function(pkg, f) {
if (pkg %in% installed.packages()) {
assign(f, eval(parse(text = paste(pkg, "::", f, sep = ""))), envir = .GlobalEnv)
} else {
stop(paste(pkg, "is not installed."))
}
}
You can use the built-in library()
function with the include.only
parameter.
library(plyr, include.only = c("count"))
# Okay
count(mtcars, vars = "cyl")
#> cyl freq
#> 1 4 11
#> 2 6 7
#> 3 8 14
# Fails to find plyr::arrange()
arrange(mtcars, cyl, disp)
#> Error in arrange(mtcars, cyl, disp): could not find function "arrange"
Created on 2021-02-09 by the reprex package (v0.3.0)
There’s now a package which provides this exact functionality: ‘box’.1 With it, the R equivalent of Python’s from x import y as z
is:
box::use(x[z = y])
For instance, I want to load just the
count
function fromplyr
, instead of loading the entire package withlibrary(plyr)
box::use(plyr[count])
It’s also worth noting that, unlike library()
, box::use()
attaches names locally. For example, to attach all names of a package inside a function without affecting the global search path, you can write
f = function () {
box::use(plyr[...])
# use it here.
}
([...]
is tells box::use()
to attach all names.)
It’s worth noting that as of R 3.6, library
also supports attaching only specified names:
library(plyr, include.only = 'count')
However, this still performs global attaching, it doesn’t allow aliases (i.e. I can’t import plyr::count
as, say, plyr_count
), and calling library
repeatedly with the same package name but different include.only
lists doesn’t work (subsequent calls have no effect). In other words, it does strictly less than the Python import
mechanism or box::use()
.
1 This package is the successor to the ‘modules’ package mentioned in Joshua’s answer, but it uses a completely different syntax and has more features.