2009-12-09 3 views
28

Ich versuche, eine Textdatei mit unterschiedlichen Zeilenlängen zu lesen:Importieren Sie Daten in R mit einer unbekannten Anzahl von Spalten?

1 
1 2 
1 2 3 
1 2 3 4 
1 2 3 4 5 
1 2 3 4 5 6 
1 2 3 4 5 6 7 
1 2 3 4 5 6 7 8 

Um dieses Problem zu überwinden, ich bin mit dem Argument fill = TRUE in read.table, so:

data<-read.table("test",sep="\t",fill=TRUE) 

Leider die maximale Zeilenlänge zu beurteilen, liest read.table nur die ersten fünf Zeilen der Datei und erzeugt ein Objekt wie folgt aussehen:

data 
    V1 V2 V3 V4 V5 
1 1 NA NA NA NA 
2 1 2 NA NA NA 
3 1 2 3 NA NA 
4 1 2 3 4 NA 
5 1 2 3 4 5 
6 1 2 3 4 5 
7 6 NA NA NA NA 
8 1 2 3 4 5 
9 6 7 NA NA NA 
10 1 2 3 4 5 
11 6 7 8 NA NA 

gibt es aw Sie können read.table zwingen, über die gesamte Datei zu blättern, um die maximale Zeilenlänge zu ermitteln. Ich weiß, eine mögliche Lösung die Spaltennummer zur Verfügung zu stellen wäre, wie:

data<-read.table("test",sep="\t",fill=TRUE,col.names=c(1:8)) 

Aber da ich eine Menge von Dateien habe, wollte ich diese Jeden Vorschlag innerhalb R. automatisch beurteilen? :-)


EDIT: die Original-Datei enthält keine progressiven Zahlen, so ist dies keine Lösung:

data1<-read.table("test",sep="\t",fill=TRUE) 
data2<-read.table("test",sep="\t",fill=TRUE,col.names=c(1:max(data1)) 
+0

können Sie einen Header in der Datei gesetzt (dh haben die Dateien ein konsistentes Format? – Shane

+0

Leider nicht, die Dateien werden extern generiert und jede Zeile kann eine zufällige Anzahl von Einträgen haben. –

Antwort

55

Es gibt nette Funktion count.fields (siehe Hilfe), die Anzahl der Spalten zählt pro Zeile:

count.fields("test", sep = "\t") 
#[1] 1 2 3 4 5 6 7 8 

Also, Ihre zweite Lösung mit:

no_col <- max(count.fields("test", sep = "\t")) 
data <- read.table("test",sep="\t",fill=TRUE,col.names=1:no_col) 
data 
# X1 X2 X3 X4 X5 X6 X7 X8 
# 1 1 NA NA NA NA NA NA NA 
# 2 1 2 NA NA NA NA NA NA 
# 3 1 2 3 NA NA NA NA NA 
# 4 1 2 3 4 NA NA NA NA 
# 5 1 2 3 4 5 NA NA NA 
# 6 1 2 3 4 5 6 NA NA 
# 7 1 2 3 4 5 6 7 NA 
# 8 1 2 3 4 5 6 7 8 
+0

Brilliant. Elegant und schnell :-) –

+0

Guter Anruf. Ich benutze R seit über einem Jahr und bin nie in diese Funktion gelaufen, obwohl es direkt am Ende der read.table-Dokumentation ist! –

+0

Ich wünschte, ich könnte mehr als 1 Upvote zu dieser Antwort geben! So nützlich! –

5

Mit count.fields ist auf jeden Fall den richtigen Ansatz dafür, aber nur der Vollständigkeit halber:

Eine weitere Option in all den Rohtext zu bringen ist und es innerhalb von R zu analysieren:

x <- readLines(textConnection(
"1\t 
1\t2 
1\t2\t3 
1\t2\t3\t4 
1\t2\t3\t4\t5 
1\t2\t3\t4\t5\t6")) 
x <- strsplit(x,"\t") 

zu kombinieren, um eine Liste von ungleiche Länge Vektoren, der einfachste Ansatz ist es, die rbind.fill Funktion von plyr zu verwenden:

library(plyr) 
# requires data.frames with column names 
x <- lapply(x,function(x) {x <- as.data.frame(t(x)); colnames(x)=1:length(x); return(x)}) 
do.call(rbind.fill,x) 
1 2 3 4 5 6 
1 1 <NA> <NA> <NA> <NA> <NA> 
2 1 2 <NA> <NA> <NA> <NA> 
3 1 2 3 <NA> <NA> <NA> 
4 1 2 3 4 <NA> <NA> 
5 1 2 3 4 5 <NA> 
6 1 2 3 4 5 6 
Verwandte Themen