简体   繁体   中英

elegantly extract R package dependencies of a package not listed on CRAN

Given the DESCRIPTION file of an R package, I would like to obtain a list of the package dependencies (eg Depends , Imports , Suggests ). It seems like this should be a solved problem (eg by devtools::install_github ) but I cannot seem to come up with an elegant way to do this. My current solution is to rely on an unexported function from tools :

## adapted.from biocLite("pkgDepTools")
cleanPkgField <- function(val) {
    if (is.na(val))
      return(character(0))
    val <- names(tools:::.split_dependencies(val))
    if (is.null(val))
      return(character(0))
    val <- val[! val %in% "R"]
    if (length(val))
      return(val)
    return(character(0))
}

get_deps <- function(dp){
  dcf <- read.dcf(paste0(dp, "/DESCRIPTION"))
  suggests <- imports <- depends <- NULL
  if("Suggests" %in% colnames(dcf))
  suggests <- cleanPkgField(dcf[,"Suggests"])
  if("Imports" %in% colnames(dcf))
  imports <- cleanPkgField(dcf[,"Imports"])
  if("Depends" %in% colnames(dcf))
  depends <- cleanPkgField(dcf[,"Depends"])

  c(suggests, imports, depends)

  ## Doesn't work for packages not on CRAN
#  unlist(tools::package_dependencies(package_names, available.packages(),
#         which=c("Depends", "Imports", "Suggests"), recursive=FALSE))
}

where dp is the package directory. This seems to work, but it feels like there should be an extant function to do this, or at least something cleaner than relying on the hidden and non-exported .split_dependencies() function in the tools package.

Note that the more widely cited way to get dependencies for a package is not to rely on the DESCRIPTION file at all, but rather to use something like tools::package_dependencies which assumes the package can be found on some CRAN-like repository, eg these SO questions:

note that while the problem description is the same, the fact that the package is not on CRAN (or similar repository) makes that approach impossible.

This is at least a bit simpler and doesn't rely on any unexported functions:

get_deps <- function(path) {
    dcf <- read.dcf(file.path(path, "DESCRIPTION"))
    jj <- intersect(c("Depends", "Imports", "Suggests"), colnames(dcf))
    val <- unlist(strsplit(dcf[, jj], ","), use.names=FALSE)
    val <- gsub("\\s.*", "", trimws(val))
    val[val != "R"]
}

## Test it out on a source package with no imports ...
get_deps("C:/R/Source/Library/raster")
##  [1] "methods"   "sp"        "rgdal"     "rgeos"     "ncdf"      "ncdf4"    
##  [7] "igraph"    "snow"      "tcltk"     "rasterVis"

## ... and an installed package with no dependencies at all
get_deps("C:/R/Library/RColorBrewer/")
# named character(0)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM