一次加载多个包
Posted
技术标签:
【中文标题】一次加载多个包【英文标题】:Load multiple packages at once 【发布时间】:2011-12-31 19:59:19 【问题描述】:我怎样才能一次加载一堆包而不一遍又一遍地重新输入 require 命令?我尝试了三种方法,但都崩溃了。
基本上,我想将包名称的向量提供给将加载它们的函数。
x<-c("plyr", "psych", "tm")
require(x)
lapply(x, require)
do.call("require", x)
【问题讨论】:
【参考方案1】:对于想要同时安装和加载软件包的人,我从 link 发现了这个功能
# 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)
【讨论】:
您好,我从您给定的 sn-p 创建了一个 R 文件。当我在 Amazon EMR 服务上运行该脚本时,它会为我提供以下 URL 中指定的以下输出。 pastie.org/10402378#3,10-11,13.【参考方案2】:Tyler Rinker's answer to add a check to install & load pacman 的轻微修改:
#Install/load pacman
if(!require(pacman))install.packages("pacman");require(pacman)
#Install/load tons of packages
p_load(plyr,psych,tm)
我喜欢 p_load 解决方案,因为它避免了引用!
【讨论】:
【参考方案3】:我认为@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()
函数将抑制列表对象的内容并防止呈现的笔记本文件混乱。
【讨论】:
【参考方案4】:您可以简单地使用 lubripack 包,它会整齐地安装新包,然后在一行中加载所有包。
lubripack("plyr", "psych", "tm")
这是您在 RStudio 中运行上述代码后的输出。
如何安装包:
运行以下代码以下载包并从 GitHub 安装它。无需 GitHub 帐户。
library(devtools)
install_github("espanta/lubripack")
【讨论】:
我猜是用图片代替文字 这也没有以尚未回答的方式回答问题,而且似乎主要是自我推销。 你说得对,我试图含蓄地回答这个问题。让我们明确表示希望它可以回答问题。 @TylerRinker 现在怎么样了?【参考方案5】:另一个选项来自包easypackages
。安装后,您可以以最直观的方式加载包:
libraries("plyr", "psych", "tm")
该包还包括一个安装多个包的功能:
packages("plyr", "psych", "tm")
参考here。
【讨论】:
函数名称相当混乱/混乱。 “库”,在library
函数中,指的是安装包的位置:包库。通过libraries
加载几个包是没有意义的。拥有一个单独的函数packages
做其他事情只会让情况变得更糟。我知道命名是软件工程中的一个难题,但确实如此。这些名字特别糟糕。
@KonradRudolph 我不同意libraries
这个名字没有意义。它是library
的复数形式,library
加载单个包; libraries
加载多个包。如果您认为library
的意思是“从您的单个库加载”,并将其扩展到libraries
的意思是“从多个库加载”,那么它可能不直观,但这不是意图;我会很高兴libraries
这个名字。
@JamieS 但它仍然(通常)从单个库加载。您似乎混淆了库和包(公平地说,这在 R 中很常见):正如我之前的评论所述,“R 库”是指安装 R 包的位置(目录/目录) .在这个答案的示例中,“plyr”、“psych”和“tm”不是库:它们是包。【参考方案6】:
基于 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)
【讨论】:
【参考方案7】:您提议的函数的几种排列确实有效——但前提是您将character.only
参数指定为TRUE
。快速示例:
lapply(x, require, character.only = TRUE)
【讨论】:
@Tommy & daroczig -- 酷。这是一个更清洁的解决方案。我会留下我的,只是为了后代,以及它说明了为什么 OP 的尝试没有奏效。 您可以利用部分字符匹配并摆脱 lapply(x, require, ch = T) 甚至 lapply(x, require, c = T) @daroczig 此代码加载包但为什么它会给出以下警告消息:1:在库中(包,lib.loc = lib.loc,character.only = TRUE,logical.return = TRUE, : 没有名为 'x' 的包 2: 在 if (!loaded) : 条件长度 > 1 并且只使用第一个元素 @PauloCardoso:没错。虽然我会想像lapply(x, function(x) if (!require(x, character.only=T)) install.packages(x);require(x))
这样的东西来保存任何先前的检查并仅按需进行安装。如果我们在 x
字符中指定要加载(并在需要时安装)的软件包列表 - 就像 OP 询问的那样。但是在评论中进一步发展这一点已经很长了:)
如果 R::base 将这个 lapply
技巧添加到 library()
,那就太好了。很高兴能够说:library(c("plyr", "umx"))
【参考方案8】:
我维护的 CRAN 包 pacman(由 Dason Kurkiewicz 编写)可以实现这一点:
所以用户可以这样做:
## install.packages("pacman")
pacman::p_load(dplyr, psych, tm)
如果包丢失,p_load
将从 CRAN 或 Bioconductor 下载。
【讨论】:
+1!为什么选择简称p_load
? load_packages
等更具描述性的名称使函数的意图更加清晰。
因为 p 代表包。包中每个有用和导出的函数都以p_
开头。另外,我们倾向于稍微使用库,那是额外的 7 个字符。 7 个字符 x ~1000000 次函数的使用时间 x 每个字符 0.5 秒 = 3500000 秒。那是程序员生命中的 58333.33 分钟、972.2222 小时或 40.50926 天,我们已经回馈给他们 :-) 无论如何,我们的目标是在 2 月 1 日前推进 CRAN
晚了大约一年,但我们最终提交给了 CRAN。过几天应该就起来了。 @trinker(或我)确保在公开后对其进行修改。
@Tyler 我知道我迟到了几年,但我发现你使用 p_
前缀的理由相当可疑。如果简洁是问题,请完全删除 p_
前缀。事实上,在其他语言中通常不鼓励使用这样的前缀是有充分理由的(我已经告诉 Hadley,对于他在 forcats 中的fct_
废话,它们也是如此)。 尤其是如此,因为这个包的预期用途是使用一个合格的命名空间 (pacman::
)。
@TylerRinker 很抱歉在这个问题上好斗,但我真的认为 R 社区在这里完全是错误的,几乎所有其他现代语言都做对了:你说“这可以防止命名空间冲突。 ” — 但是这就是命名空间的用途!包编写者的责任是教育人们正确使用包,而不是适应他们草率的编程习惯。【参考方案9】:
我使用以下函数:
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)
这会尝试加载,如果安装失败,则再次尝试加载。
【讨论】:
【参考方案10】:这应该可以解决问题:
lapply(x, FUN = function(X)
do.call("require", list(X))
)
(关键是do.call(what, args)
中的args
参数必须是一个列表——即使它只有一个元素!)
【讨论】:
以上是关于一次加载多个包的主要内容,如果未能解决你的问题,请参考以下文章