Professional Documents
Culture Documents
How R Packages Call Other Packages
How R Packages Call Other Packages
(https://twitter.com/intent/tweet?text=Package%20Building%3a%20How%20%60DESCRIPTION
%60%2c%20%60NAMESPACE%60%2c%20%60roxygen%60%2c%20and%20%60devtools
%3a%3adocument%60%20work%20together&url=%2f2019%2f02%2f12%2fpackage-building-
description-namespace%2f)
(https://www.facebook.com/sharer.php?u=%2f2019%2f02%2f12%2fpackage-building-description-
namespace%2f)
(https://www.linkedin.com/shareArticle?mini=true&url=%2f2019%2f02%2f12%2fpackage-building-
description-namespace%2f&title=Package%20Building%3a%20How%20%60DESCRIPTION%60%2c
%20%60NAMESPACE%60%2c%20%60roxygen%60%2c%20and%20%60devtools%3a%3adocument
%60%20work%20together)
(http://service.weibo.com/share/share.php?url=%2f2019%2f02%2f12%2fpackage-building-
description-namespace%2f&title=Package%20Building%3a%20How%20%60DESCRIPTION%60%2c
%20%60NAMESPACE%60%2c%20%60roxygen%60%2c%20and%20%60devtools%3a%3adocument
%60%20work%20together)
(mailto:?subject=Package%20Building%3a%20How%20%60DESCRIPTION%60%2c
%20%60NAMESPACE%60%2c%20%60roxygen%60%2c%20and%20%60devtools%3a%3adocument
1 of 9 11/21/20, 11:43 PM
Package Building: How `DESCRIPTION`, `NAMESPAC... https://laderast.github.io/2019/02/12/package-building...
%60%20work%20together&body=%2f2019%2f02%2f12%2fpackage-building-description-
As part of my new year’s resolution to learn new things about R, I’m trying to plug some
holes in my R knowledge by writing more vignettes to explain them to myself this year.
This week I �nally think I understand more about namespaces in R and why you should use
them in your R package.
What happens when you call library on both of these packages? The worst case scenario
is that you mean to call one package function and R executes the other one. This is called a
namespace collision, and unfortunately it can break your code.
Enter the namespace, which allows us to be package and function speci�c. If I want to use
the function filter from dplyr , I write it as dplyr::filter . The dplyr:: part is the
namespace of the dplyr package.
2 of 9 11/21/20, 11:43 PM
Package Building: How `DESCRIPTION`, `NAMESPAC... https://laderast.github.io/2019/02/12/package-building...
Package: burro
Type: Package
Title: Shiny App Package for setting up a data exploration session ("burro"w
into the data)
Version: 0.1.0
Authors@R: as.person(c(
"Ted Laderas <tedladeras@gmail.com> [aut, cre]",
"Jessica Minnier <minnier@ohsu.edu> [ctb]",
"Gabrielle Choonoo <choonoo@ohsu.edu> [ctb]"
))
Maintainer: Ted Laderas <ted.laderas@gmail.com>
Description: Allows the teacher to deploy a simple data exploration app for e
xploring a dataset (mostly for teaching purposes).
License: MIT LICENSE
Encoding: UTF-8
LazyData: true
Imports:
dplyr,
shinydashboard,
ggplot2,
visdat,
skimr,
naniar,
data.table,
magrittr,
glue,
usethis,
here,
viridis,
DT
Depends:
shiny
Roxygen: list(markdown = TRUE)
RoxygenNote: 6.1.0
Suggests:
testthat
Look at the Imports: �eld. You can see a list of all of the packages that burro utilizes. In
ye olde days of R, we used the Depends: �eld. Nowadays we use the Imports: �elds.
Here’s a Stack Over�ow post explaining why (https://stackover�ow.com/questions/8637993
/better-explanation-of-when-to-use-imports-depends). The main reason is that Imports:
requires the package to have a namespace.
Modifying the DESCRIPTION �le by hand is possible, but I don’t recommend it. Instead, you
can use the usethis package to modify it. For example, if I want to use dplyr in my
package I can do this in the console, while I am building it.
usethis::use_package("dplyr")
3 of 9 11/21/20, 11:43 PM
Package Building: How `DESCRIPTION`, `NAMESPAC... https://laderast.github.io/2019/02/12/package-building...
This will add dplyr to the Imports: �eld of your DESCRIPTION �le.
Addition (Thanks Hao Ye, for the suggestion): If the function is in a development version
(i.e., hosted on GitHub), you can use usethis::use_dev_package() to add it to your
DESCRIPTION �le. It will add an additional �eld called Remotes: to your package:
usethis::use_dev_package("tidyverse∕dplyr")
For more info about using remotes, check out the vignette: https://remotes.r-lib.org/articles
/dependencies.html (https://remotes.r-lib.org/articles/dependencies.html)
In many cases, calling a function by specifying its namespace is good practice. For one,
there are many functions called filter() : I can think of at least the ones that are in base
and dplyr . Using the namespace makes it unambiguous to both R and other developers
which filter() function you’re talking about.
roxygen docstrings are responsible for at least three things in your package: 1) producing
the documentation ( .Rd ) �les, but also: 2) specifying what package namespaces you want
to utilize, or import in your function, and 3) whether you want to export that function (i.e.,
make it accessible publicly).
How do they accomplish 2)? When you call devtools::document() to build the
documentation, they scan for multiple �elds, such as @import and @importFrom in the
4 of 9 11/21/20, 11:43 PM
Package Building: How `DESCRIPTION`, `NAMESPAC... https://laderast.github.io/2019/02/12/package-building...
roxygen doc strings. Then devtools::document() actually modi�es the NAMESPACE �le
in your package.
And then you can just use filter() like normal in your code:
#' @importFrom dplyr filter #This is where you add the @importFrom
use_filter <- function(df, cutoff=0.5) {
#` @import shiny
5 of 9 11/21/20, 11:43 PM
Package Building: How `DESCRIPTION`, `NAMESPAC... https://laderast.github.io/2019/02/12/package-building...
developers may add a function down the line that might collide. So, if you need to use
multiple packages, @import one package and use @importsFrom or namespaces to refer
to functions in the other packages.
If our package name is mypackage , then this function will be accessible if we use
library(mypackage) or mypackage::use_filter() .
Why is this important? You may write some internal functions that are useful in your
package, but they aren’t necessarily ones you want your users to use in their daily use.
@export allows you to control which functions you make publicly accessible in your
package.
For example, try typing dplyr:: in RStudio and hit the tab key. You’ll see the usual dplyr
verbs pop up. But these are only the exported functions. Now try dplyr::: and hit the tab
key. You’ll see a list of functions that pop up that’s much longer - these are all the functions,
including the internal functions.
So, if there’s a cool bit of internal code you want to use in a package, you can use ‘:::’ to
specify it. Just be aware that oftentimes, internal functions may change a lot as code gets
refactored, so code that utilizes them may be refactored.
You can also modify your Project Options for your package and check the Tools >> Project
6 of 9 11/21/20, 11:43 PM
Package Building: How `DESCRIPTION`, `NAMESPAC... https://laderast.github.io/2019/02/12/package-building...
Options >> Build Tools >> Generate Documentation with Roxygen box. Next to it, there is
also a Configure button that lets you select the option to run devtools::document()
whenever you build a package for testing.
7 of 9 11/21/20, 11:43 PM
Package Building: How `DESCRIPTION`, `NAMESPAC... https://laderast.github.io/2019/02/12/package-building...
TL;DR:
I hope this helps you to understand exactly the relationships between all of the components
that are responsible for accessing namespaces in your package. I was confused about this
for years, so writing this has helped me understand these relationships.
Further Reading
If you want to know how R searches for a function across its environments and why
namespaces are a good thing, this is an excellent writeup:
http://blog.obeautifulcode.com/R/How-R-Searches-And-Finds-Stuff/
(http://blog.obeautifulcode.com/R/How-R-Searches-And-Finds-Stuff/)
More about the usethis work�ow: https://www.hvitfeldt.me/blog/usethis-work�ow-
for-package-development/ (https://www.hvitfeldt.me/blog/usethis-work�ow-for-
package-development/)
More about the DESCRIPTION �le: http://r-pkgs.had.co.nz/description.html (http://r-
pkgs.had.co.nz/description.html)
More about namespaces: http://r-pkgs.had.co.nz/namespace.html (http://r-
pkgs.had.co.nz/namespace.html)
More about roxygen: http://r-pkgs.had.co.nz/man.html#roxygen-comments (http://r-
pkgs.had.co.nz/man.html#roxygen-comments)
An alternative work�ow to modify the DESCRIPTION �le: You can use
attachment::att_to_description() to scan code and add packages to the �le
after coding (thanks, Sébastien!).
Acknowledgements
8 of 9 11/21/20, 11:43 PM
Package Building: How `DESCRIPTION`, `NAMESPAC... https://laderast.github.io/2019/02/12/package-building...
Thanks to Hao Ye, Sébastien Rochette, Michael Chirico, Tim Hesterberg, and Hadley
Wickham for their comments and questions. I’ve incorporated your suggestions.
Note
I want this to be clear and correct. Please email me (mailto:laderast@ohsu.edu) if there are
any mistakes I’ve made.
devtools (/tags/devtools)
Related
Things we learned teaching clinical data wrangling (/2018/10/15/clinical-data-
wrangling/)
A gRadual Introduction to Shiny (/2018/01/24/gradual-introduction-to-shiny/)
Clinical Data Wrangling Workshop (/teaching/clinical_wrangling/)
Introduction to igraph (/teaching/igraph_tutorial/)
Data Analytics (/teaching/data_analytics/)
9 of 9 11/21/20, 11:43 PM