Importing two functions with same name using roxygen2
The thing to keep in mind is that you cannot have more than one function with
the same name in your package's namespace.
Suppose there are two packages, pkgA and pkgB, that both export a function
called foo. If you create a package, pkgC, that has import(pkgA)
and import(pkgB)
in the NAMESPACE. Now, when you call library(pkgC)
you'll get
a warning:
replacing previous import 'foo' when loading 'pkgB'.
Now, suppose someone creates another package, pkgD, that has this in the NAMESPACE file:
import(pkgA)
import(pkgB)
import(pkgC)
Then, library(pkgD
) will give 2 warnings:
1: replacing previous import ‘foo’ when loading ‘pkgB’
2: replacing previous import ‘foo’ when loading ‘pkgB’
If everyone adopts the practice of importing entire namespaces, then 30 years
from now, there will be a lot of these warnings.
Instead, since you can only have a single "foo" in your package, you should
explicitly import the "foo" (and other functions) that you want your package
to use. In the above example, the NAMESPACE for pkgD should be
importFrom(pkgB,foo)
If you actually need to use the two functions with the same name from two different packages, one hack you can perform is to import other functions from each package to ensure the packages are installed and their namespaces are loaded, but then refer to the functions you need using ::
notation by placing this in your NAMESPACE:
importFrom(pkgA,foo)
importFrom(pkgB,bar)
and then calling functions pkgA::abc()
and pkgB::abc()
in your code.
Same function but with two different names in an R package using roxygen2?
Use
#' @rdname first
#' @export
second <- first
Your example
So if first.R
initially looked like this
#' A function that adds 2
#' @name first
#' @usage first(x)
#' @param x a number
#' @export
first <- function(x) {
x + 2
}
Then simply include the extra lines of code like so (the last 3 lines are all that change)
#' A function that adds 2
#' @name first
#' @usage first(x)
#' @param x a number
#' @export
first <- function(x) {
x + 2
}
#' @rdname first
#' @export
second <- first
import the same PACKAGE in several R files
As mentioned in the comments, you only need to import it once, but importing it many times doesn't cause any problems.
If you don't want to import it in every function, but are worried about tying it to a single function (what if you only import it on function foo
, but later you decided to replace foo
with bar
and lose the import) you can add all your shared import statements to NULL
at the top of the document:
#' @import ggplot2
#' @import B
#' @import dplyr
NULL
roxygen2
will happily create the proper import statements in NAMESPACE
, but you'll only have the imports listed once in a convenient place without tying them to any particular package
R with roxygen2: How to use a single function from another package?
If ldply()
is important for your package's functionality, then you do want it in your package namespace. That is the point of namespace imports. Functions that you need, should be in the package namespace because this is where R will look first for the definition of functions, before then traversing the base namespace and the attached packages. It means that no matter what other packages are loaded or unloaded, attached or unattached, your package will always have access to that function. In such cases, use:
@importFrom plyr ldply
And you can just refer to ldply()
without the plyr::
prefix just as if it were another function in your package.
If ldply()
is not so important - perhaps it is called only once in a not commonly used function - then, Writing R Extensions 1.5.1 gives the following advice:
If a package only needs a few objects from another package it can use a fully qualified variable reference in the code instead of a formal import. A fully qualified reference to the function
f
in packagefoo
is of the formfoo::f
. This is slightly less efficient than a formal import and also loses the advantage of recording all dependencies in theNAMESPACE
file (but they still need to be recorded in theDESCRIPTION
file). Evaluatingfoo::f
will cause packagefoo
to be loaded, but not attached, if it was not loaded already—this can be an advantage in delaying the loading of a rarely used package.
(I think this advice is actually a little outdated because it is implying more separation between DESCRIPTION
and NAMESPACE
than currently exists.) It implies you should use @import plyr
and refer to the function as plyr::ldply()
. But in reality, it's actually suggesting something like putting plyr
in the Suggests
field of DESCRIPTION
, which isn't exactly accommodated by roxygen2 markup nor exactly compliant with R CMD check
.
In sum, the official line is that Hadley's advice (which you are quoting) is only preferred for rarely used functions from rarely used packages (and/or packages that take a considerable amount of time to load). Otherwise, just do @importFrom
like WRE advises:
Using
importFrom
selectively rather thanimport
is good practice and recommended notably when importing from packages with more than a dozen exports.
import all the functions of a package except one when building a package
The NAMESPACE file is somewhat flexible here, as described in Writing R Extensions.
The two main import directives are:
import(PACKAGE)
which imports all objects in the namespace into your package. The second option is to do specific imports using:
importFrom(PACKAGE, foo)
which gives you access to foo()
without needing the fully qualified reference PACKAGE::foo()
.
But these aren't the only two options. You can also use the except
argument to exclude just a handful of imports:
import(PACKAGE, except=c(foo,bar))
which gives you everything from PACKAGE's namespace but foo()
and bar()
. This is useful - as in your case - for avoiding conflicts.
For roxygen, great catch on figuring out that you can do:
#' @rawNamespace import(PACKAGE, except = foo)
to pass a raw NAMESPACE directive through roxygen.
Related Topics
Showing String in Formula and Not as Variable in Lm Fit
How to Fix Corrupted Dates in R
R Displays Numbers in Scientific Notation
Split a String by Any Number of Spaces
Show Names of Everything in a Package
Fast Levenshtein Distance in R
What's the Difference Between Integer Class and Numeric Class in R
Differencebetween Gc() and Rm()
R: Ggplot2, How to Set the Plot Title to Wrap Around and Shrink the Text to Fit the Plot
How to Sort a Data Frame by Date
How to Fix the Aspect Ratio in Ggplot
Way to Securely Give a Password to R Application from the Terminal
Add (Subtract) Months Without Exceeding the Last Day of the New Month
How to Get Coefficients and Their Confidence Intervals in Mixed Effects Models