Carica più pacchetti contemporaneamente


174

Come posso caricare un sacco di pacchetti contemporaneamente senza dover riscrivere più volte il comando request? Ho provato tre approcci, tutti crash e burn.

Fondamentalmente, voglio fornire un vettore di nomi di pacchetto a una funzione che li caricherà.

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

require(x)
lapply(x, require)
do.call("require", x)

Risposte:


251

Diverse permutazioni delle funzioni proposte funzionano, ma solo se si specifica l' character.onlyargomento TRUE. Esempio rapido:

lapply(x, require, character.only = TRUE)

@ Tommy & Daroczig - Fantastico. Questa è una soluzione molto più pulita. Lascio il mio solo per i posteri e per quello che mostra sul perché i tentativi del PO non abbiano funzionato.
Josh O'Brien,

4
Puoi trarre vantaggio dalla corrispondenza parziale dei caratteri e cavartela con lapply (x, request, ch = T) o anche lapply (x, request, c = T)
Dason,

@daroczig Questo codice carica i pacchetti, ma perché fornisce i seguenti messaggi di avviso: 1: In libreria (pacchetto, lib.loc = lib.loc, character.only = TRUE, logical.return = TRUE,: non esiste un pacchetto chiamato 'x' 2: In if (! caricato) {: la condizione ha lunghezza> 1 e verrà utilizzato solo il primo elemento
Anusha

@Anusha: non ho idea di ATM, cosa hai nel tuo x?
daroczig,

23
Sii gentile se R :: base ha aggiunto questo lapplytrucco nativo a library(). Sii fantastico per poter dire:library(c("plyr", "umx"))
tim

58

Il pacchetto CRAN pacman che mantengo (creato con Dason Kurkiewicz) può ottenere questo risultato:

Quindi l'utente potrebbe fare:

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

e se il pacchetto manca, p_loadlo scaricherà da CRAN o Bioconduttore.


7
+1! Perché hai scelto il nome breve p_load? Un nome più descrittivo come load_packagesrende più chiaro l'intento della funzione.
Paul Hiemstra,

19
Perché p sta per pacchetto. Ogni funzione nel pacchetto che è utile ed esportata inizia con p_. Inoltre tendiamo a usare un po 'la libreria e ci sono altri 7 caratteri. 7 caratteri x ~ 1000000 durata di utilizzo della funzione x 0,5 secondi per carattere = 3500000 secondi. Sono 58333.33 minuti, 972.2222 ore o 40.50926 giorni della vita di un programmatore che gli abbiamo restituito :-) In ogni caso, il nostro obiettivo è di spingere CRAN entro il 1 febbraio
Tyler Rinker,

3
Circa un anno di ritardo, ma alla fine ci siamo sottoposti al CRAN. Dovrebbe essere tra pochi giorni. @trinker (o me) assicurati di modificarlo una volta che diventa pubblico.
Dason,

5
@Tyler So di essere in ritardo di anni, ma trovo la tua logica per il p_prefisso piuttosto dubbia. Se il problema è la terseness, rimuovere del p_tutto il prefisso. In effetti, avere tali prefissi è generalmente scoraggiato in altre lingue per buone ragioni (ho detto ad Hadley che sono uguali per quanto riguarda la sua fct_assurdità nei forcati). Ciò è particolarmente vero poiché l'uso previsto del pacchetto è con uno spazio dei nomi qualificato ( pacman::).
Konrad Rudolph,

5
@TylerRinker Chiedo scusa per essere combattivo su questo problema, ma penso davvero che la comunità R sia semplicemente sbagliata qui, e praticamente ogni altro linguaggio moderno ha ragione: dici "Questo protegge dai conflitti dello spazio dei nomi". - Ma questo è lo spazio dei nomi! L'onere degli autori di pacchetti è di educare le persone a utilizzare i pacchetti in modo corretto, non per adattarsi alle loro pratiche di programmazione sciatta.
Konrad Rudolph,

24

Questo dovrebbe fare il trucco:

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

(Il bit chiave è che l' argsargomento in do.call(what, args) deve essere un elenco --- anche se ha solo un singolo elemento!)


16

Per qualcuno che vuole installare e caricare i pacchetti contemporaneamente mi sono imbattuto in questa funzione da questo link

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

Ciao, ho creato un file R dal tuo frammento dato. Quando eseguo quello script sul servizio Amazon EMR mi dà l'output seguente come specificato nel seguente URL. pastie.org/10402378#3,10-11,13 .
Rubin Porwal,

9

Un'opzione alternativa viene dal pacchetto easypackages. Una volta installato, è possibile caricare i pacchetti nel modo più intuitivo:

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

Il pacchetto include anche una funzione per installare diversi pacchetti:

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

Riferimento qui .


Il nome della funzione è piuttosto confuso / confuso. "Libreria", nella libraryfunzione, si riferisce alla posizione in cui sono installati i pacchetti : la libreria dei pacchetti . Il caricamento di più pacchetti tramite librariesnon ha senso. Avere una funzione separata packagesche fa qualcos'altro non fa che peggiorare le cose. So che la denominazione è un problema difficile nell'ingegneria del software, ma in realtà. Questi nomi sono particolarmente cattivi.
Konrad Rudolph,

2
@KonradRudolph Non sono d'accordo sul fatto che il nome librariesnon abbia senso. È il plurale di librarye librarycarica un singolo pacchetto; librariescarica una pluralità di pacchetti. Se pensi libraryal significato di "caricamento dalla tua singola libreria" e lo estendi al librariessignificato di "caricamento da più librerie", allora forse non è intuitivo, ma non è questo l'intento; Sarei abbastanza contento del nome libraries.
Jamie S,

@JamieS Ma si sta ancora (di solito) caricando da una singola libreria. Sembra che tu confonda la libreria e il pacchetto (che, per essere onesti, è diventato comune in R): La "libreria R", come affermato nel mio commento precedente, si riferisce alle posizioni (directory / directory) in cui sono installati i pacchetti R . Nell'esempio di questa risposta, "plyr", "psych" e "tm" non sono librerie: sono pacchetti.
Konrad Rudolph,

4

Puoi semplicemente usare il pacchetto lubripack e installa ordinatamente nuovi pacchetti e poi li carica tutti in una riga.

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

Ecco l'output dopo aver eseguito il codice sopra in RStudio.

inserisci qui la descrizione dell'immagine

Come installare il pacchetto:

Esegui il codice seguente per scaricare il pacchetto e installarlo da GitHub. Non è necessario disporre di un account GitHub.

library(devtools)
install_github("espanta/lubripack")

5
Immagino che usando le immagini invece del testo
The Unfun Cat,

3
Anche questo non risponde alla domanda in un modo che non ha già risposto e sembra per lo più auto-promozione.
Tyler Rinker,

Hai ragione, ho provato a rispondere implicitamente alla domanda. Rendiamolo esplicito sperando che possa essere una risposta alla domanda.
Espanta,

@TylerRinker Com'è adesso?
Espanta,

3

Basandosi sulla soluzione di daroczig, se non si desidera specificare un elenco come input, è possibile utilizzare

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

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

... che è più breve di

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

2

Uso la seguente funzione:

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

Questo tenta di caricare, e se non riesce installa e quindi prova a caricare di nuovo.


2

Penso che il codice fornito da @daroczig possa essere migliorato sostituendo il requirecon librarye avvolgendo la lapplychiamata all'interno della invisible()funzione. Quindi, il codice migliorato sarà simile al seguente:

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

Questo codice è stato migliorato perché:

  1. library() è generalmente preferito require() al caricamento dei pacchetti perché il primo genera un errore se il pacchetto non è installato mentre il secondo fornisce solo un avviso. Inoltre, require()chiama library(), quindi perché non utilizzarlo library()direttamente!

    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. L'oggetto elenco restituito e stampato da lapply() chiamata non è significativo in questo caso, quindi ha senso rendere invisibile l'output. Supponiamo che tu usi R Notebook per il tuo lavoro di analisi, usando la invisible()funzione sopprimerai il contenuto dell'oggetto elenco e impedirai il disordine nel file del notebook renderizzato.


1

Leggera mod della risposta di Tyler Rinker per aggiungere un segno di spunta per installare e caricare pacman:

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

Mi piace la soluzione p_load perché evita di quotare!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.