2009-12-09 16 views
28

Sto cercando di leggere un file di testo con diverse lunghezze di riga:Importare dati in R con un numero sconosciuto di colonne?

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 

Per superare questo problema, sto usando il riempimento argomento = TRUE in read.table, quindi:

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

Purtroppo, per valutare la lunghezza massima di fila, read.table legge solo le prime 5 righe del file, e genera un oggetto simile a questo:

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 

c'è AW ay per forzare read.table a scorrere l'intero file per valutare la lunghezza massima della riga? So che una possibile soluzione potrebbe essere quella di fornire il numero della colonna, come:

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

Ma dal momento che ho un sacco di file, ho voluto valutare questo automaticamente entro R. Qualsiasi suggerimento? :-)


EDIT: il file originale non contiene numeri progressivi, quindi questa non è una soluzione:

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

si può mettere un colpo di testa nel file (ad esempio i file hanno un formato coerente)? – Shane

+0

Sfortunatamente no, i file vengono generati esternamente e ogni riga può avere un numero casuale di voci. –

risposta

55

C'è una bella funzione count.fields (vedi aiuto) che conta il numero di colonna per riga:

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

Quindi, utilizzando la seconda soluzione:

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

Brillante. Elegante e veloce :-) –

+0

Buona chiamata. Utilizzo R da più di un anno e non ho mai eseguito questa funzione, anche se è proprio lì alla fine della documentazione read.table! –

+0

Vorrei poter dare più di 1 upvote a questa risposta! Così utile! –

5

Utilizzando count.fields è sicuramente l'approccio giusto per questo, ma solo per completezza:

Un'altra opzione è quella di portare in tutto il testo grezzo e analizzare entro R:

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") 

di combinare un elenco di vettori di lunghezza diversa, l'approccio più semplice è quello di utilizzare la funzione di rbind.fill da plyr:

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 
Problemi correlati