一次加载多个包

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_loadload_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 参数必须是一个列表——即使它只有一个元素!)

【讨论】:

以上是关于一次加载多个包的主要内容,如果未能解决你的问题,请参考以下文章

UDP数据包一次发送多大为好

tcp粘包是怎么产生的?

说一下 tcp 粘包是怎么产生的?(未完成)

`@static` 啥时候运行?

Suricata文档——第七章性能

一次加载多个包