443 Stimmen

Elegante Methode, um nach fehlenden Paketen zu suchen und sie zu installieren?

Ich scheine in letzter Zeit eine Menge Code mit Koautoren zu teilen. Viele von ihnen sind Anfänger oder fortgeschrittene R-Nutzer und wissen nicht, dass sie Pakete installieren müssen, die sie noch nicht haben.

Gibt es einen eleganten Weg zum Aufruf von installed.packages() vergleichen Sie diese mit denen, die ich lade, und installieren Sie sie, falls sie fehlen?

1 Stimmen

@krlmlr Was ist mit der akzeptierten Antwort, die nicht mehr aktuell ist und überarbeitet werden muss? Bei mir funktioniert es (für ein paar schnelle Tests) unter R version 3.0.2 (2013-09-25) x86_64-w64-mingw32/x64 (64-bit) .

1 Stimmen

@BrianDiggs: Es sind mindestens drei Pakete aufgetaucht, die sich mit diesem Problem befassen, nur auf eines wird unten verwiesen. Gibt es noch mehr - das ist die Frage.

3 Stimmen

@krlmlr Es scheint eine Art ironisches Huhn-Ei-Problem zu geben, wenn man ein Paket verwendet, um sicherzustellen, dass (andere) notwendige Pakete haben. Aber es ist sicher wert, dass jemand, der sich damit auskennt, eine Antwort schreibt.

403voto

Shane Punkte 95376

Ja. Wenn Sie Ihre Liste der Pakete haben, vergleichen Sie sie mit der Ausgabe von installed.packages()[,"Package"] und installieren Sie die fehlenden Pakete. Etwa so:

list.of.packages <- c("ggplot2", "Rcpp")
new.packages <- list.of.packages[!(list.of.packages %in% installed.packages()[,"Package"])]
if(length(new.packages)) install.packages(new.packages)

Ansonsten:

Wenn Sie Ihren Code in ein Paket packen und zu Abhängigkeiten machen, werden sie automatisch installiert, wenn Sie Ihr Paket installieren.

314voto

Tyler Rinker Punkte 103407

Dason K. und ich haben die pacman Paket, das dies sehr gut kann. Die Funktion p_load in dem Paket tut dies. Die erste Zeile soll nur sicherstellen, dass pacman installiert ist.

if (!require("pacman")) install.packages("pacman")
pacman::p_load(package1, package2, package_n)

90voto

Livius Punkte 3077

Sie können einfach den Rückgabewert von require :

if(!require(somepackage)){
    install.packages("somepackage")
    library(somepackage)
}

Ich benutze library nach der Installation, weil es eine Ausnahme auslöst, wenn die Installation nicht erfolgreich war oder das Paket aus einem anderen Grund nicht geladen werden kann. Sie machen dies robuster und wiederverwendbar:

dynamic_require <- function(package){
  if(eval(parse(text=paste("require(",package,")")))) return(TRUE)

  install.packages(package)
  return(eval(parse(text=paste("require(",package,")"))))
}

Der Nachteil dieser Methode ist, dass Sie den Paketnamen in Anführungszeichen übergeben müssen, was Sie bei der echten Methode nicht tun. require .

52voto

Matthew Punkte 3862

Viele der obigen Antworten (und auf Duplikate dieser Frage) stützen sich auf installed.packages was eine schlechte Form ist. Aus der Dokumentation:

Dies kann langsam sein, wenn Tausende von Paketen installiert sind. Verwenden Sie dies also nicht, um herauszufinden, ob ein benanntes Paket installiert ist (verwenden Sie system.file oder find.package), oder um herauszufinden, ob ein Paket verwendbar ist (rufen Sie require auf und prüfen Sie den Rückgabewert), oder um Details über eine kleine Anzahl von Paketen zu finden (verwenden Sie packageDescription). Es muss mehrere Dateien pro installiertem Paket lesen, was unter Windows und auf einigen im Netzwerk eingebundenen Dateisystemen langsam ist.

Ein besserer Ansatz ist es also, zu versuchen, das Paket mit require und installieren, wenn das Laden fehlschlägt ( require wird zurückgegeben FALSE wenn es nicht gefunden wird). Ich bevorzuge diese Implementierung:

using<-function(...) {
    libs<-unlist(list(...))
    req<-unlist(lapply(libs,require,character.only=TRUE))
    need<-libs[req==FALSE]
    if(length(need)>0){ 
        install.packages(need)
        lapply(need,require,character.only=TRUE)
    }
}

die wie folgt verwendet werden kann:

using("RCurl","ggplot2","jsonlite","magrittr")

Auf diese Weise werden alle Pakete geladen, dann werden alle fehlenden Pakete installiert (dies ist ein praktischer Ort, um eine Eingabeaufforderung einzufügen, die den Benutzer fragt, ob er Pakete installieren möchte). Anstatt den Aufruf install.packages separat für jedes Paket übergibt es den gesamten Vektor der deinstallierten Pakete nur einmal.

Hier ist die gleiche Funktion, aber mit einem Windows-Dialog, der den Benutzer fragt, ob er die fehlenden Pakete installieren möchte

using<-function(...) {
    libs<-unlist(list(...))
    req<-unlist(lapply(libs,require,character.only=TRUE))
    need<-libs[req==FALSE]
    n<-length(need)
    if(n>0){
        libsmsg<-if(n>2) paste(paste(need[1:(n-1)],collapse=", "),",",sep="") else need[1]
        print(libsmsg)
        if(n>1){
            libsmsg<-paste(libsmsg," and ", need[n],sep="")
        }
        libsmsg<-paste("The following packages could not be found: ",libsmsg,"\n\r\n\rInstall missing packages?",collapse="")
        if(winDialog(type = c("yesno"), libsmsg)=="YES"){       
            install.packages(need)
            lapply(need,require,character.only=TRUE)
        }
    }
}

40voto

user6784955 Punkte 361
if (!require('ggplot2')) install.packages('ggplot2'); library('ggplot2')

"ggplot2" ist das Paket. Es wird geprüft, ob das Paket installiert ist, und wenn nicht, wird es installiert. Anschließend wird das Paket geladen, unabhängig davon, welchen Zweig es genommen hat.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X