2012-03-26 10 views
11

Ich möchte eine große Datentabelle in R LINE BY LINE streamen, und wenn die aktuelle Zeile eine bestimmte Bedingung hat (sagen wir, die ersten Spalten sind> 15), fügen Sie die Zeile zu einem Daten hinzu Rahmen im Speicher. Ich habe folgenden Code geschrieben:R - STDIN Zeile für Zeile lesen

count<-1; 
Mydata<-NULL; 
fin <- FALSE; 
while (!fin){ 
    if (count==1){ 
     Myrow=read.delim(pipe('cat /dev/stdin'), header=F,sep="\t",nrows=1); 
     Mydata<-rbind(Mydata,Myrow); 
     count<-count+1; 
    } 
    else { 
     count<-count+1; 
     Myrow=read.delim(pipe('cat /dev/stdin'), header=F,sep="\t",nrows=1); 
     if (Myrow!=""){ 
     if (MyCONDITION){ 
      Mydata<-rbind(Mydata,Myrow); 
     } 
     } 
     else 
     {fin<-TRUE} 
    } 
} 
print(Mydata); 

Aber ich bekomme den Fehler "Daten nicht verfügbar". Bitte beachten Sie, dass meine Daten groß sind und ich möchte nicht alles einmal lesen und meine Bedingung (in diesem Fall war es einfach) anwenden.

+0

Sie können in den Antworten und Kommentare zu diesem q interessieren:? Http://stackoverflow.com/questions/9352887/strategies-for-reading-in-csv-files-in-pieces –

+0

'see scan ','? readLines', 'nrows' Argument von' read.table', und sei dir bewusst, dass deine Lösung ** sehr ** langsam in R ist - kannst du Perl oder sogar awk zur Vorverarbeitung verwenden? –

+1

Wie würde meine Antwort in Bezug auf Geschwindigkeit unterlegen? Im Wesentlichen öffne ich eine Datei und führe Linien davon aus, ohne die Datei zu schließen. –

Antwort

11

Ich denke, es wäre klüger, eine R-Funktion wie readLines zu verwenden. readLines unterstützt nur das Lesen einer bestimmten Anzahl von Zeilen, z.B. 1. Kombiniere das mit dem Öffnen einer file Verbindung zuerst, und dann ruft readLines wiederholt Sie, was Sie wollen. Beim mehrmaligen Aufruf von readLines werden die nächsten n Zeilen aus der Verbindung gelesen. In R-Code:

stop = FALSE 
f = file("/tmp/test.txt", "r") 
while(!stop) { 
    next_line = readLines(f, n = 1) 
    ## Insert some if statement logic here 
    if(length(next_line) == 0) { 
    stop = TRUE 
    close(f) 
    } 
} 

Bemerkungen:

  • R verfügt über einen internen Weg stdin als Datei zur Behandlung von: stdin(). Ich schlage vor, dass Sie dies anstelle von pipe('cat /dev/stdin') verwenden. Dies macht es wahrscheinlich robuster und definitiv plattformübergreifender.
  • Sie initialisieren Mydata am Anfang und wachsen weiter mit rbind. Wenn die Anzahl der Zeilen, die Sie rbind größer wird, wird dies wirklich langsam. Dies hat mit der Tatsache zu tun, dass das Betriebssystem, wenn das Objekt wächst, einen neuen Speicherort für es finden muss, der am Ende viel Zeit ist. Besser ist die Vorbelegung von MyData oder die Verwendung von Style-Loops.
+0

Danke für die Antwort. Aber ich habe eine Frage dazu: Wie ich schon erwähnt habe, sind meine Daten sehr groß und ich möchte sie nicht im Speicher ablegen. In Zeile 3 Ihres Codes scheint es, dass Sie die gesamten Daten lesen und dann durch die Zeilen gehen. Habe ich recht? – user1250144

+0

Nein, ich öffne eine Verbindung und lese dann davon. 'next_line' enthält nur die aktuelle Zeile. Mit 'file' wird nur eine Verbindung geöffnet, es wird noch nichts gelesen. –

+0

Ahan. Vielen Dank. Was soll ich anstelle von "/tmp/test.txt", dem ersten Argument von file() schreiben? – user1250144