Załaduj wiele paczek jednocześnie

174

Jak mogę załadować kilka pakietów naraz bez ponownego wpisywania żądanego polecenia? Wypróbowałem trzy podejścia, z których wszystkie ulegają awarii i spalają się.

Zasadniczo chcę dostarczyć wektor nazw pakietów do funkcji, która je załaduje.

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

require(x)
lapply(x, require)
do.call("require", x)
Tyler Rinker
źródło

Odpowiedzi:

251

Kilka permutacji proponowanych funkcji działa - ale tylko wtedy, gdy określisz character.onlyargument TRUE. Szybki przykład:

lapply(x, require, character.only = TRUE)
daroczig
źródło
@Tommy & daroczig - Cool. To znacznie czystsze rozwiązanie. Moje zostawię tylko dla potomności i po to, co pokazuje, dlaczego próby PO nie powiodły się.
Josh O'Brien
4
Możesz skorzystać z częściowego dopasowywania znaków i uciec z lapply (x, require, ch = T) lub nawet lapply (x, require, c = T)
Dason
@daroczig Ten kod ładuje pakiety, ale dlaczego wyświetla następujące komunikaty ostrzegawcze: 1: W bibliotece (pakiet, lib.loc = lib.loc, znak.only = TRUE, logical.return = TRUE,: nie ma wywoływanego pakietu 'x' 2: In if (! załadowano) {: warunek ma długość> 1 i zostanie użyty tylko pierwszy element
Anusha
@Anusha: Nie mam pojęcia o bankomacie, co masz w swoim x?
daroczig
23
Będzie miło, jeśli R :: base dodał tę lapplysztuczkę natywną dla library(). Byłoby wspaniale móc powiedzieć:library(c("plyr", "umx"))
Tim
58

Pakiet CRAN pacman, który utrzymuję (którego autorem jest Dason Kurkiewicz) może to osiągnąć:

Więc użytkownik może zrobić:

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

a jeśli brakuje pakietu p_load, pobierze go z CRAN lub Bioconductor.

Tyler Rinker
źródło
7
+1! Dlaczego wybrałeś krótką nazwę p_load? Bardziej opisowa nazwa, na przykład load_packagesbardziej zrozumiała intencja funkcji.
Paul Hiemstra,
19
Ponieważ p oznacza pakiet. Każda użyteczna i eksportowana funkcja w pakiecie zaczyna się od p_. Poza tym zwykle używamy biblioteki, a to dodatkowe 7 znaków. 7 znaków x ~ 1000000 żywotność wykorzystania funkcji x. 5 sekund na znak = 3500000 sekund. To 58333,33 minuty, 972,2222 godziny lub 40,50926 dni życia programisty, które im oddaliśmy :-) W każdym razie naszym celem jest przejście do CRAN do 1 lutego
Tyler Rinker
3
Około roku spóźniliśmy się, ale w końcu zgłosiliśmy się do CRAN. Powinien wstać za kilka dni. @trinker (lub ja) upewnij się, że zmodyfikujesz to po opublikowaniu.
Dason
5
@Tyler Wiem, że jestem spóźniony o lata, ale wydaje mi się, że twoje uzasadnienie dla p_przedrostka jest raczej wątpliwe. Jeśli problemem jest zwięzłość, p_całkowicie usuń przedrostek. W rzeczywistości, używanie takich przedrostków jest generalnie odradzane w innych językach z fct_ważnych powodów (powiedziałem Hadleyowi, że to samo w odniesieniu do jego bzdur w forcats). Jest to szczególnie ważne, ponieważ zamierzone użycie tego pakietu dotyczy kwalifikowanej przestrzeni nazw ( pacman::).
Konrad Rudolph
5
@TylerRinker Przepraszamy za bycie walecznym w tej kwestii, ale naprawdę uważam, że społeczność R jest po prostu w błędzie i praktycznie każdy inny współczesny język ma rację: Mówisz „To chroni przed konfliktami przestrzeni nazw”. - Ale po to są przestrzenie nazw! Obowiązkiem twórców pakietów jest edukowanie ludzi, aby właściwie korzystali z pakietów, a nie dostosowywali się do ich niechlujnych praktyk programowania.
Konrad Rudolph
24

To powinno załatwić sprawę:

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

(Kluczowym bitem jest to, że argsargument w do.call(what, args) musi być listą --- nawet jeśli ma tylko jeden element!)

Josh O'Brien
źródło
16

Dla kogoś, kto chce instalować i ładować pakiety jednocześnie, natrafiłem na tę funkcję z tego linku

# 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
źródło
Witam Utworzyłem plik R z podanego fragmentu. Kiedy uruchamiam ten skrypt w usłudze Amazon EMR, daje mi on następujące dane wyjściowe określone w następującym adresie URL. pastie.org/10402378#3,10-11,13 .
Rubin Porwal,
9

Alternatywna opcja pochodzi z pakietu easypackages. Po zainstalowaniu możesz ładować pakiety w najbardziej intuicyjny sposób:

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

Pakiet zawiera również funkcję instalowania kilku pakietów:

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

Odniesienie tutaj .

luchonacho
źródło
Nazwa funkcji jest raczej zagmatwana / zagmatwana. „Biblioteka” w libraryfunkcji odnosi się do lokalizacji, w której są instalowane pakiety: biblioteki pakietów . Ładowanie kilku pakietów przez librariesnie ma sensu. Posiadanie oddzielnej funkcji, packagesktóra robi coś innego, tylko pogarsza sytuację. Wiem, że nazewnictwo to trudny problem w inżynierii oprogramowania, ale tak naprawdę. Te nazwiska są szczególnie złe.
Konrad Rudolph
2
@KonradRudolph Nie zgadzam się, że nazwa librariesnie ma sensu. Jest to liczba mnoga libraryi libraryładuje pojedynczy pakiet; librariesładuje wiele pakietów. Jeśli myślisz o libraryznaczeniu „ładuj z jednej biblioteki” i rozszerzasz to na libraries„ładuj z wielu bibliotek”, to być może jest to nieintuicyjne, ale nie o to chodzi; Byłbym bardzo zadowolony z nazwy libraries.
Jamie S
@JamieS Ale nadal (zwykle) ładuje się z jednej biblioteki. Wydaje się, że mylisz bibliotekę i pakiet (co, szczerze mówiąc, stało się powszechne w R): „Biblioteka R”, jak stwierdził mój poprzedni komentarz, odnosi się do lokalizacji (katalogów / katalogów), w których są zainstalowane pakiety R . W przykładzie tej odpowiedzi „plyr”, „psych” i „tm” nie są bibliotekami: są pakietami.
Konrad Rudolph
4

Możesz po prostu użyć pakietu lubripack i starannie zainstaluje nowe pakiety, a następnie załaduje je wszystkie w jednej linii.

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

Oto dane wyjściowe po uruchomieniu powyższego kodu w RStudio.

wprowadź opis obrazu tutaj

Jak zainstalować pakiet:

Uruchom poniższy kod, aby pobrać pakiet i zainstalować go z GitHub. Nie musisz mieć konta GitHub.

library(devtools)
install_github("espanta/lubripack")
Espanta
źródło
5
Wydaje
3
To również nie odpowiada na pytanie w sposób, na który nie ma jeszcze odpowiedzi i wydaje się być głównie autopromocją.
Tyler Rinker
Masz rację, próbowałem pośrednio odpowiedzieć na pytanie. Powiedzmy to wprost, mając nadzieję, że będzie to odpowiedź na pytanie.
Espanta
@TylerRinker Jak to jest teraz?
Espanta
3

Opierając się na rozwiązaniu darocziga, jeśli nie chcesz określać listy jako danych wejściowych, których możesz użyć

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

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

... który jest krótszy niż

lapply(list('plyr', 'dplyr', 'data.table'), require, character.only = TRUE)
goclem
źródło
2

Używam następującej funkcji:

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

Próbuje załadować, a jeśli się nie powiedzie, instaluje się, a następnie próbuje załadować ponownie.

Ricardo
źródło
2

Myślę, że kod, który @daroczig zapewnił można poprawić poprzez zastąpienie requireze libraryi owijania lapplypołączenia wewnątrz invisible()funkcji. Tak więc ulepszony kod będzie wyglądał następująco:

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

Ten kod jest ulepszony, ponieważ:

  1. library()jest generalnie preferowany require()zamiast ładowania pakietów, ponieważ pierwszy wyświetla błąd, jeśli pakiet nie jest zainstalowany, podczas gdy drugi wyświetla tylko ostrzeżenie. Co więcej, require()połączenia library(), więc dlaczego nie używać library()bezpośrednio!

    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. Obiekt listy zwrócony i wypisany przez lapply()wywołanie nie ma w tym przypadku znaczenia, więc sensowne jest uczynienie wyjścia niewidocznym. Załóżmy, że używasz R Notebook do pracy analitycznej, użycie tej invisible()funkcji spowoduje wygaszenie zawartości obiektu listy i uniknięcie bałaganu w renderowanym pliku notatnika.

Ashirwad
źródło
1

Nieznaczny mod odpowiedzi Tylera Rinkera, aby dodać czek, aby zainstalować i załadować pacman:

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

Podoba mi się rozwiązanie p_load, ponieważ unika cytowania!

mattador
źródło