rr-packageroxygen2

Adding dependencies properly to an r package, so that they install automatically


I'm making my first R package, and I'm trying to include package dependencies. The package installs and works fine on my machine, but I already have all of the dependencies installed. When another user attempts to install and they do not have all the dependencies already installed, they get an error.

ERROR: dependency 'dplyr' is not available for package 'my_package'

I am documenting the package via roxygen2.

I know I'm supposed to include #'@import lines in my /R files, and they get added automatically to the DESCRIPTION and NAMESPACE files.

My DESCRIPTION file looks like this:

Package: my_package
Title: What the Package Does (one line, title case)
Version: 0.0.0.9000
Authors@R: person("First", "Last", email = "first.last@example.com", role = c("aut", "cre"))
Description: What the package does (one paragraph).
Depends: R (>= 3.4.1)
License: What license is it under?
Encoding: UTF-8
LazyData: true
RoxygenNote: 6.0.1
Imports: dplyr,
    descr

And my NAMESPACE looks like this:

export(my_function)
import(descr)
import(dplyr)

The user is installing the package locally with:

install.packages("C:/custom_packages/my_package_0.0.0.9000.tar.gz/", repos = NULL, type = "source")

Answers I've read on this topic say that having the proper import statements in the DESCRIPTION and NAMESPACE should be all you need to document dependencies, which I have here. The behavior for most CRAN packages I've installed is that if there is a dependency that is not installed, it installs along with the installation. What steps am I missing so that my package mimics this behavior?


Solution

  • A good strategy when it comes to developing your first packages is, in my experience, checking the work of others. The easiest way to do that is to check some of your favorite packages on Github. Here is, for example, a part of one of my DESCRIPTION files:

    Depends: 
      R (>= 3.3.0)
    License: GPL-3
    Imports: 
      stringi (>= 1.1.7), 
      data.table (>= 1.10.4.3),
      methods (>= 3.3.0),
      quanteda (>= 1.1.0),
      scales (>= 0.5.0),
      stats (>= 3.3.0),
      utils (>= 3.3.0)
    

    As you can see, every package has a minimal version (most of them are simply the versions I use but for some, I tested if older versions work). And I use Imports to mark packages and Depends only to indicate the oldest R version which I successfully tested. You should almost always use Imports or Suggests instead of Depends for packages.

    Once you have set this up, you can run:

    # This should point to the folder of your DESCRIPTION file    
    setwd("/path/to/your/package/")  
    roxygen2::roxygenise(clean = TRUE)
    

    Do not alter the NAMESPACE directly! This should be enough to install your package or put it on GitHub.

    However, this is just the tip of the iceberg and it would probably be a good idea to check this post out and then read up on the details in this book.

    Update: Given the comment from @Benjamin, I see that I have missed one part of your question. repos = NULL, type = "source" suppresses the installation of dependencies. A better way would be to use devtools. I'm not sure if this is the correct way, but when I already have a tarball and need to install it I use something like:

    # In Windows use copy and paste directly on the file to get a link  
    devtools::install_url("C:/custom_packages/my_package_0.0.0.9000.tar.gz")
    

    Update 2024

    Since I wrote this in 2018, there have been some developments. I now never define a minimal version, unless someone points out that there is an issue with an older version. I'm follwing a wider trend here, as nobody seems to be doing that anymore. Second, I now use usethisextensivly for development. For the question here, the function usethis::use_package() does everything for you. This chapter walks you through the whole game: https://r-pkgs.org/whole-game.html