Ich habe also eine Datendatei (durch Semikolons getrennt), die viele Details und unvollständige Zeilen enthält (was dazu führt, dass Access und SQL ersticken). Der Datensatz auf Kreisebene ist seit 40 Jahren in Segmente, Untersegmente und Untersegmente unterteilt (für insgesamt ~ 200 Faktoren). Kurz gesagt, es ist riesig und es wird nicht in die Erinnerung passen, wenn ich versuche, es einfach zu lesen.
Meine Frage lautet also, da ich alle Landkreise, aber nur ein einziges Jahr (und nur die höchste Segmentebene ... die am Ende zu etwa 100.000 Zeilen führen möchte) möchte, was der beste Weg wäre, um dies zu erreichen dieses Rollup in R?
Momentan versuche ich, irrelevante Jahre mit Python zu beenden, um das Dateigrößenlimit zu umgehen, indem ich jeweils eine Zeile lese und arbeite, aber ich würde eine Nur-R-Lösung bevorzugen (CRAN-Pakete OK). Gibt es eine ähnliche Möglichkeit, Dateien in R Stück für Stück einzulesen?
Irgendwelche Ideen wären sehr dankbar.
Aktualisieren:
- Einschränkungen
- Muss meine Maschine benutzen , also keine EC2-Instanzen
- So nur R-möglich wie möglich. Geschwindigkeit und Ressourcen spielen in diesem Fall keine Rolle ... vorausgesetzt, meine Maschine explodiert nicht ...
- Wie Sie unten sehen können, enthalten die Daten gemischte Typen, mit denen ich später arbeiten muss
- Daten
- Die Daten sind 3,5 GB groß, mit etwa 8,5 Millionen Zeilen und 17 Spalten
- Ein paar tausend Zeilen (~ 2k) sind fehlerhaft, mit nur einer Spalte anstelle von 17
- Diese sind völlig unwichtig und können fallengelassen werden
- Ich brauche nur ~ 100.000 Zeilen aus dieser Datei (siehe unten)
Datenbeispiel:
County; State; Year; Quarter; Segment; Sub-Segment; Sub-Sub-Segment; GDP; ...
Ada County;NC;2009;4;FIRE;Financial;Banks;80.1; ...
Ada County;NC;2010;1;FIRE;Financial;Banks;82.5; ...
NC [Malformed row]
[8.5 Mill rows]
Ich möchte einige Spalten herausschneiden und zwei von 40 verfügbaren Jahren (2009-2010 von 1980-2020) auswählen, damit die Daten in R passen:
County; State; Year; Quarter; Segment; GDP; ...
Ada County;NC;2009;4;FIRE;80.1; ...
Ada County;NC;2010;1;FIRE;82.5; ...
[~200,000 rows]
Ergebnisse:
Nachdem ich an allen gemachten Vorschlägen herumgebastelt hatte, entschied ich, dass readLines, vorgeschlagen von JD und Marek, am besten funktionieren würde. Ich gab Marek den Scheck, weil er eine Beispielimplementierung gab.
Ich habe eine leicht angepasste Version von Mareks Implementierung für meine endgültige Antwort hier reproduziert und strsplit und cat verwendet, um nur die gewünschten Spalten beizubehalten.
Es sollte auch beachtet werden, dass dies VIEL weniger effizient ist als Python ... wie in, Python durchläuft die 3,5-GB-Datei in 5 Minuten, während R ungefähr 60 dauert ... aber wenn Sie nur R haben, dann ist dies das Ticket.
## Open a connection separately to hold the cursor position
file.in <- file('bad_data.txt', 'rt')
file.out <- file('chopped_data.txt', 'wt')
line <- readLines(file.in, n=1)
line.split <- strsplit(line, ';')
# Stitching together only the columns we want
cat(line.split[[1]][1:5], line.split[[1]][8], sep = ';', file = file.out, fill = TRUE)
## Use a loop to read in the rest of the lines
line <- readLines(file.in, n=1)
while (length(line)) {
line.split <- strsplit(line, ';')
if (length(line.split[[1]]) > 1) {
if (line.split[[1]][3] == '2009') {
cat(line.split[[1]][1:5], line.split[[1]][8], sep = ';', file = file.out, fill = TRUE)
}
}
line<- readLines(file.in, n=1)
}
close(file.in)
close(file.out)
Fehler nach Ansatz:
- sqldf
- Dies ist definitiv das, was ich in Zukunft für diese Art von Problem verwenden werde, wenn die Daten wohlgeformt sind. Wenn dies nicht der Fall ist, erstickt SQLite.
- Karte verkleinern
- Um ehrlich zu sein, haben mich die Dokumente ein wenig eingeschüchtert, so dass ich nicht dazu gekommen bin, es zu versuchen. Es sah so aus, als müsste sich das Objekt ebenfalls im Speicher befinden, was den Punkt zunichte machen würde, wenn dies der Fall wäre.
- Bigmemory
- Dieser Ansatz ist sauber mit den Daten verknüpft, kann jedoch jeweils nur einen Typ verarbeiten. Infolgedessen fielen alle meine Zeichenvektoren, wenn sie in eine große Tabelle eingefügt wurden. Wenn ich jedoch große Datenmengen für die Zukunft entwerfen muss, würde ich nur Zahlen verwenden, um diese Option am Leben zu erhalten.
- Scan
- Scan schien ähnliche Probleme mit dem Typ zu haben wie großer Speicher, aber mit allen Mechanismen von readLines. Kurz gesagt, diesmal passte es einfach nicht.
sed
und / oderawk
zu erstellen, die Sie direkt einlesen können. Da dies eher eine Problemumgehung als eine Antwort ist, werde ich es als Kommentar hinterlassen.fread
Funktion ist viel schneller alsread.table
. Verwenden Sie so etwas wiex = fread(file_path_here, data.table=FALSE)
, um es alsdata.frame
Objekt zu laden .Antworten:
Mein Versuch mit
readLines
. Dieser Teil eines Codes wirdcsv
mit ausgewählten Jahren erstellt.quelle
Ich bin kein Experte in diesem Bereich, aber Sie könnten MapReduce ausprobieren , was im Grunde bedeuten würde, einen "Divide and Conquer" -Ansatz zu wählen. R hat hierfür mehrere Optionen, darunter:
Alternativ bietet R mehrere Pakete für große Datenmengen, die außerhalb des Speichers (auf die Festplatte) gehen. Sie könnten wahrscheinlich den gesamten Datensatz in ein
bigmemory
Objekt laden und die Reduzierung vollständig in R durchführen. Eine Reihe von Tools finden Sie unter http://www.bigmemory.org/ .quelle
bigmemory
In diesem Fall ist es möglicherweise einfacher, es zuerst zu versuchen.Ja. Die Funktion readChar () liest einen Zeichenblock ein, ohne davon auszugehen, dass sie nullterminiert sind. Wenn Sie Daten gleichzeitig in einer Zeile lesen möchten, können Sie readLines () verwenden . Wenn Sie einen Block oder eine Zeile lesen, eine Operation ausführen und dann die Daten ausschreiben, können Sie das Speicherproblem vermeiden. Wenn Sie jedoch eine große Speicherinstanz auf Amazon EC2 starten möchten, können Sie bis zu 64 GB RAM erhalten. Das sollte Ihre Datei und viel Platz zum Bearbeiten der Daten enthalten.
Wenn Sie mehr Geschwindigkeit benötigen, ist die Empfehlung von Shane, Map Reduce zu verwenden, sehr gut. Wenn Sie jedoch eine große Speicherinstanz auf EC2 verwenden, sollten Sie sich das Multicore-Paket ansehen, um alle Kerne auf einem Computer zu verwenden.
Wenn Sie viele Gigs mit begrenzten Daten in R lesen möchten, sollten Sie zumindest das sqldf-Paket untersuchen, mit dem Sie direkt aus R in sqldf importieren und dann die Daten aus R heraus verarbeiten können. Ich habe festgestellt, dass sqldf eines davon ist der schnellsten Möglichkeiten, Datenmengen in R zu importieren, wie in dieser vorherigen Frage erwähnt .
quelle
Es gibt ein brandneues Paket namens colbycol, mit dem Sie nur die gewünschten Variablen aus riesigen Textdateien einlesen können:
http://colbycol.r-forge.r-project.org/
Es gibt alle Argumente an read.table weiter, daher sollte die Kombination eine ziemlich enge Teilmenge ermöglichen.
quelle
Das
ff
Paket ist eine transparente Möglichkeit, mit großen Dateien umzugehen.Möglicherweise sehen Sie die Paket- Website und / oder eine Präsentation darüber.
ich hoffe das hilft
quelle
Sie können Daten in die SQLite-Datenbank importieren und dann mithilfe von RSQLite Teilmengen auswählen.
quelle
Was ist mit
readr
und derread_*_chunked
Familie?Also in deinem Fall:
testfile.csv
Tatsächlicher Code
Dies gilt
f
für jeden Block, wobei die Spaltennamen gespeichert und am Ende die gefilterten Ergebnisse kombiniert werden. Sehen Sie,?callback
woher dieses Beispiel stammt.Das führt zu:
Sie können sogar erhöhen,
chunk_size
aber in diesem Beispiel gibt es nur 4 Zeilen.quelle
Haben Sie Bigmemory angesehen ? Schauen Sie sich dies und das an .
quelle
Möglicherweise können Sie auf MySQL oder PostgreSQL migrieren, um sich vor MS Access-Einschränkungen zu schützen.
Es ist recht einfach, R mit einem DBI- basierten Datenbankconnector (verfügbar auf CRAN) mit diesen Systemen zu verbinden .
quelle
scan () hat sowohl ein nlines-Argument als auch ein skip-Argument. Gibt es einen Grund, warum Sie dies einfach verwenden können, um einen Teil der Zeilen zu lesen und das Datum zu überprüfen, um festzustellen, ob es angemessen ist? Wenn die Eingabedatei nach Datum sortiert ist, können Sie einen Index speichern, der Ihnen sagt, wie Ihr Sprung und Ihre Zeilen lauten sollten, um den Prozess in Zukunft zu beschleunigen.
quelle
Heutzutage sind 3,5 GB nicht wirklich so groß, ich kann für 2,80 USD / Stunde auf einen Computer mit 244 GB RAM (r3.8xlarge) in der Amazon Cloud zugreifen. Wie viele Stunden werden Sie brauchen, um herauszufinden, wie Sie das Problem mithilfe von Big-Data-Lösungen lösen können? Wie viel ist deine Zeit wert? Ja, Sie werden ein oder zwei Stunden brauchen, um herauszufinden, wie Sie AWS verwenden. Sie können jedoch die Grundlagen auf einer kostenlosen Ebene erlernen, die Daten hochladen und die ersten 10.000 Zeilen in R lesen, um zu überprüfen, ob sie funktionieren, und dann können Sie a starten große Speicherinstanz wie r3.8xlarge und alles einlesen! Nur mein 2c.
quelle
Jetzt, 2017, würde ich vorschlagen, sich für Spark und SparkR zu entscheiden.
Die Syntax kann auf einfache, eher dplyr-ähnliche Weise geschrieben werden
es passt ganz gut zu kleinem Speicher (klein im Sinne von 2017)
Es kann jedoch eine einschüchternde Erfahrung sein, loszulegen ...
quelle
Ich würde mich für eine Datenbank entscheiden und dann einige Fragen stellen, um die benötigten Beispiele über DBI zu extrahieren
Bitte vermeiden Sie den Import einer 3,5-GB-CSV-Datei in SQLite. Oder überprüfen Sie mindestens, ob Ihre RIESIGE Datenbank den SQLite-Grenzwerten entspricht ( http://www.sqlite.org/limits.html)
Es ist eine verdammt große DB, die du hast. Ich würde mich für MySQL entscheiden, wenn Sie Geschwindigkeit brauchen. Warten Sie jedoch viele Stunden, bis der Import abgeschlossen ist. Es sei denn, Sie haben unkonventionelle Hardware oder schreiben aus der Zukunft ...
Amazon EC2 könnte auch eine gute Lösung sein, um einen Server mit R und MySQL zu instanziieren.
meine zwei bescheidenen Pfennige wert.
quelle