2013-07-11 19 views
11

Ich wollte wissen, ob die Anzahl der Zeilen, die mit der Funktion data.table fread gelesen werden können, begrenzt ist. Ich arbeite mit einer Tabelle mit 4 Milliarden Zeilen, 4 Spalten, etwa 40 GB. Es scheint, dass fread nur die ersten ~ 840 Millionen Zeilen lesen wird. Es gibt keine Fehler, aber kehrt zur R-Eingabe zurück, als ob es alle Daten gelesen hätte!Zeilenlimit für data.table in R mit fread

Ich verstehe, dass fread ist nicht für "prod use" im Moment, und wollte herausfinden, ob es einen Zeitrahmen für die Umsetzung einer Prod-Release gab.

Der Grund, warum ich data.table verwende ist, dass für Dateien solcher Größen, es bei der Verarbeitung der Daten verglichen, um die Datei in einem data.frame Laden usw.

Im Moment extrem effizient ist, ich versuche, zwei andere Alternativen -

1) Unter Verwendung von Scan und Weitergabe an einen 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) Brechen Sie die Datei in mehrere einzelne Segmente mit einem Limit von rd. 500 Millionen Zeilen mit Unix teilen und sequentiell lesen ... dann die Dateien sequentiell in fread durchlaufen - ein bisschen umständlich, aber scheint die einzige praktikable Lösung zu sein.

Ich denke, es gibt vielleicht eine Rcpp-Methode, dies noch schneller zu tun, aber ich bin mir nicht sicher, wie es im Allgemeinen implementiert wird.

Vielen Dank im Voraus.

+1

Vergewissern Sie sich nichts Ungewöhnliches in der Datei in der letzten Zeile ist, die oder der Linie danach gelesen wurde und dann [vorlegen] (https: // r-Schmiede. r-project.org/tracker/?group_id=240) ein Fehlerbericht oder kontaktieren Sie das Paket Mantainer. – Roland

+0

Sind Sie sicher, dass Sie genug RAM haben? Und arbeitest du mit 64bit R? – eddi

+0

Nein, es gibt nicht unbedingt einen schnelleren Weg mit Rcpp, da Matt bereits mmap verwendet. Überprüfen Sie die Betriebssystemdokumentation auf Einschränkungen für den Aufruf von mmap. Milliarden können es drängen ... –

Antwort

8

Ich konnte dies mithilfe von Feedback von einem anderen Beitrag auf Stackoverflow erreichen. Der Prozess war sehr schnell und 40 GB Daten wurden in ungefähr 10 Minuten mit fread iterativ gelesen. Foreach-dopar funktioniert nicht, wenn es von alleine ausgeführt wird, um Dateien in neue data.tables sequentiell zu lesen, aufgrund einiger Einschränkungen, die auch auf der folgenden Seite erwähnt werden.

Hinweis: Die Dateiliste (file_map) wurde einfach durch Ausführen vorbereitet -

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"

Zitiert -

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. 

Meine Funktion einer Schleife Foreach dopar einbezogen, Wird über mehrere Kerne pro Datei ausgeführt, wie in file_map angegeben. Dies erlaubte mir, Dopar zu verwenden, ohne den "Serialization too large error" zu treffen, wenn ich die kombinierte Datei ausführte.

Ein weiterer hilfreicher Beitrag ist - loading files in parallel not working with foreach + data.table

Verwandte Themen