Velocità di calcolo in R?


16

Mi è stato assegnato il compito di spostare uno dei nostri attuali modelli stocastici di grandi dimensioni da SAS a un nuovo linguaggio. Personalmente, preferisco un linguaggio compilato tradizionale, ma il PI vuole che controlli R, che non ho mai usato. La nostra motivazione per ottenere il modello da SAS è (1) molte persone non hanno accesso ad esso perché SAS è costoso, (2) stiamo cercando di allontanarci da un linguaggio interpretato e (3) SAS è lento per il tipo di modello che abbiamo.

Per (1), ovviamente R soddisfa la necessità che sia gratuito. Per (2), idealmente, vorremmo creare un eseguibile, ma R è normalmente usato come linguaggio di script. Vedo che qualcuno ha recentemente pubblicato un compilatore R: è stato ben accolto? è facile da usare? Preferiamo non forzare l'utente a scaricare R da soli. Per (3), il nostro problema con SAS è tutto il tempo impiegato nella scrittura e lettura di set di dati I / O. Il nostro modello è intensivo dal punto di vista computazionale e spesso siamo limitati dal tempo di esecuzione. (Ad esempio, non è insolito che qualcuno dirotti i computer delle persone durante il fine settimana per eseguire le corse.) Abbiamo un modello simile incorporato in Fortran che non ha lo stesso problema perché tutto il lavoro viene svolto in memoria. Come funziona R? Sarà lo stesso di SAS, in quanto funziona in datasteps, leggere e scrivere file? O può fare manipolazione di array in memoria?


Di solito puoi accelerare sas facendo tutto il tuo lavoro in un unico passaggio di dati. Ciò dovrebbe ridurre i tempi di I / O, poiché in realtà stai leggendo i dati una sola volta. L'uso di molte procedure ti rallenterà. Ad esempio, se modellate ripetutamente proc proclm o proc logistic (diciamo per un bootstrap), è più veloce creare un enorme set di dati e usare un'istruzione by piuttosto che invocare molte chiamate proc (diciamo usando una macro% do loop). se si programma ben sas, non dovreste avere problemi fase di esecuzione a causa di lettura e outputing file (almeno non più di altri software
probabilityislogic

Inoltre, puoi usare le matrici temporanee nei passaggi dei dati sas in un modo simile a come utilizzeresti le matrici in R.
Probislogic,

Risposte:


18

R funziona in memoria, quindi i tuoi dati devono adattarsi alla memoria per la maggior parte delle funzioni.

Il pacchetto del compilatore, se sto pensando a quello a cui stai pensando ( pacchetto di compilatore di Luke Tierney fornito con R), non è la stessa cosa di un linguaggio compilato in senso tradizionale (C, Fortran). È un compilatore di byte per R nel senso di bytecode Java eseguito dalla VM Java o compilazione di byte del codice LISP di Emacs. Non compila il codice R in codice macchina, ma piuttosto prepara il codice R in bytecode in modo che possa essere utilizzato in modo più efficiente rispetto al codice R grezzo da interpretare.

Nota che se hai formato Fortran potresti probabilmente avere il meglio dei due mondi; R può chiamare routine Fortran compilate.


Grazie! È bello sapere che potrei avere l'ottima grafica R e chiamare routine Fortran compilate. Questa potrebbe essere la risposta!
Melissa,

2
Solo per espandere la nota di Gavin sulla memoria: vedere la sezione sulla memoria di grandi dimensioni in questa vista attività CRAN se si lavora con set di dati più grandi: cran.r-project.org/web/views/HighPerformanceComputing.html
Brandon Bertelsen

1
Inoltre, è importante notare che Rcpp potrebbe probabilmente essere utilizzato per ottenere guadagni incrementali nelle prestazioni.
Brandon Bertelsen,

Rcpp è utile per avvolgere C ++ per l'uso in / con R. Aiuta il processo (immensamente) ma sta ancora usando gli strumenti di base di R per chiamare il codice compilato. Se l'OP ha già codici Fortran o abilità Fortran, Rcpp potrebbe essere di minore utilità.
Ripristina Monica - G. Simpson,

13

Ho usato SASper 15 anni e ho iniziato a usarlo Rseriamente negli ultimi 6 mesi, con alcuni armeggi in giro per un paio d'anni prima di quello. Dal punto di vista della programmazione, R effettua direttamente manipolazioni dei dati, non esistono equivalenti DATAo PROC SQLprocedure perché non sono necessarie (quest'ultima è più efficiente SASquando vi è molta manipolazione dei dati da fonti di dati esterne, ad esempio dati amministrativi). Ciò significa che, ora sto imparando, la manipolazione dei dati è più veloce Re richiede molto meno codice.

Il problema principale che ho riscontrato è la memoria. Non tutti i pacchetti R consentono le WEIGHTspecifiche del tipo, quindi se si hanno SASset di dati con variabili utilizzate FREQo REPLICATEistruzioni, è possibile che si verifichino problemi. Ho esaminato i pacchetti ffe bigmemoryin R ma questi non sembrano compatibili con tutti i pacchetti R, quindi se si dispone di set di dati molto grandi che richiedono analisi relativamente non comuni e sono stati aggregati, è possibile che si verifichino problemi di memoria.

Per l'automazione, se lo SAS macroshai, dovresti essere in grado di programmare l'equivalente Red eseguirlo come batch.

Per la codifica R, stavo usando Notepad++e impostando la lingua su R, e ora sto scoprendo le gioie di R Studio. Entrambi questi prodotti sono gratuiti e il linguaggio è marcato come la SASGUI di sintassi migliorata (ho usato solo la schermata di sintassi in SAS).

C'è un sito Web e un libro correlato per le persone che scambiano da SASa R. Li ho trovati utili per cercare di capire come tradurre alcuni SAScomandi in R.

Aggiornamento: una cosa che mi ha spinto noci quando venire a Rè che Rnon si assume tutto è un insieme di dati ( data framein Rgergo), perché non è un pacchetto statistico nel modo in cui SAS, SPSS, Stata, ecc sono. Quindi, ad esempio, mi ci è voluto un po 'perché le ifdichiarazioni funzionassero perché continuavo a ricevere aiuto per le ifdichiarazioni con i vettori (o forse le matrici) mentre avevo bisogno di una ifdichiarazione con cui funzionasse data frames. Quindi le pagine di aiuto probabilmente devono essere lette più da vicino di quanto faresti normalmente, perché dovrai controllare che il comando che vuoi fare operi con il tipo di oggetto dati che hai.

La cosa che mi fa ancora impazzire quando apprendo un nuovo Rcomando (ad es. Metodo di analisi in un pacchetto contribuito) è che l'aiuto per i comandi spesso non è del tutto autonomo. Andrò alla pagina di aiuto per provare ad apprendere il comando e le note di utilizzo spesso sono state ...contenute in esse. A volte cercare di capire cosa può o dovrebbe andare dove ...è mi ha portato in un ciclo ricorsivo. La relativa brevità delle note di aiuto, dalle SASquali fornisce esempi dettagliati di sintassi ed esempi funzionanti con una spiegazione dello studio nell'esempio, è stata piuttosto scioccante.


2
+1 Ti preghiamo di considerare di aggiornare il nostro meta thread in cui abbiamo raccolto collegamenti a risorse del software di statistiche. C'è una risposta lì per R e un'altra per SAS: entrambi trarrebbero beneficio dall'avere un link a r4stats.com. (Quella discussione è in realtà una parte delle nostre FAQ. Speriamo di mantenerla attuale e utile.)
whuber

1
R ha anche pacchetti che supportano l'accesso SQL tramite driver RODBC o SQLite.
DWin

1
Sono d'accordo con i tuoi commenti su R aiuto. In realtà ho sottolineato essenzialmente quello che stai dicendo su una delle mailing list di R molti anni fa. La risposta non è stata positiva. In tutta onestà, io (a) probabilmente non mi sono espresso molto bene e non ho fornito esempi concreti e (b) non ho approfondito la questione. Per riassumere, il problema 1 è esempi troppo complicati e coinvolgono troppi concetti non correlati. Gli esempi complicati sono ok ma dovrebbero seguire semplici esempi. Il problema 2 è che quasi nessuna annotazione o spiegazione di ciò che fanno gli esempi.
Faheem Mitha,

Riguardo l '"aiuto" R mi ricorda qualcosa che il mio capo mi ha detto. "si impara R facendolo con qualcuno che conosce già R seduto accanto a te davanti al computer"
probabilityislogic

E per tutti gli altri ci sono libri e Stack Overflow. Sì, imparare R da solo è piuttosto difficile, almeno è stato per me.
Michelle,

10

R è un linguaggio di programmazione. Non funziona nei datasteps. Fa tutto quello che vuoi che faccia, perché non è che un linguaggio di programmazione, uno schiavo dei tuoi desideri, espresso in un linguaggio di parentesi graffe e due punti.

Pensalo come Fortran o C, ma con la vettorializzazione implicita in modo da non dover ricorrere ad array e gestione dinamica della memoria in modo da non dover malloc () o dichiarare le dimensioni degli array in qualsiasi momento.

Per lo più fa tutto il suo lavoro in memoria, ma se vuoi leggere parte di un file, mungerlo, quindi sputare alcuni dei risultati e leggere il bit successivo in, beh, vai avanti e scrivi un programma R che fa quello.

Ti contraddici nel dire che il modello è intensivo dal punto di vista computazionale ma SAS è lento a causa dell'I / O ... Uno o l'altro sicuramente ...

Se hai già qualcosa di simile in Fortran e dici che vuoi allontanarti da un linguaggio interpretato, allora perché non farlo anche in Fortran?

Il compilatore R può causare alcune accelerazioni, ma se il tuo codice R è ben scritto comunque non otterrai nulla di troppo massiccio, non come scriverlo in C o Fortran.


Ah, non mi sono spiegato bene. È intensivo nella manipolazione di set di dati, che in SAS significa troppo tempo trascorso in I / O. Il mio suggerimento iniziale era Fortran, ma il PI è interessato a passare a R, quindi voleva che lo verificassi. Grazie!
Melissa,

7

Capisco che per impostazione predefinita SAS può funzionare con modelli più grandi della memoria, ma questo non è il caso di R, a meno che non si utilizzino pacchetti specifici come biglm o ff.

Tuttavia, se stai facendo un lavoro di array in R che può essere vettorializzato sarà molto veloce - forse in alcuni casi metà della velocità di un programma C, ma se stai facendo qualcosa che non può essere vettorializzato, sembrerà piuttosto lento. Per darti un esempio:

# create a data.frame with 4 columns of standard normally distributed RVs
N <- 10000

# test 1
system.time( {df1 <- data.frame(h1=rnorm(N),
                h2=rpois(N, lambda=5),
                h3=runif(N),
                h4=rexp(N))
} )
# about 0.003 seconds elapsed time

# vectorised sum of columns 1 to 4
# i.e. it can work on an entire column all at once
# test 2
system.time( { df1$rowtotal1 <- df1$h1 + df1$h2 + df1$h3 + df1$h4 })
# about 0.001 seconds elapsed time

# test 3
# another version of the vectorised sum
system.time( { df1$rowtotal2 <- rowSums(df1[,c(1:4)]) })
# about 0.001 seconds elapsed time

# test 4
# using a loop... THIS IS *VERY* SLOW AND GENERALLY A BAD IDEA!!! :-)
system.time( {
        for(i in 1:nrow(df1)) {
                df1$rowtotal3 <- df1[i,1]+ df1[i,2] + df1[i,3] + df1[i,4]
        }
} )
# about 9.2 seconds elapsed time

Quando ho aumentato N per un fattore di dieci a 100.000, ho rinunciato test 4 dopo 20 minuti, ma i test 1: 3 presi 61, 3 e 37 milli -seconds ciascun

Per N = 10.000.000 il tempo per le prove 1: 3 è di 3,3 secondi, 0,6 secondi e 1,6 secondi

Si noti che questo è stato fatto su un laptop i7 ea 480 MB per N = 10 milioni, la memoria non era un problema.

Per gli utenti su Windows a 32 bit esiste un limite di memoria di 1,5 GB per R, indipendentemente dalla quantità di memoria disponibile, ma non esiste tale limite per Windows a 64 bit o Linux a 64 bit. In questi giorni la memoria è molto economica rispetto al costo di un'ora del mio tempo, quindi compro solo più memoria invece di passare il tempo a cercare di aggirare il problema. Ma questo presuppone che il tuo modello si adatti alla memoria.


1
(+1) Grazie per aver offerto le illustrazioni utili, Sean!
whuber

3

(2), idealmente, vorremmo creare un eseguibile, ma R è normalmente usato come linguaggio di script

Sì, e questa è la buona ragione per passare a R. L'interesse di scrivere un pacchetto R è quello di consentire agli utenti di far interagire facilmente le tue funzioni con altri strumenti forniti da R, ad esempio fornendo loro i dati di bootstrap ... o qualunque cosa vogliano. Se non ritieni che ciò sia importante, segui C / C ++ o il tuo linguaggio compilato preferito.

O()rle()

Quindi stai molto attento. Dopo i tuoi primi tentativi, avrai sicuramente un disgusto per R, perché lo troverai lento, con una strana sintassi, ecc. Una volta che lo conosci, può essere uno strumento molto efficiente. Puoi persino terminare scrivendo i tuoi metodi in R come fase preliminare per la codifica C / C ++. Lo stadio finale sarà imparare l'API di R per creare funzioni precompilate e sarai un mago R :)


2

La manipolazione di array in memoria è una cosa importante per SAS, a quanto pare. Non conosco i dettagli riguardanti R, ma suppongo che R funzioni di default in memoria, poiché i pacchetti di espansione di memoria per R, ff e bigmemory spostano i dati dalla memoria al disco. Ho dei suggerimenti per te se vuoi migliorare la velocità o l'utilizzo della memoria. Per migliorare la velocità, è innanzitutto necessario utilizzare R come previsto, ovvero: vettorializzare il codice e utilizzare la compilazione del codice byte. (Inoltre: evitare il più possibile le operazioni di copia della memoria.) In secondo luogo, utilizzare il profiler di codice fornito Rprof () per identificare le patch lente nel codice e riscriverle in C o C ++ se necessario. Se hai bisogno di più memoria, puoi usare l'argomento skip nella funzione read.table () per leggere nei tuoi dati un pezzo alla volta e puoi anche usare un pacchetto come RMySQL, che aggiunge utilità di manipolazione del database a R. Se hai bisogno di ancora più memoria e puoi permetterti la concomitante diminuzione della velocità, puoi usare il pacchetto neve per eseguire R in parallelo. (Puoi trovare dettagli su questo, e molto altro, nel libro "The Art of R Programming", di Norman Matloff, pubblicato alla fine dello scorso anno. I dettagli sui pacchetti menzionati qui sono disponibili online.)

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.