优雅地提取CRAN上未列出的包的R包依赖关系

时间:2015-05-13 19:49:02

标签: r

鉴于R包的DESCRIPTION文件,我想获得包依赖关系的列表(例如DependsImportsSuggests)。看起来这应该是一个解决的问题(例如devtools::install_github),但我似乎无法想出一个优雅的方法来做到这一点。我目前的解决方案是依靠来自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))
}

其中dp是包目录。这似乎有效,但感觉应该有一个现存的功能来执行此操作,或者至少比依赖.split_dependencies()包中隐藏和未导出的tools函数更清晰。

请注意,更广泛引用的获取包的依赖关系的方法根本不依赖于DESCRIPTION文件,而是使用像tools::package_dependencies这样的东西,它假定包可以在某些CRAN上找到存储库,例如这些问题:

请注意,虽然问题描述相同,但是包不在CRAN(或类似的存储库)上这一事实使得该方法无法实现。

1 个答案:

答案 0 :(得分:10)

这至少要简单一点,并且不依赖于任何未导出的函数:

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)