我如何一次性加载多个包而不需要重复输入require命令?我尝试了三种方法,但都失败了。
基本上,我想要提供一个包名向量给一个函数,然后这个函数可以加载它们。
x<-c("plyr", "psych", "tm")
require(x)
lapply(x, require)
do.call("require", x)
你提出的几种函数排列方式是可以工作的 -- 但只有在指定character.only
参数为TRUE
时才有效。快速示例:
lapply(x, require, character.only = TRUE)
我维护的CRAN软件包pacman(与Dason Kurkiewicz合著)可以完成此操作:
因此,用户可以执行以下操作:
## install.packages("pacman")
pacman::p_load(dplyr, psych, tm)
如果缺少软件包,p_load
将从 CRAN 或 Bioconductor 下载它。
p_load
这样的简短名称?使用更描述性的名称,比如 load_packages
,可以更清晰地表达函数的意图。 - Paul Hiemstrap_
开头。我们还倾向于使用 library(库),这是额外的 7 个字符。7 个字符 x ~1000000 次函数使用寿命 x 每个字符 0.5 秒 = 3500000 秒。这相当于 58333.33 分钟、972.2222 小时或 40.50926 天的程序员生命,我们已经为他们节省回来了 :-) 无论如何,我们的目标是在 2 月 1 日前推广到 CRAN。 - Tyler Rinkerp_
前缀的理由很靠不住。如果简洁是问题,可以完全删除p_
前缀。事实上,在其他语言中通常不建议使用这样的前缀,有很好的原因(我已经告诉过 Hadley 在 forcats 中使用 fct_
也是同样如此)。这一点特别适用于使用限定名称空间 (pacman::
) 的包的预期使用方式。 - Konrad Rudolph这应该就可以解决问题了:
lapply(x, FUN = function(X) {
do.call("require", list(X))
})
重要的是,在do.call(what, args)
中的args
参数必须是一个列表,即使它只有一个元素!
我认为@daroczig提供的代码可以通过将require
替换为library
并将lapply
调用包装在invisible()
函数中来进行改进。因此,改进后的代码将如下所示:
invisible(lapply(x, library, character.only = TRUE))
这段代码得到改进,因为:
library()
一般比 require()
更受欢迎,用于加载包,因为前者如果未安装该包,则会出现错误,而后者只会给出警告。此外,require()
调用 library()
,那么为什么不直接使用 library()
呢!
library("time")
# Error in library("time") : there is no package called ‘time’
require("time")
# Loading required package: time
# Warning message:
# In library(package, lib.loc = lib.loc, character.only = TRUE, logical.return = TRUE, :
# there is no package called ‘time’
在这种情况下,lapply()
调用返回并打印的列表对象没有意义,因此将输出设置为不可见是有意义的。假设你在使用 R Notebook 进行分析工作,使用 invisible()
函数将抑制列表对象的内容,并防止渲染的笔记本文件中出现混乱。
include=F
来删除@daroczig解决方案中杂乱的TRUE
输出列表,但添加invisible()
是与笔记本无关的,所以您的添加更好。 - Dylan_Gomes对于想要同时安装和加载软件包的人,我发现了这个函数,来自于这个链接
# ipak function: install and load multiple R packages.
# check to see if packages are installed. Install them if they are not, then load them into the R session.
ipak <- function(pkg){
new.pkg <- pkg[!(pkg %in% installed.packages()[, "Package"])]
if (length(new.pkg))
install.packages(new.pkg, dependencies = TRUE)
sapply(pkg, require, character.only = TRUE)
}
# usage
packages <- c("ggplot2", "plyr", "reshape2", "RColorBrewer", "scales", "grid")
ipak(packages)
另一个选项来自于包easypackages
(需要安装)。您可以以最直观的方式加载包:
library("easypackages")
libraries("plyr", "psych", "tm")
这个套餐还包括一个安装多个包的函数:
packages("plyr", "psych", "tm")
参考此处。
library
函数中指的是安装软件包的位置:软件包库。通过libraries
加载多个软件包毫无意义。拥有一个执行其他操作的单独函数packages
只会让情况更糟。我知道在软件工程中命名是一个难题,但这些名称真的很糟糕。 - Konrad Rudolph在daroczig的解决方案基础上,如果您不想指定一个列表作为输入,则可以使用
# Foo
mLoad <- function(...) {
sapply(sapply(match.call(), as.character)[-1], require, character.only = TRUE)
}
# Example
mLoad(plyr, dplyr, data.table)
...比...短
lapply(list('plyr', 'dplyr', 'data.table'), require, character.only = TRUE)
对 Tyler Rinker 的答案进行了轻微修改,添加了一个检查以安装和加载 pacman:
#Install/load pacman
if(!require(pacman)){install.packages("pacman");require(pacman)}
#Install/load tons of packages
p_load(plyr,psych,tm)
I use the following function:
mrip <- function(..., install = TRUE){
reqFun <- function(pack) {
if(!suppressWarnings(suppressMessages(require(pack, character.only = TRUE)))) {
message(paste0("unable to load package ", pack,
": attempting to download & then load"))
install.packages(pack)
require(pack, character.only = TRUE)
}
}
lapply(..., reqFun)
}
这个操作会尝试加载内容,如果失败则安装并再次尝试加载。
lapply(x, function(x) {if (!require(x, character.only=T)) {install.packages(x);require(x)}})
这样的方式,在需要时才进行先前检查并安装所需的包。如果我们以字符形式在x
中指定要加载(以及必要时安装)的包的列表,就像OP所要求的那样。但是在评论中进一步开发这个想法会变得相当冗长 :) - darocziglibrary()
函数中的这个lapply
技巧那就太好了。这样就可以很方便地使用类似于library(c("plyr", "umx"))
这样的语法了。 - tim