Attach packages mindfully in R

Attach packages mindfully in RReduce conflicts and make your source code more concise and future safe with explicit namespacesAndré MüllerBlockedUnblockFollowFollowingJun 24R packages exporting the same symbol lead to conflicts when imported into the global namespace (Photo by Siala on pixabay)A common problem in R occurs when attaching several libraries at the top of your script by library() calls.

Loading all symbols into the global R environment often results in name conflicts.

The last imported package wins the fight — the order matters, by which libraries appear at the top of your script!R is a fast-growing language with a vivid community contributing countless packages (c.

f.

R Package Documentation).

Chances are that yesterdays script will not work tomorrow because an updated package now exports a function conflicting with another globally attached package.

So I propose here the mindful use of attaching packages into the global R environment.

Try to reduce library() calls and use requireNamespace() instead for other packages.

Use explicit namespaces likerequireNamespace("lubridate") # at the top of your file# .

some codelubridate::ymd(20190130)instead oflibrary(lubridate) # at the top of your file# .

some codeymd(20190130)The requireNamespace() loads the package leaving it in its own namespace.

The call yields an exception if the required package is missing.

This might seem to be awkward.

But: it makes the code more concise and is in other software development areas (e.

g.

Python) observed as a good habit.

Candidates for no global attachment might be sparsely used functions or packages leading to name conflicts.

Usually, I globally import packages with overloaded operators such as dplyr’s %>% operator.

Example: One of my script headers looks like this:library(dplyr)library(tidyr)library(readr)library(ggplot2)requireNamespace(“lubridate”)requireNamespace(“glue”)# here comes my codeLoad data from non-attached packages using the package argument of the data() call:requireNamespace("psd")data(magnet, package = "psd")Why requireNamespace() mattersThe drawback of not attaching packages at the top is that your script could encounter an error likeError in loadNamespace(name) : there is no package called ‘lubridate’in the depth of a rare program path if the current R installation is lacking the required package.

This is uncomfortable and surprising!Ensuring software integrity is challenging in dynamically typed languages like R or Python.

Compiled languages complain missing libraries earlier: upon compilation (if statically linked) or at least when starting the application (if dynamically linked).

Warning: Some R packages are not working without globally attaching their namespaces — so in these cases, you have to use library() instead.

One example with that problem is the psd package (v1.

2.

0):data(magnet, package = "psd")x <- magnet$cleanspec <- psd::pspectrum(x, plot = TRUE)gives the errorStage 0 est.

(pilot)environment ** .

psdEnv ** refresheddetrending (and demeaning)Error in psdcore.

default(as.

vector(X.

d), X.

frq = frq, .

) :!is.

null(ops) is not TRUEConclusionWrite robust and concise R scripts by using explicit namespaces.

Also, R scripts will be more readable by others: It is clear in which package a function is called!.. More details

Leave a Reply