2017-01-13 2 views
0

ich in einer Reihe von Textdateien lese, die Datenzeilen mit einigen Kopfzeilen an der Spitze, die Informationen für die Daten enthalten, etwa so:Leselinien in der Nähe Kommentare in R mit read.table

Test file 
# 
File information 
1 2 3 4 
# 
a 2 
b 4 
c 6 
d 8 

Ich möchte die verschiedenen Informationen einzeln aus dieser Datei einlesen. Ich kann dies erreichen gerade fein wie so:

file <- read.table(txt, nrow = 1) 
name <- read.table(txt, nrow = 1, skip = 2) 
vals <- read.table(txt, nrow = 1, skip = 3) 
data <- read.table(txt,   skip = 5) 

Aufgrund der zwei leeren Kommentarzeilen, habe ich auch in den Daten wie diese gelesen haben könnte:

file <- read.table(txt, nrow = 1) 
name <- read.table(txt, nrow = 1, skip = 1) # Skip changed from 2 
vals <- read.table(txt, nrow = 1, skip = 3) 
data <- read.table(txt,   skip = 4) # Skip changed from 5 

Das ist schön und gut, aber die Textdateien haben nicht immer die gleiche Anzahl von leeren Kommentarzeilen; manchmal sind sie anwesend, manchmal nicht. Wenn ich die Kommentarzeilen in meiner Beispieltextdatei entweder (oder beide) verliere, funktioniert keine meiner Lösungen weiter.

Gibt es eine robustere Möglichkeit, eine Textdatei einzulesen, in der die skip Variable niemals eine Kommentarzeile zählt? Ersetzen

(Die Verwendung von textConnection(...) ist Funktionen Trick eine Zeichenfolge erwartet Dateiverbindungen in der Verarbeitung:

+2

Etwas wie, Linien <- readLines (txt); lines_clean <- linien [substr (linien, 1, 1)! = "#"] ' –

Antwort

2

(nach den Datei-Metadaten an der Spitze, sobald die Daten beginnen, gibt es keine weiteren Kommentare Annahme.). der Funktionsaufruf mit dem Dateinamen.)

eine Technik ist die ersten n Zeilen einer Datei (eine Zahl „garantiert“, um alle der kommentierten/nicht-Datenzeilen), finden Sie die letzten, zu lesen und dann Deal mit All-Vorher und All-After entsprechend:

txt <- "Test file 
# 
File information 
1 2 3 4 
# 
a 2 
b 4 
c 6 
d 8" 
max_comment_lines <- 8 
(dat <- readLines(textConnection(txt), n = max_comment_lines)) 
# [1] "Test file"  "#"    "File information" "1 2 3 4"   
# [5] "#"    "a 2"    "b 4"    "c 6"    
(skip <- max(grep("^\\s*#", dat))) 
# [1] 5 

(BTW:. Sollte wohl einen Scheck tun, um sicherzustellen, dass es in der Tat Kommentare sind ... dies sonst integer(0) zurückkehren wird, und die read* Funktionen mag das nicht als Argument)

Jetzt, wo wir " wissen“, dass der letzte gefundene Kommentar ist auf der Linie 5, die ersten 4 Zeilen verwenden kann, um Header-Informationen zu erhalten ...

meta <- readLines(textConnection(txt), n = skip - 1) 
meta <- meta[! grepl("^\\s*#", meta) ] # remove the comment rows themselves 
meta 
# [1] "Test file"  "File information" "1 2 3 4"   

... und überspringen 5 Zeilen auf die Daten zu erhalten.

dat <- read.table(textConnection(txt), skip = skip) 
str(dat) 
# 'data.frame': 4 obs. of 2 variables: 
# $ V1: Factor w/ 4 levels "a","b","c","d": 1 2 3 4 
# $ V2: int 2 4 6 8 
+0

Natürlich ... duh. Vielen Dank. – r2evans

+0

Danke auch für den 'textConnection' Trick, das ist ein nettes bisschen Bonusinfo! – hfisch

+0

Technisch haben 'read.table' und Freunde ein 'text =' Argument, das die Zeichenfolge akzeptiert, anstatt nach einer Datei zu suchen. Da 'readLines' nicht' text = 'hat, habe ich' textConnection' aus Konsistenzgründen verwendet, obwohl dies nicht unbedingt notwendig ist. – r2evans

Verwandte Themen