Charger plusieurs packages à la fois

174

Comment puis-je charger un tas de packages à la fois sans retaper la commande require encore et encore? J'ai essayé trois approches qui se brisent et brûlent.

Fondamentalement, je souhaite fournir un vecteur de noms de packages à une fonction qui les chargera.

x<-c("plyr", "psych", "tm")

require(x)
lapply(x, require)
do.call("require", x)
Tyler Rinker
la source

Réponses:

251

Plusieurs permutations de vos fonctions proposées fonctionnent - mais uniquement si vous spécifiez l' character.onlyargument à être TRUE. Exemple rapide:

lapply(x, require, character.only = TRUE)
Daroczig
la source
@Tommy & daroczig - Cool. C'est une solution bien plus propre. Je ne laisserai le mien que pour la postérité, et pour ce qu'il montre sur les raisons pour lesquelles les tentatives du PO n'ont pas fonctionné.
Josh O'Brien
4
Vous pouvez profiter de la correspondance partielle des caractères et vous en tirer avec lapply (x, require, ch = T) ou même lapply (x, require, c = T)
Dason
@daroczig Ce code charge les packages mais pourquoi donne-t-il les messages d'avertissement suivants: 1: Dans la bibliothèque (package, lib.loc = lib.loc, character.only = TRUE, logical.return = TRUE,: il n'y a pas de package appelé 'x' 2: Dans si (! chargé) {: la condition a une longueur> 1 et seul le premier élément sera utilisé
Anusha
@Anusha: Je n'ai aucune idée de guichet automatique, qu'est-ce que vous avez dans votre x?
daroczig
23
Soyez gentil si R :: base a ajouté cette lapplyastuce native à library(). Soyez génial de pouvoir dire:library(c("plyr", "umx"))
tim
58

Le paquet CRAN Pacman que je maintiens (créé avec Dason Kurkiewicz) peut accomplir ceci:

Ainsi, l'utilisateur peut faire:

## install.packages("pacman")
pacman::p_load(dplyr, psych, tm) 

et si le paquet est manquant, p_loadil le téléchargera depuis CRAN ou Bioconductor.

Tyler Rinker
la source
7
+1! Pourquoi avez-vous choisi le nom court p_load? Un nom plus descriptif tel que load_packagesrend l'intention de la fonction plus claire.
Paul Hiemstra
19
Parce que le p signifie package. Chaque fonction du package utile et exportée commence par p_. De plus, nous avons tendance à utiliser un peu la bibliothèque et cela représente 7 caractères supplémentaires. 7 caractères x ~ 1000000 utilisations de la durée de vie de la fonction x 0,5 seconde par caractère = 3500000 secondes. C'est 58333,33 minutes, 972,2222 heures ou 40,50926 jours de la vie d'un programmeur que nous leur avons rendu :-) En tout cas, notre objectif est de pousser au CRAN avant le 1er février
Tyler Rinker
3
Environ un an de retard mais nous avons finalement soumis au CRAN. Devrait être en place dans quelques jours. @trinker (ou moi) assurez-vous de le modifier une fois qu'il sera rendu public.
Dason
5
@Tyler Je sais que j'ai des années de retard, mais je trouve la justification du p_préfixe plutôt douteuse. Si le problème est la concision, supprimez p_entièrement le préfixe. En fait, avoir de tels préfixes est généralement déconseillé dans d'autres langues pour de bonnes raisons (j'ai dit à Hadley qu'ils fct_étaient pareils en ce qui concerne ses absurdités dans les forcats). Cela est d' autant plus vrai que l'utilisation prévue du package est avec un namespace qualifié ( pacman::).
Konrad Rudolph
5
@TylerRinker Toutes nos excuses pour être combatif sur ce problème, mais je pense vraiment que la communauté R a tout simplement tort ici, et pratiquement tous les autres langages modernes ont raison: vous dites: «Cela protège des conflits d'espace de noms.» - Mais c'est à cela que servent les espaces de noms! Il incombe aux rédacteurs de paquets d'éduquer les gens à utiliser correctement les paquets, et non de s'adapter à leurs pratiques de programmation bâclées.
Konrad Rudolph
24

Cela devrait faire l'affaire:

lapply(x, FUN = function(X) {
    do.call("require", list(X)) 
})

(Le bit clé est que l' argsargument dans do.call(what, args) doit être une liste --- même s'il n'a qu'un seul élément!)

Josh O'Brien
la source
16

Pour quelqu'un qui veut installer et charger des packages simultanément, je suis tombé sur cette fonction à partir de ce lien

# 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)
bala
la source
Bonjour, j'ai créé un fichier R à partir de votre extrait de code. Lorsque j'exécute ce script sur le service Amazon EMR, il me donne la sortie suivante comme spécifié dans l'URL suivante. pastie.org/10402378#3,10-11,13 .
Rubin Porwal
9

Une option alternative vient du package easypackages. Une fois installés, vous pouvez charger des packages de la manière la plus intuitive:

libraries("plyr", "psych", "tm")

Le package comprend également une fonction pour installer plusieurs packages:

packages("plyr", "psych", "tm")

Référence ici .

Luchonacho
la source
Le nom de la fonction est plutôt déroutant / confus. «Bibliothèque», dans la libraryfonction, fait référence à l'emplacement où les packages sont installés: la bibliothèque de packages . Charger plusieurs paquets via librariesn'a aucun sens. Avoir une fonction distincte packagesqui fait autre chose ne fait qu'empirer les choses. Je sais que la dénomination est un problème difficile en génie logiciel, mais vraiment. Ces noms sont particulièrement mauvais.
Konrad Rudolph
2
@KonradRudolph Je ne suis pas d'accord pour dire que le nom librariesn'a aucun sens. C'est le pluriel de library, et librarycharge un seul paquet; librariescharge une pluralité d'emballages. Si vous pensez libraryque cela signifie «charger à partir de votre bibliothèque unique», et que vous étendez cela à libraries«charger à partir de plusieurs bibliothèques», alors ce n'est peut-être pas intuitif, mais ce n'est pas l'intention; Je serais très content du nom libraries.
Jamie S
@JamieS Mais c'est toujours (généralement) le chargement à partir d'une seule bibliothèque. Vous semblez confondre bibliothèque et package (ce qui, pour être honnête, est devenu courant dans R): La «bibliothèque R», comme mon commentaire précédent l'a indiqué, fait référence au (x) emplacement (s) (répertoire / répertoires) où les packages R sont installés . Dans l'exemple de cette réponse, «plyr», «psych» et «tm» ne sont pas des bibliothèques: ce sont des packages.
Konrad Rudolph
4

Vous pouvez simplement utiliser le package lubripack et il installe proprement les nouveaux packages, puis les charge tous sur une seule ligne.

lubripack("plyr", "psych", "tm")

Voici la sortie après avoir exécuté le code ci-dessus dans RStudio.

entrez la description de l'image ici

Comment installer le package:

Exécutez le code ci-dessous pour télécharger le package et l'installer à partir de GitHub. Pas besoin d'avoir un compte GitHub.

library(devtools)
install_github("espanta/lubripack")
Espanta
la source
5
Je suppose que l'utilisation d'images au lieu de texte
The Unfun Cat
3
Cela ne répond pas non plus à la question d'une manière qui n'a pas encore été répondue et semble être principalement de l'auto-promotion.
Tyler Rinker
Vous avez raison, j'ai essayé de répondre implicitement à la question. Permet de le rendre explicite en espérant qu'il peut être une réponse à une question.
Espanta
@TylerRinker Comment est-ce maintenant?
Espanta
3

En vous basant sur la solution de Daroczig, si vous ne souhaitez pas spécifier une liste comme entrée, vous pouvez utiliser

# Foo
mLoad <- function(...) {
  sapply(sapply(match.call(), as.character)[-1], require, character.only = TRUE)
}

# Example 
mLoad(plyr, dplyr, data.table)

... qui est plus court que

lapply(list('plyr', 'dplyr', 'data.table'), require, character.only = TRUE)
goclem
la source
2

J'utilise la fonction suivante:

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)
}

Cela tente de se charger, et si cela échoue, installe, puis essayez de charger à nouveau.

Ricardo
la source
2

Je pense que le code fourni par @daroczig peut être amélioré en remplaçant le requirepar libraryet en enveloppant l' lapplyappel dans la invisible()fonction. Ainsi, le code amélioré ressemblera à ce qui suit:

invisible(lapply(x, library, character.only = TRUE))

Ce code est amélioré car:

  1. library()est généralement préféré au require()chargement des paquets car le premier donne une erreur si le paquet n'est pas installé tandis que le second donne juste un avertissement. De plus, les require()appels library(), alors pourquoi ne pas simplement l'utiliser library()directement!

    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’
  2. L'objet de liste retourné et imprimé par l' lapply()appel n'a pas de sens dans ce cas, il est donc logique de rendre la sortie invisible. Supposons que vous utilisiez R Notebook pour votre travail d'analyse, l'utilisation de la invisible()fonction supprimera le contenu de l'objet de liste et empêchera l'encombrement dans le fichier de notebook rendu.

Ashirwad
la source
1

Léger mod de la réponse de Tyler Rinker pour ajouter un chèque pour installer et charger pacman:

#Install/load pacman
if(!require(pacman)){install.packages("pacman");require(pacman)}
#Install/load tons of packages
p_load(plyr,psych,tm)

J'aime la solution p_load car elle évite de citer!

Mattador
la source