Ken Williams
Ken Williams

Reputation: 24015

Require minimum version of R package

I just noticed that there's no version argument to R's require() or library() functions. What do people do when they need to ensure they have at least some minimum version of a package, so that e.g. they know some bug is fixed, or some feature is available, or whatever?

I'm aware of the Depends stuff for package authors, but I'm looking for something to use in scripts, interactive environments, org-mode files, code snippets, etc.

Upvotes: 24

Views: 4030

Answers (4)

Statistican
Statistican

Reputation: 43

The pacman-package provides the p_install_version function that allows to define a minimal package version.

For a single package:

pacman::p_install_version(
  'conflicted',  # the package
  '1.2.0'        # the minimum version to be installed
)

Or multiple packages at once:

pacman::p_install_version(
  c('conflicted', 'tidyverse'),
  c('1.2.0', '2.0.0')
)

Note that the packages are only installed and have to be loaded afterwards:

pacman::p_load(
  conflicted, tidyverse
)

Upvotes: 0

Josh O'Brien
Josh O'Brien

Reputation: 162461

You could use packageVersion():

packageVersion("stats")
# [1] ‘2.14.1’

if(packageVersion("stats") < "2.15.0") {
    stop("Need to wait until package:stats 2.15 is released!")
}
# Error: Need to wait until package:stats 2.15 is released!

This works because packageVersion() returns an object of class package_version for which < behaves as we'd like it to (which < will not do when comparing two character strings using their lexicographical ordering).

Upvotes: 20

Ken Williams
Ken Williams

Reputation: 24015

After reading Paul's pseudocode, here's the function I've written.

use <- function(package, version=0, ...) {
  package <- as.character(substitute(package))
  library(package, ..., character.only=TRUE)
  pver <- packageVersion(package)
  if (compareVersion(as.character(pver), as.character(version)) < 0)
    stop("Version ", version, " of '", package, 
         "' required, but only ", pver, " is available")
  invisible(pver)
}

It functions basically the same as library(), but takes an extra version argument:

> use(plyr, 1.6)
> use(ggplot2, '0.9')
Error in use(ggplot2, "0.9") : 
  Version 0.9 of 'ggplot2' required, but only 0.8.9 is available

Upvotes: 13

Paul Hiemstra
Paul Hiemstra

Reputation: 60984

I am not aware of such a function, but it should be quite easy to make one. You can base it on sessionInfo() or packageVersion(). After loading the packages required for the script, you can harvest the package numbers from there. A function that checks the version number would look like (in pseudo code, as I don't have time right now):

check_version = function(pkg_name, min_version) {
    cur_version = packageVersion(pkg_name)
    if(cur_version < min_version) stop(sprintf("Package %s needs a newer version, 
               found %s, need at least %s", pkg_name, cur_version, min_version))
}

Calling it would be like:

library(ggplot2)
check_version("ggplot2", "0.8-9")

You still need to parse the version numbers into something that allows the comparison cur_version < min_version, but the basic structure remains the same.

Upvotes: 8

Related Questions