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.

35voto

MichaelChirico Punkte 32476

TL;DR können Sie verwenden find.package() für diese.

Fast alle Antworten beruhen entweder auf (1) require() oder (2) installed.packages() um zu prüfen, ob ein bestimmtes Paket bereits installiert ist oder nicht.

Ich füge eine Antwort hinzu, weil diese für einen leichtgewichtigen Ansatz zur Beantwortung dieser Frage nicht zufriedenstellend sind.

  • require hat den Nebeneffekt, dass der Namespace des Pakets geladen wird, was nicht immer erwünscht sein mag
  • installed.packages ist eine Bazooka, um eine Kerze anzuzünden - sie wird die das Universum der installierten Pakete, dann prüfen wir, ob unser(e) Paket(e) in dieser Bibliothek "vorrätig" sind. Es ist nicht nötig, einen Heuhaufen zu bauen, nur um eine Nadel zu finden.

Diese Antwort wurde auch inspiriert durch Die großartige Antwort von @ArtemKlevtsov in ähnlichem Sinne zu einer duplizierten Version dieser Frage. Er stellte fest, dass system.file(package=x) kann die gewünschte Wirkung haben, nämlich die Rückkehr '' wenn das Paket nicht installiert ist, und etwas mit nchar > 1 sonst.

Wenn wir unter die Haube schauen, wie system.file dies erreicht, können wir sehen, dass es eine andere base Funktion, find.package die wir direkt verwenden können:

# a package that exists
find.package('data.table', quiet=TRUE)
# [1] "/Library/Frameworks/R.framework/Versions/4.0/Resources/library/data.table"

# a package that does not
find.package('InstantaneousWorldPeace', quiet=TRUE)
# character(0)

Wir können auch einen Blick unter die Haube werfen find.package um zu sehen, wie es funktioniert, aber das ist hauptsächlich eine lehrreiche Übung - die einzige Möglichkeit, die Funktion zu verschlanken, die ich sehe, wäre, einige Robustheitsüberprüfungen zu überspringen. Aber die Grundidee ist: Schau in .libPaths() -- jedes installierte Paket pkg haben eine DESCRIPTION Datei unter file.path(.libPaths(), pkg) Eine schnelle und einfache Prüfung ist also file.exists(file.path(.libPaths(), pkg, 'DESCRIPTION') .

24voto

Simon O'Hanlon Punkte 56969

Diese Lösung nimmt einen Zeichenvektor von Paketnamen und versucht, sie zu laden oder zu installieren, wenn das Laden fehlschlägt. Sie verlässt sich auf das Rückgabeverhalten von require um dies zu tun, weil...

require gibt (unsichtbar) eine Logik zurück, die angibt, ob das gewünschte Paket verfügbar ist

Daher können wir einfach sehen, ob wir das benötigte Paket laden konnten, und wenn nicht, es mit Abhängigkeiten installieren. Geben Sie also einen Zeichenvektor von Paketen an, die Sie laden möchten...

foo <- function(x){
  for( i in x ){
    #  require returns TRUE invisibly if it was able to load package
    if( ! require( i , character.only = TRUE ) ){
      #  If package was not able to be loaded then re-install
      install.packages( i , dependencies = TRUE )
      #  Load package after installing
      require( i , character.only = TRUE )
    }
  }
}

#  Then try/install packages...
foo( c("ggplot2" , "reshape2" , "data.table" ) )

16voto

Juan Antonio Cano Punkte 387

Obwohl die Antwort von Shane wirklich gut ist, musste ich für eines meiner Projekte die Ausgabemeldungen und Warnungen entfernen und Pakete installieren automagisch . Ich habe es endlich geschafft, dieses Skript zu bekommen:

InstalledPackage <- function(package) 
{
    available <- suppressMessages(suppressWarnings(sapply(package, require, quietly = TRUE, character.only = TRUE, warn.conflicts = FALSE)))
    missing <- package[!available]
    if (length(missing) > 0) return(FALSE)
    return(TRUE)
}

CRANChoosen <- function()
{
    return(getOption("repos")["CRAN"] != "@CRAN@")
}

UsePackage <- function(package, defaultCRANmirror = "http://cran.at.r-project.org") 
{
    if(!InstalledPackage(package))
    {
        if(!CRANChoosen())
        {       
            chooseCRANmirror()
            if(!CRANChoosen())
            {
                options(repos = c(CRAN = defaultCRANmirror))
            }
        }

        suppressMessages(suppressWarnings(install.packages(package)))
        if(!InstalledPackage(package)) return(FALSE)
    }
    return(TRUE)
}

Verwendung:

libraries <- c("ReadImages", "ggplot2")
for(library in libraries) 
{ 
    if(!UsePackage(library))
    {
        stop("Error!", library)
    }
}

15voto

Brian Spiering Punkte 852
# List of packages for session
.packages = c("ggplot2", "plyr", "rms")

# Install CRAN packages (if not already installed)
.inst <- .packages %in% installed.packages()
if(length(.packages[!.inst]) > 0) install.packages(.packages[!.inst])

# Load packages into session 
lapply(.packages, require, character.only=TRUE)

8voto

mtelesha Punkte 1899

Verwenden Sie packrat so dass die gemeinsam genutzten Bibliotheken genau gleich sind und die Umgebung der anderen nicht verändern.

Was die Eleganz und die besten Praktiken betrifft, so denke ich, dass Sie die Sache grundsätzlich falsch angehen. Das Paket packrat wurde für diese Probleme entwickelt. Es wird von RStudio von Hadley Wickham entwickelt. Anstatt dass sie Abhängigkeiten installieren und möglicherweise jemandes Umgebungssystem durcheinanderbringen müssen, packrat verwendet ein eigenes Verzeichnis und installiert dort alle Abhängigkeiten für Ihre Programme und berührt nicht die Umgebung eines anderen.

Packrat ist ein Abhängigkeitsmanagementsystem für R.

Abhängigkeiten von R-Paketen können frustrierend sein. Mussten Sie schon einmal durch Ausprobieren herausfinden, welche R-Pakete Sie installieren müssen, damit der Code von jemand anderem funktioniert - und mussten dann feststellen, dass diese Pakete für immer global installiert sind, weil Sie nicht sicher sind, ob Sie sie brauchen? Haben Sie jemals ein Paket aktualisiert, um den Code in einem Ihrer Projekte zum Laufen zu bringen, nur um festzustellen, dass das aktualisierte Paket den Code in einem anderen Projekt nicht mehr zum Laufen bringt?

Wir haben packrat entwickelt, um diese Probleme zu lösen. Verwenden Sie packrat, um Ihre R-Projekte zu verbessern:

  • Isoliert: Wenn Sie ein neues oder aktualisiertes Paket für ein Projekt installieren, werden Ihre anderen Projekte nicht beschädigt und umgekehrt. Das liegt daran, dass packrat jedem Projekt seine eigene private Paketbibliothek zur Verfügung stellt.
  • Tragbar: Transportieren Sie Ihre Projekte einfach von einem Computer zum anderen, auch über verschiedene Plattformen hinweg. Packrat macht es einfach, die Pakete zu installieren, von denen Ihr Projekt abhängt.
  • Reproduzierbar: Packrat zeichnet die genauen Paketversionen auf, auf die Sie angewiesen sind, und stellt sicher, dass genau diese Versionen installiert werden, wo immer Sie hingehen.

https://rstudio.github.io/packrat/

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