WoDoSc
WoDoSc

Reputation: 2618

Install a local R package with dependencies from CRAN mirror

I have built an R package, i.e. I have the mypackage.tar.gz file. This package depends on several other packages, all downloadable and installable from any CRAN mirror.

Now I want to install this package on a system where the dependencies are not yet installed, and I would like that the dependencies will be downloaded and installed automatically when I install my package.

I tried:

install.packages("mypackage.tar.gz",type="source",dependencies=TRUE,repos="http://a.cran.mirror")

but it searches for mypackage.tar.gz on the mirror (and obviously it does not find), while if I set repos=NULL it correctly tries to install the local package file (as documented), but obviously it does not find the dependencies packages.

So my question is: is there a way to perform a 'mixed' installation (local package with online dependencies) or the only way to do is to manually install all the dependencies?

Upvotes: 58

Views: 38144

Answers (5)

jangorecki
jangorecki

Reputation: 16727

So old question and so many answers but unfortunately none of them presents the canonical way to address the problem. R was designed to handle situations like this, no extra packages are needed. One has to create local repository, and then use it, together with CRAN url, as a repository source when installing. Below is code that present complete process.

## double check our dependency is not yet installed
## remove.packages("data.table")
"data.table" %in% rownames(installed.packages())
#[1] FALSE

## create our pkg
hello = function() "world"
package.skeleton(name="pkg", list="hello")
#...
cat("Imports: data.table\n", file="pkg/DESCRIPTION", append=TRUE)
unlink(c("pkg/Read-and-delete-me", "pkg/man"), recursive=TRUE)
rm(hello)

## publish our pkg in current working directory
system("R CMD build pkg")
#...
dir.create("src/contrib", recursive=TRUE)
file.rename("pkg_1.0.tar.gz", "src/contrib/pkg_1.0.tar.gz")
#[1] TRUE
tools::write_PACKAGES("src/contrib")

## install pkg and its dependencies automatically
install.packages("pkg", repos=c(
  paste0("file://", getwd()),
  "https://cloud.r-project.org"
))
#Installing package into '/home/jan/R/x86_64-pc-linux-gnu-library/4.2'
#(as 'lib' is unspecified)
#also installing the dependency 'data.table'
#...

## test
library(pkg)
hello()
#[1] "world

"data.table" %in% rownames(installed.packages())
#[1] TRUE

On windows one may need to specify type="source" and amend paths.

Upvotes: 2

fry
fry

Reputation: 538

If you are not opposed to using another package who manages this for you, this can nowadays be easily achieved with the {remotes} package.

install.packages("remotes")
remotes::install_local("mypackage.tar.gz")

You can specify some further options which dependencies you want (e.g. also those in 'Suggests') etc.:

?remotes::install_local

{remotes} itself does not have dependencies afaik, so it does not add too much clutter to your environment.

Upvotes: 4

Megatron
Megatron

Reputation: 17099

Here, I'm using untar() with devtools::install() and passing in a directory to which the source tarball has been extracted.

d <- tempdir()
untar("mypackage.tar.gz", compressed="gzip", exdir=d)
devtools::install(file.path(d, "mypackage"), dependencies=TRUE,
                  repos="https://cloud.r-project.org/")

If you want to install from multiple repos, you can provide a list of them. For example, to use both Bioconductor and CRAN, you could run:

 devtools::install(file.path(d, "mypackage"), dependencies=TRUE,
                   repos=BiocManager::repositories())

NOTE: I can't figure out how to directly pass the tarball to install(), but this solution works in the meantime and leaves no clutter because we extract to a temp directory. It seems install_local() should be able to take a tarball, but I am getting an error when attempting to do so.

Upvotes: 6

Emiel
Emiel

Reputation: 175

You could use install from the devtools package. Just run install("<directory of your package>", dependencies = TRUE). Its help states:

Uses R CMD INSTALL to install the package. Will also try to install dependencies of the package from CRAN, if they're not already installed.

Upvotes: 9

Thomas
Thomas

Reputation: 44565

If you already have installed your local package, you should be able to use a couple functions in tools to install the dependencies from CRAN:

library('tools')
installFoundDepends(pkgDepends('mypackage', local = FALSE)$Found)

Note: You can pass args (like repos) through installFoundDepends to install.packages.

You can also use the Depends element from the pkgDepends output to pass directly to install.packages:

install.packages(pkgDepends('mypackage')$Depends)

UPDATE: Apparently it is not possible to install a local package with dependencies=FALSE. This seems odd, since you can do that for a remote package from a repository. The reason (looking at the source code) is that if(is.null(repos) & missing(contriburl)), installation is handled via system calls to R CMD INSTALL, which has no dependency-related arguments.

Upvotes: 4

Related Questions