"import as" in R
Is there a way to import a package with another name in R, the way you might with import as
in Python, e.g. import numpy as np
? I've been starting to use package::function
lately to avoid conflicts between, say, Hmisc::summarize
and plyr::summarize
.
I'd like to be able to instead write h::summarize
and p::summarize
, respectively. Is this possible in R?
This is not quite what you want because it involves changing from ::
notation to $
notation, but if you load a package namespace (without attaching it), you can then refer to it by its environment name:
h <- loadNamespace('Hmisc')
p <- loadNamespace('plyr')
> summarize(iris$Sepal.Length, iris$Species, FUN=mean)
Error: could not find function "summarize"
> Hmisc::summarize(iris$Sepal.Length, iris$Species, FUN=mean)
iris$Species iris$Sepal.Length
1 setosa 5.006
2 versicolor 5.936
3 virginica 6.588
> h$summarize(iris$Sepal.Length, iris$Species, FUN=mean)
iris$Species iris$Sepal.Length
1 setosa 5.006
2 versicolor 5.936
3 virginica 6.588
> summarise(iris, x = mean(Sepal.Length))
Error: could not find function "summarise"
> plyr::summarise(iris, x = mean(Sepal.Length))
x
1 5.843333
> p$summarise(iris, x = mean(Sepal.Length))
x
1 5.843333
Note, however, that you do lose access to documentation files using the standard ?
notation (e.g., ? p$summarise
does not work). So, it will serve you well as shorthand, but may not be great for interactive use since you'll still have to resort to ? plyr::summarise
for that.
Note also that you do not have access to the data objects stored in the package using this approach.
Here's a solution that should only be used for interactive mode. You modify ::
so that it can accept character package names, then write a function to register the aliases.
`::` <- function(pkg, name) {
sym <- as.character(substitute(pkg))
pkg <- tryCatch(get(sym, envir=.GlobalEnv), error=function(e) sym)
name <- as.character(substitute(name))
getExportedValue(pkg, name)
}
pkg.alias <- function(alias, package) {
assign(alias, package, .GlobalEnv)
lockBinding(alias, .GlobalEnv)
}
pkg.alias('r', 'reshape2')
r::dcast
But instead of using aliases, you could also redefine ::
to find the package that matches your abbreviation:
`::` <- function(pkg, name) {
pkg <- as.character(substitute(pkg))
pkg <- installed.packages()[grepl(paste0('^', pkg), installed.packages())]
name <- as.character(substitute(name))
getExportedValue(pkg, name)
}
ggp::ggplot
Rather than aliasing the package, why not just alias the function?
hsumm <- Hmisc::summarize
dsumm <- dplyr::summarize
psumm <- plyr::summarize
I was starting down an eval(parse())
path, but I ran into trouble and need to get back to work. @Thomas's answer seems to get a similar result in a much smoother way, but here's the non-working draft.
package_alias <- function(package, alias, infix = "..") {
funs <- ls(paste0("package:", package))
for (i in seq_along(funs)) {
assign(paste0(alias, infix, funs[i]),
value = eval(parse(text = funs[i])), envir = .GlobalEnv)
}
}
With the idea that you could do something like
package_alias("plyr", "p")
to create p..ddply
, etc.
Use the namespace package to generate another namespace aliased to the one you are interested in.
library(namespace)
registerNamespace('ggp', loadNamespace('ggplot2'))
data(iris)
ggp::ggplot(iris, ggp::aes(x = Petal.Length, y = Sepal.Length)) + ggp::geom_point()
Note this has the disadvantage of making the package versioning/installation requirements more opaque for scripts.
Too long to fit nicely in comment box, so pseudo-answer:
If it's only a few (or few dozen) functions, how about an override wrapper function, e.g.
summarize<-function(whichone='h',//all variables for either "summarize"// ) {
switch(whichone,
'h' = Hmisc::summarize(//all the appropriate variables//),
'p' = plyr:: summarize(//all the appropriate variables//)
)
}