I'm updating an R package and have two specific dependencies
httr (>= 0.6.1),
jsonlite (>= 0.9.14)
If these are not met the package will not function. I can see that if I put them both in Depends these version restrictions will be enforced by R. If I put them under Imports it appears they are not. There is no need for the packages to be put in Depends, I do not need them attached, and I know it is bad practice to do so.
Is it expected that Imports does not enforce version restrictions? Would it be kosher to leave the packages in Imports and have the .onLoad function check for out of date dependencies?
Writing R Extensions section 1.1.3 says
The ‘Imports’ field ... Version requirements
can be specified and are checked when the namespace is loaded (since R >= 3.0.0).
So it sounds like the lack of version checking is a bug and should be reported to the R-devel mailing list or bug tracker.
Hmm, I think the check is enforced when the namespace is loaded, e.g., import(httr) in the NAMESPACE file. If your code were to use httr::foo() without ever explicitly importing from httr, then there would be no check, or perhaps a check at run time. So again it seems like a bug, even if consistent with the documentation ('checked when the namespace is loaded').
Related
I have some C++ code that I intend to export into my r package using Rcpp. However, this code links to fftw3 via
#include <fftw3.h>
at the top of the file. When I try to compile this code, I unsurprisingly get the error
fatal error: 'fftw3.h' file not found
What is the proper way to link to this file so that it will be available upon compilation of my package? I know that a Makevars file can generally be used to link to system libraries but since this library is external I'm not sure what to do.
Thanks,
Eric.
Please see the Rcpp vignette Rcpp libraries -- which is also this arXiv paper.
There are many examples among the 2400+ CRAN packages using Rcpp. My hunch would probably be to look at what I contributed to the nloptr package -- even though that is a more complicated scheme where we allow use either a system library if present (could be the case with fftw3 too) or downloand and build.
Rcpp has been used a lot to build such glue. The most common, and simplest , approach is to look for pkg-config and query it for headers and libraries. Please give that a shot (with some looking around CRAN or GitHub for examples).
Edit: There is also an (old) fftw3 package by Gabor at his previous employer's GitHub org as well as another CRAN package fftwtools (which, if memory served, I helped once too but I don't recall now what for).
I just finished some minor updates to an R package I've had on CRAN for a few years (haven't had to update in a while). My package passes Check on my local machine and on winbuilder, but it just bounced back from CRAN with the message
checking whether package 'riverdist' can be installed ... WARNING
Found the following significant warnings:
Warning: S4 exports specified in 'NAMESPACE' but not defined in package 'riverdist'
I use roxygen2 to build my package NAMESPACE and don't have any S4 exports that I'm aware of.
Perhaps this might be related to changes in R version 4.0.0?
If anyone's encountered this error, I'd love to hear how you were able to resolve it. Thanks!
Resolved. roxygen2's #exportClass adds to NAMESPACE exportClasses() which is intended for S4 classes. S3 classes do not need to be exported, only constructor and method functions should be exported, and this is done using #export. In my case deleting all #exportClass commands solved the problem as my package defines only S3 classes. So, indeed the WARNING message is correct in diagnosing S4 exports. Found answer with the help from a thread in R-package-devel mail list from yesterday.
In the case of my packages, the problem existed in only one package that the other 9 which were also triggering the warning depend on.
The WARNING is triggered only under r-devel (future R 4.1.0).
I received this message from rdevel
"This is a new check in R-devel. The NEWS say:
R CMD check etc now warn when a package exports non-existing S4 classes or methods, also in case of no "methods" presence
In your case, the NAMESPACE contains
exportClasses(classify)
exportClasses(gonad_mature)
exportClasses(morphMat)
but your package does not define these S4 classes.
You seem to instruct roxygen2 to create these invalid directives using
#exportClass tags manually instead of just #export. Simply remove these
wrong #exportClass tags from your source files and regenerate your
NAMESPACE.
Best regards,
Sebastian Meyer"
https://www.mail-archive.com/r-package-devel#r-project.org/msg05436.html
Rcpp beginner's question:
I want to improve my execution efficiency in R. So I write some code in cpp and use Rcpp to help me compile them.
Question is that I use some other R packages in my .cpp files and I want those packages to be installed and imported automatically when a user installs my package.
e.g. If I use the R package 'gtools' in my files, I don't want the error:
* installing to library 'C:/Program Files/R/R-3.4.1/library'
* installing *source* package 'pkgname' ...
make: Nothing to be done for `all`.
** libs
installing to C:/Program Files/R/R-3.4.1/library/pkgname/libs/i386
** R
** preparing package for lazy loading
Error in library(gtools) : there is no package called 'gtools'
Error : unable to load R code in package 'pkgname'
ERROR: lazy loading failed for package 'pkgname'
* removing 'C:/Program Files/R/R-3.4.1/library/pkgname'
Exited with status 1.
I tried to add depended package name to the DESCRIPTION file. i.e.
Imports: Rcpp (>= 0.12.12),gtools
LinkingTo: Rcpp, gtools
But it gives me following error:
ERROR: dependency 'gtools' is not available for package 'pkgname'
I don't find any similar questions and please tell me if there are.
First, you should probably make sure gtools is installed on your system. I say this because of the following error:
Error in library(gtools) : there is no package called 'gtools'
With this being said, the main issue you are running into is uncertainty between the LinkingTo: and Imports: fields in the DESCRIPTION file. This is covered in Section 1.1.3: Package Dependencies of Writing R Extensions.
Specifically, we have:
The ‘Imports’ field lists packages whose namespaces are imported from (as specified in the NAMESPACE file) but which do not need to be attached. Namespaces accessed by the ‘::’ and ‘:::’ operators must be listed here, or in ‘Suggests’ or ‘Enhances’ (see below). Ideally this field will include all the standard packages that are used, and it is important to include S4-using packages (as their class definitions can change and the DESCRIPTION file is used to decide which packages to re-install when this happens). Packages declared in the ‘Depends’ field should not also be in the ‘Imports’ field. Version requirements can be specified and are checked when the namespace is loaded (since R >= 3.0.0).
And the LinkingTo field:
A package that wishes to make use of header files in other packages needs to
declare them as a comma-separated list in the field ‘LinkingTo’ in the
DESCRIPTION file. For example
LinkingTo: link1, link2
The ‘LinkingTo’ field can have a version requirement which is checked at installation.
Specifying a package in ‘LinkingTo’ suffices if these are C++ headers containing source code or static linking is done at installation: the packages do not need to be (and usually should not be) listed in the ‘Depends’ or ‘Imports’ fields. This includes CRAN package BH and almost all users of RcppArmadillo and RcppEigen.
For another use of ‘LinkingTo’ see Linking to native routines in other packages.
So, the Imports: is meant to specify packages that contain R functions that you wish to import. In particular, the function from a given package or the entire package itself must be specified in the NAMESPACE file. For packages that use Rcpp, you can typically expect R functions to be available if the author has exported the routine from C++.
Now, regarding the LinkingTo:, this is a bit more specific. If an author wishes to make available a C++ API via header files they must explicitly declare the statements as is given in native methods of Writing R Extensions. Generally, packages that proceed in this manner are "header-only". These packages place the header definitions under inst/include, e.g.
|- pkgname
|- inst/
|- include/
|- pkgname.h
|- R/
|- man/
|- DESCRIPTION
|- NAMESPACE
However, another trend is to allow for "non-header" packages. This leads to a bit more complicated of topic as you have to understand shared objects and dynamic libraries. CRAN presents an overview of how to "Link" packages in Section 5.8: Linking to other packages of Writing R Extensions
If the author does not make available a C++ API, then there are four options:
Ask the author nicely to support calling the C++ API or submit a patch that enables access to the C++ API.
Call an R function from C++. (This negates any performance gain from writing your code in C++ though.)
Copy the implementation from the author's package while respecting their intellectual property.
Implement the desired functionality from scratch to avoid licensing issues.
Unfortunately, this is the case for gtools. As the author(s) do not provide a means to "link" to the C++ version of package's code.
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).
I tend to be rather explicit than implicit about the code I write. So after having managed to create my own packages, the next thing that immediately comes to my mind is how best to ensure robustness and reliability of my code. Part of that has to do with the packages my package depends on.
Actual Question
In that respect: is it possible to explicitly state which version of a package dependency is required/desired?
I'm looking for ways that don't require stating the actual path to, say, the zip file (which of course would easily be possible), but just make use of install.packages "standard behavior" of stating the package name only (possibly with some reference of the required version).
Due dilligence
I've checked Writing R Extensions to see what my options are with respect to the Depends section of the DESCRIPTION file, hoping for a similar mechanism that works for stating the required R version (e.g. R (>= 2.15.2)). But I didn't find anything similar for package dependencies:
The ‘Depends’ field gives a comma-separated list of package names which this package depends on. The package name may be optionally followed by a comment in parentheses. The comment should contain a comparison operator, whitespace and a valid version number.
You can also use the special package name ‘R’ if your package depends on a certain version of R — e.g., if the package works only with R version 2.11.0 or later, include ‘R (>= 2.11.0)’ in the ‘Depends’ field. You can also require a certain SVN revision for R-devel or R-patched, e.g. ‘R (>= 2.14.0), R (>= r56550)’ requires a version later than R-devel of late July 2011 (including released versions of 2.14.0). Both library and the R package checking facilities use this field: hence it is an error to use improper syntax or misuse the ‘Depends’ field for comments on other software that might be needed. Other dependencies (external to the R system) should be listed in the ‘SystemRequirements’ field, possibly amplified in a separate README file.
The R INSTALL facilities check if the version of R used is recent enough for the package being installed, and the list of packages which is specified will be attached (after checking version requirements) before the current package, both when library is called and when preparing for lazy-loading during installation.
Then I also had a look a install.packages and hoped for something like a version argument, but I guess there isn't.
Disclaimer
I'm perfectly aware that the goal of my questions might contrast R's philosophy of distributing and installing packages via CRAN package repositories where (at least I guess) new versions of certain packages just "overrule" previous ones and install.packages() always picks up the latest one available. It also does make a lot of sense to hide version peculiarities from the end user in order not to make things overly complex.
Yet, with respect to the goal of writing as robust code as possible, IMHO it also makes sense to state things very explicitly. Or at least to have the option to do so.
You do use Depends. For example:
Depends: R (>= 2.15.0), foo (== 1.17-12)
would place a dependency on R versions greater than or equal to 2.15.0 and on package foo being equal to 1.17-12.
(At least if I have understood you correctly, that you want to state explicitly that your package works only with version x.yy-zz of package foo.)
I'm not sure how helpful this will be for end users though; you are probably going to be forcing them to maintain separate libraries of packages in order to use your package just to maintain the exact versions you stipulate.