Include non-CRAN package in CRAN package
Existing answer is good but doesn't explain the whole process fully in details so posting this one.
Is it possible to include a non-CRAN (or bioconductor, or omega hat) package in a CRAN package and actually use tools from that package in examples.
Yes, it is possible. Any use (package code, examples, tests, vignettes) of such non-CRAN has to be escaped as any other package in Suggests, ideally using
if (requireNamespace("non.cran.pkg", quietly=TRUE)) {
non.cran.pkg::fun()
} else {
cat("skipping functionality due to missing Suggested dependency")
}
If yes how does one set up the DESCRIPTION file etc. to make it legit and pass CRAN checks?
You need to use Additional_repositories
field in DESCRIPTION file. Location provided in that field has to contain expect directory structure, PACKAGES
file in appropriate directory, and PACKAGES
file has to have non-CRAN package listed.
Now going to your particular example of openNLPmodels.en
package.
According to the way how you download and install this package it will not be possible to use it as dependency and pass on CRAN. openNLPmodels.en
has to be published in a structure expected from R repository. Otherwise you don't have a valid location to put into Additional_repositories
field.
What you can do is to download non-CRAN package and publish it in your R repository yourself, and then use that location in Additional_repositories
field in your CRAN package.
Here is an example of how to do it:
dir.create("src/contrib", recursive=TRUE)
download.file("http://datacube.wu.ac.at/src/contrib/openNLPmodels.en_1.5-1.tar.gz", "src/contrib/openNLPmodels.en_1.5-1.tar.gz")
tools::write_PACKAGES("src/contrib")
We just put package sources in expected directory src/contrib
and the rest is nicely handled by write_PACKAGES
function. To ensure that repository is properly created you can list packages that are available in that repository:
available.packages(repos=file.path("file:/",getwd()))
It should list your non-CRAN package there.
Then having non-CRAN package published in R repository you should location of the repository into Additional_repositories
field of your CRAN package. In this case location will be location returned by file.path("file:/",getwd())
expression.
Note that it uses location on your local machine, you will probably want to put it online, so that url can accessed by any machine checking your CRAN package, including checks on CRAN itself. For that just move your src
directory to a public directory that is going to be hosted somewhere online and use the location of that server.
Now looking at your non-CRAN package again, we can see it has src/contrib in its url, thus we can assume that proper R repository already exists for it and we don't have to create and publish new one.
Therefore your installation instruction could look like
install.packages(
"openNLPmodels.en",
repos="http://datacube.wu.ac.at",
type="source"
)
And then all you need for your CRAN package is to use existing repository where it is available
Additional_repositories http://datacube.wu.ac.at
(How) can a package on CRAN import a package not on CRAN?
I don't think so.
Writing R Extensions specifies that you can include an Additional_repositories
field in the DESCRIPTION file.
However, the CRAN Repository Policy says:
Packages on which a CRAN package depends should be available from a mainstream repository: if any mentioned in ‘Suggests’ or ‘Enhances’ fields are not from such a repository, where to obtain them at a repository should be specified in an ‘Additional_repositories’ field of the DESCRIPTION file (as a comma-separated list of repository URLs) or for other means of access, described in the ‘Description’ field.
- "mainstream" here presumably means CRAN (and maybe? Bioconductor) (this bioc-devel thread from 2015 suggests that both CRAN and Bioconductor are "mainstream")
- "depends" here means Imports/LinkingTo/Depends
I can't think of any solutions beyond the ones you suggest (get the package on CRAN or incorporate the necessary code in your package).
R package building: How to import a function from a package not on CRAN
A super easy trick is to add a ‘remotes’ field into our DESCRIPTION
file specifying the username/package_name target of our target package on Github.
Remotes:
github::User/PackageNotOnCRAN
Import:
PackageNotOnCRAN
Suggests:
devtools,
testthat
Not only will this work very well for files on github (github::
), but works for git, bitbucket, local packages and more.
More information, how I figured it out.
Installation of non-CRAN package requires CRAN mirror
You are relying on the (R global) options()
having a valid repos
entry on the cluster.
Which you ... cannot as base R ships (in source from) without such as base R Core feels, rightly or wrongly, that they cannot play favourites and set one. Some of us think that is wrong (as it diminishes the user experience -- like yours here) so in the Debian (and hence Ubuntu) package I set this to the 'cloud' mirror everybody is close to as it is on a CDN:
edd@rob:~$ tail -6 /usr/lib/R/etc/Rprofile.site
## We set the cloud mirror, which is 'network-close' to everybody, as default
local({
r <- getOption("repos")
r["CRAN"] <- "https://cloud.r-project.org"
options(repos = r)
})
edd@rob:~$
I suggest you do the same, maybe in ~/.Rprofile
, on the cluster.
R package dependencies not installed from Additional_repositories (revisited)
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.
Make CRAN R package suggest GitHub R package
As you found, you can't use Remotes
in a CRAN package. What you need to do is to make sure the .tar.gz
file for the package you are depending on is available somewhere. Github doesn't do that automatically, because https://github.com/daviddaigithub/BOLTSSIRR
isn't set up as a package repository.
The solution is to create your own small repository, and keep copies of non-CRAN packages there. The drat
package (available here: https://github.com/eddelbuettel/drat) makes this easy as long as you have a Github account: follow the instructions here: https://github.com/drat-base/drat. In summary:
- Fork https://github.com/drat-base/drat into your account, and clone it to your own computer.
- Enable Github Pages with the
docs/
folder in the main branch. - Install the
drat
package into R usingremotes::install_github("eddelbuettel/drat")
. (I assume this version will make it to CRAN eventually; if you use the current CRAN version instructions are slightly more complicated.) - Build the package you want to insert. You need the source version; you might want binaries too, if those are hard for your users to build.
- Run
options(dratBranch="docs"); drat::insertPackage(...)
to insert those files into your repository. - Commit the changes, and push them to Github.
- In the package that needs to use this non-CRAN package, add
Additional_repositories: https://yourname.github.io/drat
to the DESCRIPTION.
You will be responsible for updating your repository if BOLTSSIRR
is updated. This is good because the updates might break yours: after all, it's still in development mode. It's also bad because your users won't automatically get bug fixes.
That's it, if I haven't missed anything!
Use GitHub Package R Actions
After some time, I have found a workaround that for now is good enough if you want to test for the development version(like I wanted). You should include an install_github
command in the check.yaml
file. Here's an example:
- name: Install dependencies
run: |
install.packages(c("remotes","testthat"),dependencies=TRUE)
remotes::install_github("tidyverse/dplyr")
remotes::install_cran("covr")
shell: Rscript {0}
The above snippet fixed my issue because I wanted to depend on a future dplyr
version. You can view the full yaml
file here.
Related Topics
Get Start and End Index of Runs of Values
Flag First By-Group in R Data Frame
Combining Two Vectors Element-By-Element
How to Read All Files in One Directory into R at Once
Order Dataframe for Given Columns
Mlogit: Missing Value Where True/False Needed
Function to Change Blanks to Na
How to Change Color Scheme in Corrplot
Spread with Duplicate Identifiers for Rows
How to Use Stat_Bin2D() to Compute Counts Labels in Ggplot2
Aggregating Rows for Multiple Columns in R
Customise The Infowindow/Tooltip in R -> Plotly
Adding a Layer to The Current Plot Without Creating a New One in Ggplot2
Conda Build R Package Fails at C Compiler Issue on Macos Mojave