Подтвердить что ты не робот

Изящно извлекать R-пакетные зависимости пакета, не указанного в CRAN

Учитывая файл DESCRIPTION пакета R, я хотел бы получить список зависимостей пакета (например, Depends, Imports, Suggests). Кажется, что это должна быть решена проблема (например, 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 (или аналогичном репозитории), делает этот подход невозможным.

4b9b3361

Ответ 1

Это, по крайней мере, немного проще и не зависит от каких-либо невыполненных функций:

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)