Elegancki sposób na sprawdzenie brakujących pakietów i ich instalację?


336

Wydaje mi się, że w dzisiejszych czasach udostępniam dużo kodu współautorom. Wielu z nich to początkujący / średniozaawansowani użytkownicy R i nie zdają sobie sprawy, że muszą instalować pakiety, których jeszcze nie mają.

Czy istnieje elegancki sposób na połączenie installed.packages(), porównaj to z tymi, które ładuję i zainstaluj, jeśli go brakuje?


1
@krlmlr Co z zaakceptowaną odpowiedzią jest nieaktualna i wymaga korekty? Działa dla mnie (na kilka szybkich testów) pod R version 3.0.2 (2013-09-25) x86_64-w64-mingw32/x64 (64-bit).
Brian Diggs,

1
@BrianDiggs: Pojawiły się co najmniej trzy pakiety, które rozwiązują ten problem, tylko jeden jest wymieniony poniżej. Czy jest jeszcze więcej - oto jest pytanie.
krlmlr

2
@krlmlr Wygląda na to, że jest trochę ironiczny problem z kurczakiem i jajkiem przy korzystaniu z pakietu w celu zapewnienia (innym) posiadania niezbędnych pakietów. Ale na pewno warto mieć kogoś, kto o nich wie, że napisze odpowiedź.
Brian Diggs,

2
@BrianDiggs: ładowanie tego pakietu sprawdzającego instalację jest konieczną uciążliwością, ale małą. O ile, oczywiście, funkcjonalność nie znajdzie się w base... ;-)
krlmlr

Odpowiedzi:


304

Tak. Jeśli masz listę pakietów, porównaj ją z danymi wyjściowymi installed.packages()[,"Package"]i zainstaluj brakujące pakiety. Coś takiego:

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)

Inaczej:

Jeśli umieścisz swój kod w pakiecie i uzależnisz je, zostaną one automatycznie zainstalowane podczas instalacji pakietu.


11
Myślę, że poprawna składnia to: if(length(new.packages)>0) {install.packages(new.packages)}

5
@psql, Shine ma rację, ponieważ „> 0” jest „niejawne” w ramach warunku if. uruchom to, aby to sprawdzić:new.packages <- c(1,2) length(new.packages) if(length(new.packages)){print("hello!")}else{print("oh no!")}
Andrea Cirillo

7
Dokument install.packages mówi: „Może to być powolne, gdy tysiące pakietów są zainstalowane, więc nie używaj tego, aby dowiedzieć się, czy pakiet nazwany jest zainstalowany (użyj pliku system.file lub find.package) ...”
Thomas Materna

2
Zgadzam się z Thomasem, to byłby lepszy występ requirezamiast sprawdzaniainstalled.packages
Matthew

1
packratzostał stworzony do tego. Jest to powtarzalny system zarządzania pakietami. W ten sposób idzie to w niewłaściwy sposób i miesza się z czyimś środowiskiem, a nie jest odtwarzalne. Packrat ma własny folder i środowisko dla bibliotek współdzielonych. rstudio.github.io/packrat
mtelesha,

231

Dason K. i mam pacman pakiet, który może to zrobić ładnie. Funkcja p_loadw pakiecie to robi. Pierwszy wiersz ma na celu upewnienie się, że Pacman jest zainstalowany.

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

1
Jaki jest status paczki? Nie widzę w C-RAN.
MERose


6
Zainstalowałem teraz i działa wspaniale; powinien być częścią bazy!
AndyF

3
Jedynym sposobem byłoby lepiej, gdyby sprawdził /i automatycznie zainstalował / załadował z github.
nalot

4
@NealBarsch, jeśli masz na myśli funkcję Pacmana, która if (!require("pacman")) install.packages("pacman")nazywa się p_boot()tą linią dla Ciebie automatycznie i kopiuje ją do schowka.
Tyler Rinker,

72

Możesz po prostu użyć zwracanej wartości require:

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

Używam librarypo instalacji, ponieważ spowoduje to wyjątek, jeśli instalacja nie powiedzie się lub pakiet nie może zostać załadowany z innego powodu. Sprawiasz, że jest to bardziej niezawodne i wielokrotnego użytku:

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

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

Minusem tej metody jest to, że musisz przekazać nazwę pakietu w cudzysłowie, czego nie robisz tak naprawdę require.


4
Można uprościć swoje życie wiele używając character.only = TRUEw require, ale to chyba nie ma nic do odróżnienia odpowiedź od kopalni.
Simon O'Hanlon

Wygląda to ładnie, ale wydaje się, że nie działa, przynajmniej dla mnie. Kiedy wypróbowałem solidną wersję tego, otrzymuję dwa komunikaty o błędach, ponieważ R z jakiegoś powodu nie wie, jak obsługiwać „return True” i „return eval”. Tak więc naprawdę chciałbym taką funkcję, która ładuje pakiet, jeśli jest obecny w mojej bibliotece i w inny sposób instaluje (a następnie ładuje) pakiet. Idealnie byłoby wtedy użyć tego jako domyślnego do ładowania pakietów. Przynajmniej wydaje się, że miałoby to sens i pozwoliłoby zaoszczędzić trochę czasu.
Fabian Habersack

23
if (!require('ggplot2')) install.packages('ggplot2'); library('ggplot2')

„ggplot2” to pakiet. Sprawdza, czy pakiet jest zainstalowany, jeśli nie jest, to go instaluje. Następnie ładuje pakiet bez względu na wybraną gałąź.


21

To rozwiązanie pobierze wektor znakowy nazw pakietów i spróbuje je załadować lub zainstalować, jeśli ładowanie się nie powiedzie. Polega na zachowaniu powrotu w requirecelu wykonania tej czynności, ponieważ ...

require zwraca (niewidocznie) logiczne wskazanie, czy wymagany pakiet jest dostępny

Dlatego możemy po prostu zobaczyć, czy udało nam się załadować wymagany pakiet, a jeśli nie, zainstaluj go z zależnościami. Biorąc pod uwagę wektor znaków pakietów, które chcesz załadować ...

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

Czy nie chcesz requireponownie zadzwonić po instalacji?
krlmlr

@krlmlr Nie, ponieważ ifaby ocenić instrukcję, należy ją najpierw ocenić require, której efektem ubocznym jest ładowanie pakietu, jeśli jest dostępny!
Simon O'Hanlon,

1
SimonO101: Myślę, że krlmlr oznacza w instrukcji if po wywołaniu install.packages, ponieważ tak naprawdę nie załadowałoby tego pakietu. Ale (do @krlmlr) podejrzewam, że intencją jest, aby ten fragment kodu był wywoływany tylko raz; nie pisałbyś tego za każdym razem, gdy potrzebowałeś pakietu. Zamiast tego uruchomisz go raz przed czasem, a następnie zadzwonisz requiretak, jak to konieczne.
Aaron opuścił Stack Overflow

@Aaron ah tak ok, rozumiem, co masz na myśli i tak, twoja interpretacja jest poprawna. Zmodyfikuję go nieco, aby bardziej precyzyjnie określić ładowanie po instalacji.
Simon O'Hanlon

1
Czy nie byłoby lepiej, aby drugie requirewezwanie do librarytak głośno, że nie powiedzie się, jeśli jest jeszcze w stanie dołączyć pakiet z jakiegoś powodu?
kabdulla,

18

Wiele powyższych odpowiedzi (i duplikatów tego pytania) opiera się na installed.packageszłej formie. Z dokumentacji:

Może to być powolne, gdy tysiące pakietów są zainstalowane, więc nie używaj tego, aby dowiedzieć się, czy nazwany pakiet jest zainstalowany (użyj pliku system.file lub find.package), ani nie dowiedz się, czy pakiet jest użyteczny (wywołanie wymaga i sprawdź wartość zwracana) ani w celu znalezienia szczegółów niewielkiej liczby pakietów (użyj packageDescription). Musi odczytać kilka plików na zainstalowany pakiet, co będzie wolne w systemie Windows i niektórych systemach plików podłączonych do sieci.

Lepszym rozwiązaniem jest próba załadowania pakietu przy użyciu requirei instalacji, jeśli ładowanie się nie powiedzie ( requirezwróci, FALSEjeśli nie zostanie znalezione). Wolę tę implementację:

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

które mogą być użyte w ten sposób:

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

W ten sposób ładuje wszystkie pakiety, a następnie wraca i instaluje wszystkie brakujące pakiety (co jeśli chcesz, to przydatne miejsce, aby wstawić monit z pytaniem, czy użytkownik chce zainstalować pakiety). Zamiast wywoływać install.packagesosobno dla każdego pakietu, przekazuje cały wektor odinstalowanych pakietów tylko raz.

Oto ta sama funkcja, ale z oknem dialogowym z pytaniem, czy użytkownik chce zainstalować brakujące pakiety

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

Jest to dość elegancki sposób, znacznie lepszy niż przyjęty. Uwzględnię to w mojej osobistej bibliotece. Dzięki.
Bing,

15

Chociaż odpowiedź Shane'a jest naprawdę dobra, dla jednego z moich projektów musiałem usunąć komunikaty wyjściowe, ostrzeżenia i zautomatyzować instalację pakietów . W końcu udało mi się zdobyć ten skrypt:

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

Posługiwać się:

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

9
# 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)

6

Taki jest cel pakietu rbundler : zapewnienie sposobu kontrolowania pakietów zainstalowanych dla konkretnego projektu. W tej chwili pakiet współpracuje z funkcją devtools w celu instalowania pakietów w katalogu twojego projektu. Funkcjonalność jest podobna do programu pakującego Ruby .

Jeśli twój projekt to pakiet (zalecane), wszystko, co musisz zrobić, to załadować pakiet rbundler i spakować pakiety. bundleFunkcja będzie wyglądać na swój pakiet w DESCRIPTIONpliku, aby określić, które pakiety do wiązki.

library(rbundler)
bundle('.', repos="http://cran.us.r-project.org")

Teraz pakiety zostaną zainstalowane w katalogu .Rbundle.

Jeśli twój projekt nie jest pakietem, możesz go sfałszować, tworząc DESCRIPTIONplik w katalogu głównym projektu za pomocą pola Depends, które zawiera listę pakietów, które chcesz zainstalować (z opcjonalnymi informacjami o wersji):

Depends: ggplot2 (>= 0.9.2), arm, glmnet

Oto repozytorium github dla projektu, jeśli jesteś zainteresowany udziałem: rbundler .


5

Pewnie.

Musisz porównać „zainstalowane pakiety” z „pożądanymi pakietami”. Jest to bardzo zbliżone do tego, co robię z CRANberries, ponieważ muszę porównać „przechowywane znane pakiety” z „obecnie znanymi pakietami”, aby określić nowe i / lub zaktualizowane pakiety.

Więc zrób coś takiego

AP <- available.packages(contrib.url(repos[i,"url"]))   # available t repos[i]

aby uzyskać wszystkie znane pakiety, należy wywołać symetrycznie aktualnie zainstalowane pakiety i porównać je z danym zestawem pakietów docelowych.


5

Użyj, packrataby udostępnione biblioteki były dokładnie takie same i nie zmieniały środowiska innych osób.

Jeśli chodzi o elegancję i najlepsze praktyki, myślę, że zasadniczo postępujesz w niewłaściwy sposób. Pakiet packratzostał zaprojektowany z myślą o tych problemach. Jest rozwijany przez RStudio przez Hadley Wickham. Zamiast instalować zależności i być może zepsuć czyjś system środowiskowy, packratużywa własnego katalogu i instaluje wszystkie zależności dla twoich programów tam i nie dotyka czyjegoś środowiska.

Packrat to system zarządzania zależnościami dla R.

Zależności od pakietu R mogą być frustrujące. Czy kiedykolwiek musiałeś użyć metody prób i błędów, aby dowiedzieć się, które pakiety R należy zainstalować, aby czyjś kod działał, a następnie pozostawiono Ci te pakiety globalnie zainstalowane na zawsze, ponieważ teraz nie masz pewności, czy ich potrzebujesz ? Czy kiedykolwiek zaktualizowałeś pakiet, aby kod w jednym ze swoich projektów działał, a okazało się, że zaktualizowany pakiet powoduje, że kod w innym projekcie przestaje działać?

Zbudowaliśmy packrat, aby rozwiązać te problemy. Użyj packrat, aby Twoje projekty R były bardziej:

  • Izolowane: zainstalowanie nowego lub zaktualizowanego pakietu dla jednego projektu nie spowoduje uszkodzenia innych projektów i odwrotnie. To dlatego, że packrat daje każdemu projektowi swoją prywatną bibliotekę pakietów.
  • Przenośne: łatwo transportuj projekty z jednego komputera na drugi, nawet na różnych platformach. Packrat ułatwia instalację pakietów, od których zależy Twój projekt.
  • Powtarzalność: Packrat rejestruje dokładne wersje pakietów, na których polegasz, i zapewnia, że ​​te dokładne wersje są instalowane gdziekolwiek jesteś.

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


4

Następująca prosta funkcja działa jak urok:

  usePackage<-function(p){
      # load a package if installed, else load after installation.
      # Args:
      #   p: package name in quotes

      if (!is.element(p, installed.packages()[,1])){
        print(paste('Package:',p,'Not found, Installing Now...'))
        install.packages(p, dep = TRUE)}
      print(paste('Loading Package :',p))
      require(p, character.only = TRUE)  
    }

(nie moje, znalazłem to w sieci jakiś czas temu i używałem go od tego czasu. nie jestem pewien, czy oryginalne źródło)


4

Korzystam z następującej funkcji, aby zainstalować pakiet, jeśli require("<package>")wychodzi z błędem pakiet nie znaleziono. Przeszukuje zarówno repozytoria CRAN, jak i repozytoria Bioconductor pod kątem brakującego pakietu.

Na podstawie oryginalnej pracy Joshua Wileya, http://r.789695.n4.nabble.com/Install-package-automatically-if-not-there-td2267532.html

install.packages.auto <- function(x) { 
  x <- as.character(substitute(x)) 
  if(isTRUE(x %in% .packages(all.available=TRUE))) { 
    eval(parse(text = sprintf("require(\"%s\")", x)))
  } else { 
    #update.packages(ask= FALSE) #update installed packages.
    eval(parse(text = sprintf("install.packages(\"%s\", dependencies = TRUE)", x)))
  }
  if(isTRUE(x %in% .packages(all.available=TRUE))) { 
    eval(parse(text = sprintf("require(\"%s\")", x)))
  } else {
    source("http://bioconductor.org/biocLite.R")
    #biocLite(character(), ask=FALSE) #update installed packages.
    eval(parse(text = sprintf("biocLite(\"%s\")", x)))
    eval(parse(text = sprintf("require(\"%s\")", x)))
  }
}

Przykład:

install.packages.auto(qvalue) # from bioconductor
install.packages.auto(rNMF) # from CRAN

PS: update.packages(ask = FALSE)i biocLite(character(), ask=FALSE)zaktualizuje wszystkie zainstalowane pakiety w systemie. Może to zająć dużo czasu i uznać to za pełne ulepszenie R, co może nie być gwarantowane przez cały czas!


Można to poprawić, sprawdzając, czy pakiety są rzeczywiście dostępne na platformie cran lub bc. Powinien także użyć biblioteki na końcu, aby zgłosić błąd, jeśli instalacja się nie powiedzie lub pakiet nie istnieje. Zobacz moje ulepszoną wersję o nazwie loadpack()na raw.githubusercontent.com/holgerbrandl/datautils/master/R/...
Holger Brandl

4

Możesz po prostu użyć tej setdifffunkcji, aby uzyskać pakiety, które nie są zainstalowane, a następnie je zainstalować. W poniższym przykładzie sprawdzamy, czy pakiety ggplot2i Rcppsą zainstalowane przed ich zainstalowaniem.

unavailable <- setdiff(c("ggplot2", "Rcpp"), rownames(installed.packages()))
install.packages(unavailable)

W jednym wierszu powyższe można zapisać jako:

install.packages(setdiff(c("ggplot2", "Rcpp"), rownames(installed.packages())))

Używam tego samego podejścia. Możemy również użyć installed.packages()[,'Package']zamiast rownames(installed.packages()).
Scudelletti

3

Zaimplementowałem funkcję cichego instalowania i ładowania wymaganych pakietów R. Nadzieja może pomóc. Oto kod:

# Function to Install and Load R Packages
Install_And_Load <- function(Required_Packages)
{
    Remaining_Packages <- Required_Packages[!(Required_Packages %in% installed.packages()[,"Package"])];

    if(length(Remaining_Packages)) 
    {
        install.packages(Remaining_Packages);
    }
    for(package_name in Required_Packages)
    {
        library(package_name,character.only=TRUE,quietly=TRUE);
    }
}

# Specify the list of required packages to be installed and load    
Required_Packages=c("ggplot2", "Rcpp");

# Call the Function
Install_And_Load(Required_Packages);

3

Nadchodząca wersja RStudio (1.2), już dostępna w wersji zapoznawczej, będzie zawierać funkcję wykrywania brakujących pakietów library()i require()wywołań oraz monitowania użytkownika o ich zainstalowanie:

Wykryj brakujące pakiety R.

Wiele skryptów R otwiera się z wywołaniami library()i require()ładowaniem pakietów potrzebnych do wykonania. Jeśli otworzysz skrypt R, który odwołuje się do pakietów, które nie zostały jeszcze zainstalowane, RStudio zaoferuje teraz instalację wszystkich potrzebnych pakietów jednym kliknięciem. Nigdy więcej wpisywania, install.packages()dopóki błędy nie znikną!
https://blog.rstudio.com/2018/11/19/rstudio-1-2-preview-the-little-things/

Wydaje się, że szczególnie dobrze odnosi się to do pierwotnego problemu PO:

Wielu z nich to początkujący / średniozaawansowani użytkownicy R i nie zdają sobie sprawy, że muszą instalować pakiety, których jeszcze nie mają.


2

Jeśli chodzi o twój główny cel „zainstalować biblioteki, których jeszcze nie mają.” I bez względu na użycie „instllaed.packages ()”. Poniższa funkcja maskuje pierwotną funkcję wymaganą. Próbuje załadować i sprawdzić nazwany pakiet „x”, jeśli nie jest zainstalowany, zainstaluj go bezpośrednio z uwzględnieniem zależności; i na koniec załaduj go normalnie. zmieniasz nazwę funkcji z „wymagaj” na „biblioteka”, aby zachować integralność. Jedynym ograniczeniem jest cytowanie nazw pakietów.

require <- function(x) { 
  if (!base::require(x, character.only = TRUE)) {
  install.packages(x, dep = TRUE) ; 
  base::require(x, character.only = TRUE)
  } 
}

Możesz więc załadować i zainstalować pakiet staromodny sposób R. wymaga („ggplot2”) wymaga („Rcpp”)


Jeśli nie podoba ci się już odpowiedź, nie niszcz jej - po prostu ją usuń.
Michael Petrotta

Próbowałem, ale nie mogłem. Wydaje mi się, że moje rozszerzenie FF w NoScript wyłącza je lub nie mam uprawnień ani kredytów, aby usunąć własną odpowiedź. LoL Myślę jednak, że Livius jest dość blisko mojej odpowiedzi, pomyślał bez maskowania. Dzięki Michael Petrotta. do powiadomienia.
GeoObserver,

Powinieneś zobaczyć deletelink nad tymi komentarzami. Jeśli nie, a nadal chcesz usunąć, użyj flaglinku, wybierz „inne” i wyjaśnij moderatorowi, że chcesz usunąć odpowiedź.
Michael Petrotta,

2

Całkiem podstawowy.

pkgs = c("pacman","data.table")
if(length(new.pkgs <- setdiff(pkgs, rownames(installed.packages())))) install.packages(new.pkgs)

2

Pomyślałem, że wrócę do tego, którego używam:

testin <- function(package){if (!package %in% installed.packages())    
install.packages(package)}
testin("packagename")

2
source("https://bioconductor.org/biocLite.R")
if (!require("ggsci")) biocLite("ggsci")

2

Używając rodzinnej rodziny i anonimowego podejścia do funkcji, możesz:

  1. Spróbuj załączyć wszystkie wymienione pakiety.
  2. Zainstaluj tylko brakujące (przy użyciu ||leniwej oceny).
  3. Spróbuj ponownie dołączyć te, których brakowało w kroku 1 i zainstalowano w kroku 2.
  4. Wydrukuj stan końcowego obciążenia każdej paczki ( TRUE/ FALSE).

    req <- substitute(require(x, character.only = TRUE))
    lbs <- c("plyr", "psych", "tm")
    sapply(lbs, function(x) eval(req) || {install.packages(x); eval(req)})
    
    plyr psych    tm 
    TRUE  TRUE  TRUE 

1

Używam następujących, które sprawdzą, czy pakiet jest zainstalowany i czy zależności są aktualizowane, a następnie ładuje pakiet.

p<-c('ggplot2','Rcpp')
install_package<-function(pack)
{if(!(pack %in% row.names(installed.packages())))
{
  update.packages(ask=F)
  install.packages(pack,dependencies=T)
}
 require(pack,character.only=TRUE)
}
for(pack in p) {install_package(pack)}

completeFun <- function(data, desiredCols) {
  completeVec <- complete.cases(data[, desiredCols])
  return(data[completeVec, ])
}

1

Oto mój kod:

packages <- c("dplyr", "gridBase", "gridExtra")
package_loader <- function(x){
    for (i in 1:length(x)){
        if (!identical((x[i], installed.packages()[x[i],1])){
            install.packages(x[i], dep = TRUE)
        } else {
            require(x[i], character.only = TRUE)
        }
    }
}
package_loader(packages)

1
 48 lapply_install_and_load <- function (package1, ...)
 49 {
 50     #
 51     # convert arguments to vector
 52     #
 53     packages <- c(package1, ...)
 54     #
 55     # check if loaded and installed
 56     #
 57     loaded        <- packages %in% (.packages())
 58     names(loaded) <- packages
 59     #
 60     installed        <- packages %in% rownames(installed.packages())
 61     names(installed) <- packages
 62     #
 63     # start loop to determine if each package is installed
 64     #
 65     load_it <- function (p, loaded, installed)
 66     {
 67         if (loaded[p])
 68         {
 69             print(paste(p, "loaded"))
 70         }
 71         else
 72         {
 73             print(paste(p, "not loaded"))
 74             if (installed[p])
 75             {
 76                 print(paste(p, "installed"))
 77                 do.call("library", list(p))
 78             }
 79             else
 80             {
 81                 print(paste(p, "not installed"))
 82                 install.packages(p)
 83                 do.call("library", list(p))
 84             }
 85         }
 86     }
 87     #
 88     lapply(packages, load_it, loaded, installed)
 89 }

1
library <- function(x){
  x = toString(substitute(x))
if(!require(x,character.only=TRUE)){
  install.packages(x)
  base::library(x,character.only=TRUE)
}}

Działa to z niecytowanymi nazwami pakietów i jest dość elegancki (por. Odpowiedź GeoObserver)


1

W moim przypadku chciałem jednej linijki, którą mogłem uruchomić z wiersza poleceń (właściwie przez Makefile). Oto przykład instalacji „VGAM” i „wtapiania”, jeśli nie są jeszcze zainstalowane:

R -e 'for (p in c("VGAM", "feather")) if (!require(p, character.only=TRUE)) install.packages(p, repos="http://cran.us.r-project.org")'

Z poziomu R byłoby to po prostu:

for (p in c("VGAM", "feather")) if (!require(p, character.only=TRUE)) install.packages(p, repos="http://cran.us.r-project.org")

Nie ma tu nic poza poprzednimi rozwiązaniami oprócz tego, że:

  • Trzymam to w jednej linii
  • Twarde kodowanie repos parametru (aby uniknąć wyskakujących okienek z pytaniem o użycie kopii lustrzanej)
  • Nie zawracam sobie głowy zdefiniowaniem funkcji, która ma być używana gdzie indziej

Zwróć też uwagę na ważne character.only=TRUE(bez niego, requirepróbowałby załadować pakiet p).


0
  packages_installed <- function(pkg_list){
        pkgs <- unlist(pkg_list)
        req <- unlist(lapply(pkgs, require, character.only = TRUE))
        not_installed <- pkgs[req == FALSE]
        lapply(not_installed, install.packages, 
               repos = "http://cran.r-project.org")# add lib.loc if needed
        lapply(pkgs, library, character.only = TRUE)
}

0

Pozwólcie, że podzielę się odrobiną szaleństwa:

c("ggplot2","ggsci", "hrbrthemes", "gghighlight", "dplyr") %>%  # What will you need to load for this script?
  (function (x) ifelse(t =!(x %in% installed.packages()), 
    install.packages(x[t]),
    lapply(x, require))) 
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.