2013-07-11 5 views
11

Volevo sapere se esiste un limite al numero di righe che può essere letto utilizzando la funzione di battitura data.table. Sto lavorando con un tavolo con 4 miliardi di righe, 4 colonne, circa 40 GB. Sembra che fread leggerà solo i primi ~ 840 milioni di righe. Non dà errori, ma ritorna al prompt R come se avesse letto tutti i dati!Limite di riga per data.table in R utilizzando il tasto

Capisco che al momento non ci sia "prod use", e volevo scoprire se ci fosse un periodo di tempo per l'implementazione di un rilascio.

Il motivo per cui sto usando data.table è che, per i file di tali dimensioni, è estremamente efficiente l'elaborazione dei dati rispetto al caricamento del file in un data.frame, ecc

Al momento, sto cercando 2 altre alternative -

1) Utilizzando la scansione e la trasmissione ad un data.table

data.table(matrix(scan("file.csv",what="integer",sep=","),ncol=4)) 

Resulted in -- 
Error in scan(file, what, nmax, sep, dec, quote, skip, nlines, na.strings, : 
    too many items 

2) Rompere il file fino in segmenti individuali con un limite di circa mq. 500 milioni di righe usando Unix diviso e leggendole in sequenza ... quindi eseguendo il looping dei file in modo sequenziale su un piano - un po 'macchinoso, ma sembra essere l'unica soluzione praticabile.

Penso che ci possa essere un modo Rcpp per farlo ancora più veloce, ma non sono sicuro di come sia generalmente implementato.

Grazie in anticipo.

+1

Assicurarsi che ci sia nulla di insolito nel file nell'ultima riga che è stato letto o la linea dopo che e poi [Invia] (https: // r-forge. r-project.org/tracker/?group_id=240) una segnalazione di bug o contattare il mantainer del pacchetto. – Roland

+0

Sei sicuro di avere abbastanza RAM? E stai lavorando con 64bit R? – eddi

+0

No, non c'è necessariamente un modo più veloce con Rcpp dato che Matt usa già mmap. Controlla la documentazione del tuo sistema operativo per i limiti della chiamata mmap. Miliardi potrebbero spingerlo ... –

risposta

8

Sono riuscito a farlo utilizzando il feedback di un altro post su StackOverflow. Il processo è stato molto veloce e 40 GB di dati sono stati letti in circa 10 minuti usando fread iterativamente. Foreach-dopar non è riuscito a funzionare quando eseguito da solo per leggere i file in nuovi data.tables in sequenza a causa di alcune limitazioni che sono menzionate anche nella pagina seguente.

Nota: l'elenco dei file (file_map) è stato preparato con la semplice corsa in montagna -

file_map <- list.files(pattern="test.$") # Replace pattern to suit your requirement 

mclapply with big objects - "serialization is too large to store in a raw vector"

Citando -

collector = vector("list", length(file_map)) # more complex than normal for speed 

for(index in 1:length(file_map)) { 
reduced_set <- mclapply(file_map[[index]], function(x) { 
    on.exit(message(sprintf("Completed: %s", x))) 
    message(sprintf("Started: '%s'", x)) 
    fread(x)    # <----- CHANGED THIS LINE to fread 
}, mc.cores=10) 
collector[[index]]= reduced_set 

} 

# Additional line (in place of rbind as in the URL above) 

for (i in 1:length(collector)) { rbindlist(list(finalList,yourFunction(collector[[i]][[1]]))) } 
# Replace yourFunction as needed, in my case it was an operation I performed on each segment and joined them with rbindlist at the end. 

La mia funzione incluso un ciclo utilizzando Foreach Dopar che eseguito su più core per file come specificato in file_map. Questo mi ha permesso di usare dopar senza incontrare la "serializzazione errore troppo grande" durante l'esecuzione sul file combinato.

un altro post utile è a - loading files in parallel not working with foreach + data.table