2016-04-28 2 views
0

Ich versuche, eine große Datei mit dem folgende Stück Code zu lesen:Wie Schelm Datenzeilen zu verwalten, während feste Breite-Dateien in R mit laf_open_fwf Lesen

laf <- laf_open_fwf(paste(input$dir,"/",filename,sep=""), column_widths = col_width, 
          column_types=rep("character",length(col_width)),                  
          column_names = column_names) 

Die Leistung ist gut, aber mein Problem ist, dass, Nehmen wir an, die Datei hat ungefähr 100.000 Datenzeilen, die alle der Definition der festen Breite entsprechen; aber in einigen Fällen kann es ein paar Datenzeilen geben, die "scheußlich" sind, da sie nicht den festen Breiten jeder Spalte entsprechen - Daten in einigen Spalten oder wir sagen, eine Spalte könnte länger oder kürzer sein, und wenn das passiert, Der Ausgang dieses Lesers ist vollständig unterbrochen.

Was ich dachte ist, dass jede Datenzeile, die nach der ersten Rogue-Zeile analysiert wird, die der Parser findet, nicht korrekt analysiert wird. Dies geschieht vor allem, wenn die letzte Spalte der Rogue-Datenzeile übermäßige Daten (ist länger als die definierte Breite für sie)

Also alle Ideen, wie Sie dies umgehen würde sehr geschätzt werden.

+0

Möglicherweise müssen Sie 'readLines()' verwenden und die Daten selbst analysieren. – Gopala

+0

Ja Sie haben Recht - ich folgte dieser Logik und ich habe jetzt die rowNumbers aller Rogue-Datensätze und die richtigen Datensätze - aber laf_open_fwf scheint durch Öffnen der Verbindung zu einer Datei funktionieren - so muss ich eine Datei mit nur den richtigen Daten haben . Oder gibt es eine Möglichkeit, mit der ich den Parser angeben kann, nur ausgewählte Datenzeilen zu lesen? – Sandeep

+1

Nicht, dass ich sehen kann. Am einfachsten, wenn Sie ein Unix-Dienstprogramm verwenden können, um diese Zeilen zu markieren und loszuwerden. – Gopala

Antwort

0

Leider geht LaF davon aus, dass alle Zeilen gleich lang sind. Es verwendet die Breite der Zeilen, um schnell zu den angeforderten Zeilen zu springen. Um zu Zeile X zu gehen, weiß es vom Anfang der Zeilen an zum Byte zu gehen (Die 1/2 hängt von dem verwendeten Zeilenzeichen \n/\r\n ab).

Die einzige Lösung ist, die 'Rogue' Zeilen aus der Datei zu entfernen. Im Folgenden gebe ich ein reines R-Beispiel, wie man das macht. Es ist ziemlich schnell.

generieren und Beispieldatei mit ~ 2% ‚Rogue‘ Linien:

lines <- c("abcde3.14", "efghi-123", "abcdef2.11") 
lines <- sample(lines, 1E6, prob = c(0.44, 0.44, 0.02), replace=TRUE) 
writeLines(lines, "test.dat") 

die Datei in Blöcken lesen Zeilen mit der richtigen Länge zu einer Verbindung und den anderen Linien auf eine andere Verbindung zu schreiben. Durch Öffnen der Verbindungen außerhalb der Schleife und halten sie diese öffnen, ist recht schnell:

widths <- c(5,4) 
types <- c("string", "numeric") 
names <- c("a", "b") 
library(LaF) 


con <- file("test.dat", "rt") 
ok <- file("ok.dat", "wt") 
notok <- file("notok.dat", "wt") 
while (TRUE) { 
    l <- readLines(con, n = 1E5) # increase n for faster reading; used 1E5 as example 
    if (length(l) == 0) break; 
    s <- nchar(l) == sum(widths) 
    writeLines(l[s], con = ok) 
    writeLines(l[!s], con = notok) 
} 
close(notok) 
close(ok) 
close(con) 

Die Datei mit den richtigen Linien kann dann durch LaF analysiert werden:

laf <- laf_open_fwf("ok.dat", column_types = types, column_names = names, 
    column_widths = widths) 
laf[,] 

Und Sie können die andere Datei prüfen um zu sehen, was die Fehler sind.

Verwandte Themen