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.
fread
Funktion ist viel schneller als read.table
. Verwenden Sie so etwas wie x = fread(file_path_here, data.table=FALSE)
, um es als data.frame
Objekt zu laden .
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.