Laden Sie mehrere Pakete gleichzeitig

174

Wie kann ich eine Reihe von Paketen gleichzeitig laden, ohne den Befehl require immer wieder neu einzugeben? Ich habe drei Ansätze ausprobiert, die alle abstürzen und brennen.

Grundsätzlich möchte ich einer Funktion, die sie lädt, einen Vektor mit Paketnamen bereitstellen.

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

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

Antworten:

251

Mehrere Permutationen Ihrer vorgeschlagenen Funktionen funktionieren - allerdings nur, wenn Sie das character.onlyArgument angeben TRUE. Kurzes Beispiel:

lapply(x, require, character.only = TRUE)
daroczig
quelle
@ Tommy & Daroczig - Cool. Das ist eine weitaus sauberere Lösung. Ich überlasse meine nur der Nachwelt und dem, was sie darüber zeigt, warum die Versuche des OP nicht funktioniert haben.
Josh O'Brien
4
Sie können die teilweise Zeichenübereinstimmung nutzen und mit lapply (x, require, ch = T) oder sogar lapply (x, require, c = T)
davonkommen
@daroczig Dieser Code lädt die Pakete, aber warum gibt er die folgenden Warnmeldungen aus: 1: In der Bibliothek (Paket, lib.loc = lib.loc, Zeichen.nur = TRUE, logisch.return = TRUE ,: Es wird kein Paket aufgerufen 'x' 2: In if (! geladen) {: Die Bedingung hat eine Länge> 1 und nur das erste Element wird verwendet
Anusha
@ Anusha: Ich habe keine Ahnung Geldautomat, was hast du in deinem x?
Daroczig
23
Seien Sie nett, wenn R :: base diesen lapplynativen Trick hinzugefügt hat library(). Seien Sie großartig, um sagen zu können:library(c("plyr", "umx"))
Tim
58

Das von mir gepflegte CRAN-Paket pacman (verfasst mit Dason Kurkiewicz) kann dies erreichen:

Der Benutzer könnte also Folgendes tun:

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

und wenn das Paket fehlt, p_loadwird es von CRAN oder Bioconductor heruntergeladen.

Tyler Rinker
quelle
7
+1! Warum hast du den Kurznamen gewählt p_load? Ein aussagekräftigerer Name wie load_packagesmacht die Absicht der Funktion klarer.
Paul Hiemstra
19
Weil das p für Paket steht. Jede nützliche und exportierte Funktion im Paket beginnt mit p_. Außerdem benutzen wir die Bibliothek ein bisschen und das sind zusätzliche 7 Zeichen. 7 Zeichen x ~ 1000000 Lebenszeitverwendung der Funktion x .5 Sekunden pro Zeichen = 3500000 Sekunden. Das sind 58333,33 Minuten, 972,2222 Stunden oder 40,50926 Tage des Lebens eines Programmierers, die wir ihnen zurückgegeben haben :-) Auf jeden Fall ist es unser Ziel, bis zum 1. Februar
Tyler Rinker am
3
Etwa ein Jahr zu spät, aber wir haben uns endlich bei CRAN gemeldet. Sollte in ein paar Tagen auf sein. @trinker (oder ich) stellen Sie sicher, dass Sie dies ändern, sobald es öffentlich wird.
Dason
5
@ Tyler Ich weiß, ich bin Jahre zu spät, aber ich finde deine Begründung für das p_Präfix ziemlich zweifelhaft. Wenn es um Knappheit geht, entfernen Sie das p_Präfix vollständig. Tatsächlich wird davon abgeraten, solche Präfixe in anderen Sprachen aus guten Gründen zu haben (ich habe Hadley gesagt, dass sie dies auch in Bezug auf seinen fct_Unsinn bei Forcats tun). Dies gilt insbesondere , da die beabsichtigte Verwendung des Pakets mit einem qualifizierten Namespace ( pacman::) erfolgt.
Konrad Rudolph
5
@TylerRinker Entschuldigung, dass Sie in dieser Angelegenheit kämpferisch sind, aber ich denke wirklich, dass die R-Community hier einfach falsch liegt und praktisch jede andere moderne Sprache es richtig macht: Sie sagen: "Dies schützt vor Namespace-Konflikten." - Aber dafür sind Namespaces da! Die Aufgabe der Paketschreiber besteht darin, die Benutzer zu erziehen, die Pakete ordnungsgemäß zu verwenden, und nicht ihren schlampigen Programmierpraktiken Rechnung zu tragen.
Konrad Rudolph
24

Dies sollte den Trick tun:

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

(Der Schlüssel Bit ist , dass das argsArgument do.call(what, args) muss eine Liste sein --- auch wenn es nur ein einziges Element hat!)

Josh O'Brien
quelle
16

Für jemanden, der Pakete gleichzeitig installieren und laden möchte, bin ich über diesen Link auf diese Funktion gestoßen

# 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
quelle
Hallo, ich habe eine R-Datei aus Ihrem angegebenen Snippet erstellt. Wenn ich dieses Skript im Amazon EMR-Dienst ausführe, erhalte ich die folgende Ausgabe, wie in der folgenden URL angegeben. pastie.org/10402378#3,10-11,13 .
Rubin Porwal
9

Eine alternative Option kommt aus dem Paket easypackages. Nach der Installation können Sie Pakete auf intuitivste Weise laden:

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

Das Paket enthält auch eine Funktion zum Installieren mehrerer Pakete:

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

Referenz hier .

Luchonacho
quelle
Der Funktionsname ist eher verwirrend / verwirrt. "Bibliothek" in der libraryFunktion bezieht sich auf den Speicherort, an dem Pakete installiert werden: die Paketbibliothek . Das Laden mehrerer Pakete über librariesmacht keinen Sinn. Eine separate Funktion packages, die etwas anderes bewirkt, macht dies nur noch schlimmer. Ich weiß, dass das Benennen ein schweres Problem in der Softwareentwicklung ist, aber wirklich. Diese Namen sind besonders schlecht.
Konrad Rudolph
2
@KonradRudolph Ich bin nicht der Meinung, dass der Name librarieskeinen Sinn ergibt . Es ist der Plural von libraryund librarylädt ein einzelnes Paket; librarieslädt mehrere Pakete. Wenn Sie sich library"Laden aus Ihrer einzelnen Bibliothek" vorstellen und dies auf libraries"Laden aus mehreren Bibliotheken" erweitern, ist dies möglicherweise nicht intuitiv, aber das ist nicht die Absicht. Ich würde mich sehr über den Namen freuen libraries.
Jamie S
@JamieS Aber es ist immer noch ( in der Regel) Laden aus einer einzigen Bibliothek. Sie scheinen Bibliothek und Paket zu verwechseln (was, um fair zu sein, in R üblich geworden ist): Die „R-Bibliothek“ bezieht sich, wie in meinem vorherigen Kommentar angegeben, auf die Speicherorte (Verzeichnisse / Verzeichnisse), an denen R-Pakete installiert sind . Im Beispiel dieser Antwort sind "plyr", "psych" und "tm" keine Bibliotheken, sondern Pakete.
Konrad Rudolph
4

Sie können einfach das lubripack-Paket verwenden und es installiert ordentlich neue Pakete und lädt dann alle in einer Zeile.

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

Hier ist die Ausgabe, nachdem Sie den obigen Code in RStudio ausgeführt haben.

Geben Sie hier die Bildbeschreibung ein

So installieren Sie das Paket:

Führen Sie den folgenden Code aus, um das Paket herunterzuladen und von GitHub zu installieren. GitHub-Konto ist nicht erforderlich.

library(devtools)
install_github("espanta/lubripack")
Espanta
quelle
5
Ich würde raten, Bilder anstelle von Text zu verwenden
The Unfun Cat
3
Dies beantwortet die Frage auch nicht auf eine Weise, die noch nicht beantwortet wurde, und scheint größtenteils Eigenwerbung zu sein.
Tyler Rinker
Sie haben Recht, ich habe versucht, die Frage implizit zu beantworten. Machen wir es explizit und hoffen, dass es eine Antwort auf die Frage sein kann.
Espanta
@ TylerRinker Wie ist das jetzt?
Espanta
3

Aufbauend auf der Lösung von daroczig können Sie eine Liste als Eingabe angeben, die Sie verwenden können

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

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

... was kürzer ist als

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

Ich benutze die folgende Funktion:

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

Dies versucht zu laden, und wenn es fehlschlägt, installiert und dann erneut zu laden.

Ricardo
quelle
2

Ich denke , dass der Code, der @daroczig hat , kann durch den Austausch der verbessert werden bereitgestellt requiremit libraryund das Einwickeln der lapplyAnruf innerhalb der invisible()Funktion. Der verbesserte Code sieht also folgendermaßen aus:

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

Dieser Code wurde verbessert, weil:

  1. library()wird im Allgemeinen require()zum Laden von Paketen bevorzugt, da erstere einen Fehler ausgibt, wenn das Paket nicht installiert ist, während letztere nur eine Warnung ausgibt. Darüber hinaus require()Anrufe library(), warum also nicht einfach library()direkt nutzen !

    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. Das vom lapply()Aufruf zurückgegebene und gedruckte Listenobjekt ist in diesem Fall nicht aussagekräftig. Daher ist es sinnvoll, die Ausgabe unsichtbar zu machen. Angenommen, Sie verwenden R Notebook für Ihre Analysearbeit. Wenn Sie die invisible()Funktion verwenden, wird der Inhalt des Listenobjekts unterdrückt und die Unordnung in der gerenderten Notebook-Datei verhindert.

Ashirwad
quelle
1

Leichte Modifikation von Tyler Rinkers Antwort, um einen Check zum Installieren und Laden von Pacman hinzuzufügen:

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

Ich mag die p_load-Lösung, weil sie das Zitieren vermeidet!

Mattador
quelle