以非字符列表形式加载多个包的函数

function to load multiple packages with input as non-character list

我厌倦了用 require(data.table); require(ggplot2) 等等启动我的脚本。我知道我可以做类似 lapply(c('data.table', 'ggplot2'), require, character.only=T) 的事情,但它只会 return 一个警告(不是错误) 对于丢失的包,另外我想要我自己的函数 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(data.table, ggplot2)require_mult,它将丰富我对 R 表达式评估的理解等等

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

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

我想你可以用它来进一步构建。

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’