0

我厌倦了用require(data.table); require(ggplot2)etc 等开始我的脚本。我知道我可以做类似的事情lapply(c('data.table', 'ggplot2'), require, character.only=T),但它只会为丢失的包返回一个警告(不是错误),而且我希望我自己的函数require_mult(...)来保持我的脚本更干净。所以我写了这个函数:

require_mult <- function(...){
  arg_list <- list(...)
  if(any(!sapply(arg_list, is.character)) ) stop('require_mult must have character arguments')
    check <- tryCatch({pkg_array <- unlist(arg_list)
                       loaded <- sapply(pkg_array, require, character.only=TRUE, quietly=TRUE)
                       message('Loaded packages: ',
                               paste(pkg_array, collapse=', ') ) },
                       warning = function(w) stop(w), # I want execution to halt if a package is missing
                       error = function(e) stop(e)
                       )
}

这似乎可以按需要工作(例如,负载为require_mult('data.table','ggplot2'),错误为require_mult('data.table','ggplotfoo')),但我想让它require_mult(...)character.only=FALSE. 我查看了 的定义require,它使用

if (!character.only) 
        package <- as.character(substitute(package))

但我不知道如何应用substitute到一个未计算的表达式,它实际上是一个逗号分隔的列表。

我知道这个应用程序毫无意义和学术性,但如果实际上有一种方法可以编写require_mult可用于require_mult(data.table, ggplot2)等的方法,它将丰富我对 R 表达式评估的理解。

解释为什么不能这样做也是可以接受的。

4

1 回答 1

1

我今天在这里学到了一些东西!您可以使用match.call获取传入的参数...而不评估它们。(大概,你可以用命名参数来做到这一点......?我需要对此进行更多实验。)我使用这个答案来构建下面非常简单的函数。如您所见,它在到达不存在的包时会中断。

我认为您可以使用它来进一步构建。

library_mult <- function(...) {
    args <- match.call(expand.dots = FALSE)$`...`
    for(x in args) {

        x <- as.character(substitute(x))
        library(x,character.only = TRUE)
    }
}

> library_mult(MASS,thisisnopack)

Error in library(x, character.only = TRUE) : 
  there is no package called ‘thisisnopack’
于 2015-12-18T15:26:04.400 回答