我已经厌倦了用require(data.table); require(ggplot2)
等开始我的脚本。我知道我可以做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表达式评估的理解。
解释为什么不能这样做也是可以接受的。
答案 0 :(得分:1)
我今天在这里学到了一些东西!您可以使用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’