2010-11-05 12 views
39

Ho un file in cui ogni riga è un insieme di risultati raccolti in repliche specifiche di un esperimento. Il numero di risultati in ciascun esperimento (ovvero il numero di colonne in ogni riga) può essere diverso. Inoltre, non vi è alcuna importanza per l'ordine dei risultati in ogni riga (il primo risultato nella riga 1 e il primo risultato 2 non sono più correlati di qualsiasi altra coppia, questi sono set di risultati).Qual è un buon modo per leggere riga per riga in R?

Il file simile a questa:

2141 0 5328 5180 357 5335 1 5453 5325 5226 7 4880 5486 0 
2650 0 5280 4980 5243 5301 4244 5106 5228 5068 5448 3915 4971 5585 4818 4388 5497 4914 5364 4849 4820 4370 
2069 2595 2478 4941 
2627 3319 5192 5106 32 4666 3999 5503 5085 4855 4135 4383 4770 
2005 2117 2803 2722 2281 2248 2580 2697 2897 4417 4094 4722 5138 5004 4551 5758 5468 17361 
1914 1977 2414 100 2711 2171 3041 5561 4870 4281 4691 4461 5298 3849 5166 5578 5520 4634 4836 4905 5105 5089 
2539 2326 0 4617 3735 0 5122 5439 5238 1 
25 5316 21173 4492 5038 5944 5576 5424 5139 5184 5 5096 4963 2771 2808 2592 2 
4963 9428 17152 5467 5202 6038 5094 5221 5469 5079 3753 5080 5141 4097 5173 11338 4693 5273 5283 5110 4503 51 
2024 2 2822 5097 5239 5296 4561 

salvo ogni linea è molto più lungo (fino a qualche migliaio di valori). Come si può vedere, tutti i valori sono numeri interi non negativi.

Per farla breve - questo non è un tavolo normale, dove le colonne hanno significati. Sono solo un mucchio di risultati, ognuno in linea.

desidero leggere tutti i risultati, quindi eseguire alcune operazioni di ciascun esperimento (riga), come il calcolo del ecdf. Vorrei anche calcolare l'ecdf medio su tutti i replicati.

Il mio problema - come dovrei leggere questo file in cerca di strano? Sono così usare per read.table che non sono sicuro che io abbia mai provato qualsiasi altra cosa ... Devo usare qualche basso livello come readlines? Immagino che l'output preferito sia una lista (o vettore?) Di vettori. Ho guardato scan ma sembra che tutti i vettori debbano essere della stessa lunghezza lì.

Qualsiasi suggerimento sarà apprezzato.

UPDATE Seguendo i suggerimenti di seguito, io ora faccio qualcosa di simile:

con <- file('myfile') 
open(con); 
results.list <- list(); 
current.line <- 1 
while (length(line <- readLines(con, n = 1, warn = FALSE)) > 0) { 
results.list[[current.line]] <- as.integer(unlist(strsplit(line, split=" "))) 
current.line <- current.line + 1 
} 
close(con) 

sembra funzionare. Sembra ok?

Quando ho summary(results.list) ottengo: Lunghezza Modo Classe

 Length Class Mode 
[1,] 1091 -none- numeric 
[2,] 1070 -none- numeric 
    .... 

Non dovrebbe essere la classe intero? E qual è la modalità?

+0

Che tipo di file? Potresti farti un esempio? –

+0

@Brandon Bertelsen: certo, guarda il post aggiornato. –

risposta

27

L'esempio Josh collegato a è uno che uso tutto il tempo.

inputFile <- "/home/jal/myFile.txt" 
con <- file(inputFile, open = "r") 

dataList <- list() 
ecdfList <- list() 

while (length(oneLine <- readLines(con, n = 1, warn = FALSE)) > 0) { 
    myVector <- (strsplit(oneLine, " ")) 
    myVector <- list(as.numeric(myVector[[1]])) 
    dataList <- c(dataList,myVector) 

    myEcdf <- ecdf(myVector[[1]]) 
    ecdfList <- c(ecdfList,myEcdf) 

    } 

close(con) 

Ho modificato l'esempio per creare due elenchi dai dati di esempio. dataList è una lista in cui ogni elemento della lista è un vettore di valori numerici da ogni riga del tuo file di testo. ecdfList è una lista in cui ogni elemento è un ecdf per ogni riga del tuo file di testo.

Probabilmente dovresti aggiungere qualche logica try() o trycatch() lì per gestire correttamente le situazioni in cui non è possibile creare l'ecdf a causa di valori null o simili. Ma l'esempio sopra riportato ti dovrebbe avvicinare molto. In bocca al lupo!

+0

+ 1 grazie! per convertire la linea in un vettore di interi uso 'as.integer (unlist (strsplit (oneLine, split =" ")))'. Funziona, ma mi chiedo se c'è un modo migliore? Inoltre, come suggeriresti di mettere tutti quei vettori in una lista/vettore? Nota anche che ho aggiunto un campione all'OP. –

+0

Non sono sicuro se la tua conversione sia "migliore" della mia. Il metodo che uso è quello in cui mi sono imbattuto durante l'apprendimento di R e ho la brutta abitudine di apprendere un singolo idioma che funziona e quindi di usare sempre quell'unico idioma anche se esiste un "modo migliore". –

17

Sì, è possibile utilizzare readLines. JD Long has a good example, che ho modificato leggermente e fornito di seguito.

con <- file(inputFile, open = "r") 

while (length(oneLine <- readLines(con, n = 1, warn = FALSE)) > 0) { 
    # do stuff 
} 

close(con) 
+2

Bello. Stavo armeggiando per un po 'con la condizione 'while'. Strano che non abbiamo 'isEOF()' o così. –

2

Uso

line <- readLines(con, 1) 

per leggere una linea dalla connessione con, che può essere semplice come con <- file(filename, "r").

5

Oppure:

df <- read.delim(file="whatever", header=F, sep = " ") 
1

se si sa che i valori nel file sono numeri interi, è possibile utilizzare scan() invece di readLines(), ma anche in un ciclo:

open(con) 
results.list <- list(); 
current.line <- 1 
while(length(line <- scan(con,what=integer(0),nlines=1,quiet=TRUE))>0) { 
    results.list[[current.line]] <- line 
    current.line <- current.line + 1 
} 
close(con) 

avrete una lista di vettori numerici.

8

Perché preoccuparsi della lettura riga per riga?

results.list <- lapply(strsplit(readLines("myfile")," "), as.integer) 

fornisce un elenco di vettori di numeri interi.

Chi le vostre domande: dare un'occhiata a ?mode (in breve - mode è numerico per i numeri, typeof può essere intero o doppia, e class numerico o intero). Per vedere se ci sono numeri interi controlla str(results.list) o lapply(results.list, class).

Problemi correlati