Sono occupato nella pulizia dei dati. Ho una funzione che identifica le righe danneggiate in un file di input di grandi dimensioni (troppo grande per essere letto in una volta sola, data la dimensione della ram) e restituisce i numeri di riga delle righe danneggiate come un vettore badRows
. Questa funzione sembra funzionare.Come posso leggere le righe selezionate da un file di grandi dimensioni utilizzando il comando R "readLines" e scriverle su un frame di dati?
Ora sto provando a leggere solo le righe danneggiate in un frame di dati, finora senza successo.
Il mio approccio attuale è quello di utilizzare read.table
su una connessione aperta al mio file, utilizzando un vettore del numero di righe da saltare tra ogni riga che viene letta. Questo numero è zero per le righe danneggiate consecutive.
ho calcolare skipVec
come:
(badRowNumbers - c(0, badRowNumbers[1:(length(badRowNumbers-1]))-1
Ma per il momento io sono solo distribuendo la mia funzione un skipVec
vettore di tutti gli zeri.
Se la mia logica è corretta, questo dovrebbe restituire tutte le righe. Non è così. Invece ottengo un errore:
"Error in read.table(con, skip = pass, nrow = 1, header = TRUE, sep = "") : no lines available in input"
La mia funzione attuale è vagamente basato su una funzione da Miron Kursa ("MBq"), che ho trovato here.
La mia domanda è in qualche modo duplicativa di quella, ma presumo che la sua funzione funzioni, quindi l'ho interrotta in qualche modo. Sto ancora cercando di capire la differenza tra l'apertura di un file e l'apertura di una connessione a un file, e ho il sospetto che il problema ci sia da qualche parte o nel mio utilizzo di lapply
.
Sto utilizzando R 3.0.1 sotto RStudio 0.97.551 su una vecchia macchina Windows XP SP3 con 3gig di ram. Stone Age, lo so.
Ecco il codice che genera il messaggio di errore precedente:
# Make a small small test data frame, write it to a file, and read it back in
# a row at a time.
testThis.DF <- data.frame(nnn=c(2,3,5), fff=c("aa", "bb", "cc"))
testThis.DF
# This function will work only if the number of bad rows is not too big for memory
write.table(testThis.DF, "testThis.DF")
con<-file("testThis.DF")
open(con)
skipVec <- c(0,0,0)
badRows.DF <- lapply(skipVec, FUN=function(pass){
read.table(con, skip=pass, nrow=1, header=TRUE, sep="") })
close(con)
L'errore si verifica prima che il comando di chiusura. Se strappo il comando readLines dal lapply e dalla funzione e lo inserisco da solo, continuo a ricevere lo stesso errore.
Caro @ flodel- Questo codice non funziona, ma penso che questo sia solo un errore di battitura, perché funziona per skipVec = 0,0,0 invece di 0,1,0. Sebbene funzioni, sono imbarazzato nell'ammettere che mi manca una parte della logica. Per prima cosa, non so perché scannerizzi la prima riga e usi read.table per il resto. Ma la mia più grande confusione, forse perché non capisco come i file e le connessioni sono elaborati in modo diverso, è che non vedo perché skipVec = 0,0,0 non inizia alla prima riga. Inoltre, non so cosa sia un rle. Ho letto la funzione doc, ma non so che cos'è una corsa o una lunghezza della corsa, o come scoprirlo. – andrewH
* Questo codice non funziona * non è molto utile per me a meno che tu non mi dica perché non funziona. Uscita imprevista, messaggio di errore? Nota che funziona con il tuo esempio, quindi forse il tuo file di dati reali ha un formato diverso da quello che ci stai costruendo in questo esempio. – flodel
Una connessione è come un file che viene tenuto aperto, quindi è possibile accedervi più volte per la lettura o la scrittura. La connessione include un puntatore a dove sono stati letti o scritti i dati. Quando apri per la prima volta il file, l'handle del file punta all'inizio del file. Dopo aver usato 'read.table (con, skip = 0, nrow = 1, header = TRUE, sep =" ")' la prima volta vengono letti l'intestazione e la prima riga di dati del tuo file, quindi il puntatore sta puntando all'inizio della seconda riga di dati. – flodel