Ho 12 data.frame
s con cui lavorare. Sono simili e devo eseguire la stessa elaborazione per ognuno di essi, quindi ho scritto una funzione che prende uno data.frame
, lo elabora e quindi restituisce uno data.frame
. Questo funziona. Ma temo di passare intorno a una struttura molto grande. Potrei fare delle copie temporanee (sono io?) Questo non può essere efficiente. Qual è il modo migliore per evitare di passare un data.frame
in giro?Qual è il modo migliore per evitare di passare un frame di dati in giro?
risposta
Si sta, in effetti, passando l'oggetto e utilizzando un po 'di memoria. Ma non penso che tu possa fare un'operazione su un oggetto in R senza far passare l'oggetto. Anche se non hai creato una funzione e hai eseguito le tue operazioni al di fuori della funzione, R si comporterebbe sostanzialmente allo stesso modo.
Il modo migliore per vedere questo è impostare un esempio. Se sei in Windows, apri il Task Manager di Windows. Se sei in Linux apri una finestra di terminale ed esegui il comando in alto. In questo esempio assumerò Windows. In R eseguire il seguente:
col1<-rnorm(1000000,0,1)
col2<-rnorm(1000000,1,2)
myframe<-data.frame(col1,col2)
rm(col1)
rm(col2)
gc()
questo crea una coppia di vettori chiamati col1 e col2 poi li combina in un frame di dati denominato MyFrame. Quindi rilascia i vettori e impone la garbage collection per l'esecuzione. Guarda il tuo task manager di Windows sull'utilizzo di mem per l'attività Rgui.exe. Quando avvio R utilizza circa 19 meg di mem. Dopo che ho eseguire i comandi sopra la mia macchina utilizza poco meno di 35 mega per R.
Ora provate questo:
myframe<-myframe+1
l'uso della memoria per R dovrebbe saltare a più di 144 mega. Se imposti la garbage collection usando gc() lo vedrai ridursi a circa 35 mega. Per provare questo utilizzando una funzione, è possibile effettuare le seguenti operazioni:
doSomething <- function(df) {
df<-df+1-1
return(df)
}
myframe<-doSomething(myframe)
quando si esegue il codice di cui sopra, l'utilizzo di memoria salterà fino a 160 mega o giù di lì. L'esecuzione di gc() la ridurrà a 35 meg.
Quindi, cosa fare di tutto questo? Bene, eseguire un'operazione al di fuori di una funzione non è molto più efficiente (in termini di memoria) che farlo in una funzione. La raccolta dei rifiuti pulisce le cose davvero bene. Dovresti forzare gc() a correre? Probabilmente no, poiché verrà eseguito automaticamente secondo necessità, l'ho appena eseguito sopra per mostrare come influisce sull'utilizzo della memoria.
Spero che questo aiuti!
Non sono un esperto di R, ma la maggior parte delle lingue utilizza uno schema di conteggio dei riferimenti per i grandi oggetti. Una copia dei dati dell'oggetto non verrà eseguita finché non si modifica la copia dell'oggetto. Se le tue funzioni leggono solo i dati (ad esempio per l'analisi), non dovrebbe essere fatta alcuna copia.
Ecco come funziona anche R, Neil. Buon punto –
Mi sono imbattuto in questa domanda alla ricerca di qualcos'altro, ed è vecchio - quindi fornirò una risposta breve per ora (lascia un commento se desideri ulteriori spiegazioni).
È possibile passare intorno agli ambienti in R che contengono ovunque da 1 a tutte le variabili. Ma probabilmente non devi preoccuparti di questo.
[Si potrebbe anche essere in grado di fare qualcosa di simile con le classi. Al momento capisco solo come usare le classi per le funzioni polimorfiche - e notare che c'è più di un sistema di classe a dare il calcio.]
Domanda di follow-up: quando si finisce con "doSomething", il comando 'rm (doSomething)' libererà il oggetto per la raccolta dei rifiuti, giusto? – bernie
Adam, si. Hai ragione. –
ma tieni presente che nell'esempio precedente "doSomething" è una funzione, non i dati, quindi non è molto grande. –