2010-02-03 12 views
38

Ho alcuni file di dati delimitati molto grandi e Voglio elaborare solo determinate colonne in R senza prendere tempo e memoria per creare un data.frame per il intero file.Modi per leggere solo selezionare colonne da un file in R? (Un mezzo felice tra `read.table` e` scan`?)

Le uniche opzioni che conosco sono read.table che è molto dispendioso quando voglio solo un paio di colonne o scan che sembra livello troppo basso per quello che voglio.

Esiste un'opzione migliore, con R pura o forse chiamando altri script di shell per eseguire l'estrazione di colonne e quindi utilizzare scan o read.table sull'output? (Il che porta alla domanda su come chiamare uno script di shell e catturarne l'output in R?).

+0

Un insieme di risposte utili qui. Ognuno di loro sarebbe utile per un determinato contesto. Quello accettato era semplicemente il più vicino al mio caso reale e includeva uno snippet di codice. (Avrei potuto semplicemente aver scelto Dirk ma sembra che abbia già molta reputazione ;-)) –

+6

La migliore risposta è nella nuova domanda http://stackoverflow.com/q/5788117/168747 – Marek

risposta

34

volte mi fare qualcosa di simile quando ho i dati in un file delimitato da tabulazioni:

df <- read.table(pipe("cut -f1,5,28 myFile.txt")) 

Ciò consente a cut di eseguire la selezione dei dati, operazione che è possibile eseguire senza utilizzare molta memoria.

Vedere Only read limited number of columns per la versione R pura, utilizzando "NULL" nell'argomento colClasses su read.table.

+1

Il tuo primo esempio è praticamente esattamente quello che ho finito usando.(awk invece di tagliare nel mio caso a causa di un formato di file delimitato irregolare). Il tuo secondo esempio non è veramente equivalente a quanto mi risulta. Non creerà l'intero 'data.frame' solo per buttarlo via di nuovo? Quando voglio 2 di 10 colonne da un file di milioni di righe, le prestazioni sono molto diverse. –

+11

No, l'equivalente R puro sarebbe qualcosa come (supponendo 28 colonne) 'mycols <- rep (NULL, 28); micoli [c (1,5,28)] <- NA; df <- read.table (file, colClasses = mycols) ' –

+1

@DirkEddelbuettel Ho appena saltato su questo. Sembra che 'NULL' deve essere tra virgolette. – JackeJR

18

Una possibilità è utilizzare pipe() al posto del nome file e avere awk o filtri simili estrarre solo le colonne che si desidera.

Vedere help(connection) per ulteriori informazioni su pipe e amici.

Edit: read.table() può anche fare questo per voi se siete molto esplicito su colClasses - un valore NULL per una data colonna salta la colonna alltogether. Vedi help(read.table). Quindi, abbiamo una soluzione in base R senza pacchetti o strumenti aggiuntivi.

7

Penso che l'approccio di Dirk sia semplice e veloce. Un'alternativa che ho usato è di caricare i dati in sqlite che carica MOLTO più velocemente di read.table() e poi estrae solo quello che vuoi. il pacchetto sqldf() rende tutto abbastanza semplice. Here's a link a una precedente risposta di overflow dello stack che fornisce esempi di codice per sqldf().

3

Questo è probabilmente più del necessario, ma se si opera su molto grandi insiemi di dati, allora si potrebbe anche dare un'occhiata a the HadoopStreaming package che fornisce una mappa-ridurre di routine utilizzando Hadoop.

7

Esiste un pacchetto, colbycol, progettato per fare esattamente quello che stai cercando:

http://cran.r-project.org/web/packages/colbycol/index.html

+1

In realtà sembra che sia ancora elabora tutte le colonne ma senza le restrizioni in memoria. Potrebbe essere molto utile in un contesto leggermente diverso. –

+2

Questo pacchetto non è più disponibile su CRAN. –