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?
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")
Related
I'm need to fix the Description file for an R package and I need to specify a specific version of imported package (i.e. Brobdingnag (>= 1.2-8) ).
But that version is not on Cran already (Cran has only up to 1.2-7) but is on github.
so I tried :
Imports:
Brobdingnag (>= 1.2-8)
Remotes:
RobinHankin/Brobdingnag
But I predictably get:
checking package dependencies ... ERROR
Package required and available but unsuitable version: ‘Brobdingnag’
And if I just use:
devtools::install_github("RobinHankin/Brobdingnag")
I get the 1.2-8 version without needing to specify it.
Any idea how to solve this ?
Thanks, David
I think specifying this would solve your problem
Imports:
Brobdingnag (>= 1.2.8)
Remotes:
RobinHankin/Brobdingnag#HEAD
I have a private package stored locally (and version-controlled via SVN). To install the package, I am asking the user to SVN-update his/her package directory, then setwd() on the directory, and then devtools::install().
This package imports many CRAN packages, which are not stored locally. These imported packages are not auto-installing during the installation, which produces the error message Dependency package foo not available. The user must manually install install.packages('foo'), then try again, only to get Dependency package bar not available, ad nauseam, even though foo and bar are among my Imports:
Details:
My DESCRIPTION file looks like:
Package: apackage
Type: Package
Title: Package to Do Stuff
Version: 1.11111
Date: 2017-03-02
Author: C8H10N4O2
Maintainer: C8H10N4O2<C8H10N4O2#example.com>
Description: Package that does many useful things
License: file LICENSE
Depends:
R (>= 3.3.0)
Imports:
bit64 (>= 0.9.5),
data.table (>= 1.9.6),
extrafont (>= 0.17),
foreach(>= 1.4.3),
ggplot2 (>= 2.0.0),
gbm (>= 2.1),
grid (>= 3.2.3),
gridExtra (>= 2.0.0),
httr (>= 1.1.0),
readxl (>= 0.1.1),
scales (>= 0.4.0),
xlsx (>= 0.5.7)
LazyData: true
RoxygenNote: 5.0.1
Suggests: testthat (>= 0.9.1)
But upon invoking check() or load_all() I still get the error:
Error in (function (dep_name, dep_ver = NA, dep_compare = NA) :
Dependency package gridExtra not available.
And then my user has to install.packages('gridExtra'), and then he/she gets another dependency not available error.
What I have tried:
According to R packages:
Imports: packages listed here must be present for your package to
work. In fact, any time your package is installed, those packages
will, if not already present, be installed on your computer
(devtools::load_all() also checks that the packages are installed).
I also checked Writing R Extensions but couldn't find anything else on this topic.
Am I correct that these packages should be auto-installing, and what should I do to ensure that they auto-install?
I recognize that the problem is not fully reproducible, but I can't link to my repo, so I'm happy to provide any additional details.
**versions**
R 3.4.0, platform = x86_64-w64-mingw32
devtools 1.13.1
You are reinventing packaging with R. I advise against. You could just drat to create a repository. This is tried and true and works.
And this deployment aspect, for both production of local packages as well as their use and installation is entirely orthogonal to where you keep sources. Don't mistake a source code repository for code distribution mechanism.
In sum, using drat locally along with local GitHub Enterprise instance has worked swimmingly for us at work, and drat in general is in fairly widespread use.
(Usual disclaimers as I am the one who started drat, but I had the good fortune of a bunch of contributors too.)
I am attempting to prepare a package for submission to the CRAN. In my DESCRIPTION file I include non-CRAN packages in the Depends and Suggests arguments. To tell R where to find the non-CRAN packages, I include the Additional_repositories argument; and I include an .onLoad function at the top of my program (i.e., in 'zzz.R'). I am able to build and check (--as-cran) in RStudio with zero warnings, notes or errors so long as all the Depends and Suggests packages are present. I then use devtools::build() to create a .tar.gz file locally.
To test for a successful local install, I remove the non-CRAN packages from my computer and attempt to install the .tar.gz file that I created. I then get the message:
ERROR: dependency 'smwrQW' is not available for package 'baytrends'
I've read through the
R package dependencies not installed from Additional_repositories
Include non-CRAN package in CRAN package
http://thecoatlessprofessor.com/programming/r-data-packages-in-external-data-repositories-using-the-additional_repositories-field/
How should I deal with "package 'xxx' is not available (for R version x.y.z)" warning?
Unfortunately, the above error continues. I'm confident of the url I'm using since the below install.package line works when run independently
install.packages('smwrQW',repos=c("http://owi.usgs.gov/R"),dependencies = TRUE)
The applicable bits of the DESCRIPTION and zzz.R file are below:
DESCRIPTION:
Date: 2017-03-15
Depends:
R (>= 3.2.0),
lubridate,
mgcv,
smwrQW
License: GPL-3
LazyData: TRUE
RoxygenNote: 6.0.1
Suggests:
dataRetrieval,
devtools,
fitdistrplus,
knitr,
nlme,
pander,
plyr,
rmarkdown,
smwrBase,
smwrGraphs,
smwrStats,
testthat
Additional_repositories: http://owi.usgs.gov/R
VignetteBuilder: knitr
zzz.R:
.onLoad <- function(libname = find.package("baytrends"), pkgname = "baytrends"){
repos = getOption("repos")
repos["USGS"] = "http://owi.usgs.gov/R"
options(repos = repos)
invisible(repos)
# declaration of global variables (https://stackoverflow.com/questions/9439256)
if(getRversion() >= "2.15.1")
utils::globalVariables(c("begin", "methodsList"))
invisible()
}
.onAttach <- function(libname = find.package("baytrends"), pkgname = "baytrends"){
packageStartupMessage("This software program is preliminary or provisional and is subject to revision. ")
}
You cannot have packages from non-standard repos in Depends: or Imports:.
You can have them in Suggests:
Several packages do this; one you could look at is hurricaneexposure which uses this to make a 'too-large-for-CRAN' data package hurricanexposuredata available from a repository created via drat.
So you must move the smwrQR package to Suggests: and then test for it.
Brooke and I have a draft paper (under review) on this which we could send you if you drop us line -- it details all this more than the short answer could.
Hi I am following the tutorial here from Hilary and here from Hadley Wickham trying to create a dummy package.
However, my package need some external dependencies XML and RCurl in this case, when I run the command document, it will complain that:
> setwd('/home/datafireball/projects/Rprojects/rgetout/rgetout')
> document()
Error: could not find function "document"
> library(devtools)
> document()
Updating rgetout documentation
Loading rgetout
Loading required namespace: XML
Error in (function (dep_name, dep_ver = NA, dep_compare = NA) :
Dependency package XML not available.
>
Here is my DESCRIPTION file.
Package: rgetout
Title: A R package to get all the outlinks for a given URL
Version: 0.1
Authors#R: "Eric Cartman <Eric.Cartman#gmail.com> [aut, cre]"
Description: This package is intended to include as much web extraction functionality as much as possible. It starts with one function. getout will extract
all the outlinks for a given URL with a user-agent that you can customize.
Depends: R (>= 3.0.2)
Imports:
XML,
RCurl
License: MIT
LazyData: true
Here is the source code github repo if you want to get more info.
If you are having problems with this, even when you have the packages installed and loaded, I suggest you to do the following.
Delete the Imports: and Suggests: entries of your DESCRIPTION file.
Make sure you have usethis working by doing library(usethis)
Now start adding the libraries to your DESCRIPTION file, by running the following command on your console: usethis::use_package("dplyr") for any Imports: you need. Repeat this step for every library that is required.
In my case, dplyr was the one refusing to load. You can decide where the package will be located by doing: usethis::use_package("dplyr", "Suggests").
It is assumed that you will have the required tools / dependencies for developing a package when you are
doing so.
utils::install.packages has a dependencies argument that will attempt to install uninstalled packages on which a package depends / (in whichever way they are dependent (suggests/ depends/linkingTo).
devtools::install_github will perform similarly.
Installing a package and documenting it as a component of development are quiet different activities
.
Although there are quite a few postings on similar topics, none of them helped me understanding how to setup the DESCRIPTION file an R package.
My questions are:
1.) Is my description file correct now? Did I use "depends" and "imports" correctly? (maybe duplicate question...)
2.) Are required packages (dependencies?) automatically installed along with my package when needed, or "loaded" when one of my package function needs to refer to a function of an imported package? (didn't find anything on this issue yet...)
I tried to submit a package to CRAN and got following feedback:
checking package dependencies ... NOTE
Depends: includes the non-default packages:
‘MASS’ ‘car’ ‘foreign’ ‘ggplot2’ ‘lmtest’ ‘plyr’ ‘reshape2’ ‘scales’
Adding so many packages to the search path is excessive and importing selectively is preferable.
I originally had listed all above mentioned packages in the depends section of the DESCRIPTION file. In the NAMESPACE file, I used import(pkgName) for all packages listed above.
After that, I updated my files using importFrom(pkgName, function) in the NAMESPACE file and moved most of the packages to the imports section of my DESCRIPTION file. The package check with the current R-devel-version no longer gives this note. Here's an extract of my DESCRIPTION file:
License: GPL-3
Depends:
ggplot2
Imports:
MASS,
car,
foreign,
lmtest,
plyr,
reshape2,
scales
Collate:
'sjImportSPSS.R'
and the NAMESPACE file:
import(ggplot2)
importFrom(MASS,lda)
importFrom(MASS,loglm)
importFrom(car,crPlots)
importFrom(car,durbinWatsonTest)
importFrom(car,influencePlot)
importFrom(car,leveragePlots)
importFrom(car,ncvTest)
importFrom(car,outlierTest)
importFrom(car,spreadLevelPlot)
importFrom(car,vif)
importFrom(foreign,read.spss)
importFrom(lmtest,bptest)
importFrom(plyr,adply)
importFrom(plyr,ddply)
importFrom(reshape2,melt)
importFrom(scales,brewer_pal)
importFrom(scales,percent)
I'm unsure whether this approach addresses the issue given in the check note above. Furthermore, when I load my package with library(sjPlot), ggplot2 is also attached, but none of the other packages. Does my package still work for other users? What if they don't have all needed packages installed?
From ?install.packages the default behavior is that Depends: and Imports: packages are installed if not already installed. Check out sessionInfo() and you'll see your Imports: are loaded (resident in memory) but not attached (available on disk). If your importFrom statements cover the symbols used in your package code, then your code will work for others (if there were missing imports, you would be warned about undefined global variables).