2016-02-25 13 views
5

Provo a caricare un file di dati di grandi dimensioni (circa 20 milioni di righe) utilizzando fread() dal pacchetto . Alcune file stanno causando grandi problemi, tuttavia.Utilizzo di fread per leggere i dati con virgolette doppie e caratteri di escape errati

Esempio minimo:

text.csv contains: 

id, text 
1,"""Oops"",\""The"",""Georgia"""   

fread("text.csv", sep=",") 

Error in fread("text.csv", sep = ",") : 
    Not positioned correctly after testing format of header row. ch=',' 
In addition: Warning message: 
In fread("text.csv", sep = ",") : 
    Starting data input on line 2 and discarding line 1 because it has too few or too many items to be column names or data: id, text 

read.table() opere leggermente migliori ma è troppo lento e troppo memoria inefficiente.

> read.table("text.csv", header = TRUE, sep=",") 
    id      text 
1 1 "Oops",\\"The","Georgia" 

Mi rendo conto che il mio file di testo non è formattato correttamente, ma è troppo grande per essere modificato in modo pratico.

Qualsiasi aiuto molto apprezzato.

EDIT:

Un piccolo campione di record di dati effettivi:

sample1.txt, a good record: 

materiale_id,dk5,description,creator,subject-phrase,title,type 
125030-katalog:000000003,[78.793],Privatoptagelse. - Liveoptagelse,Frederik Lundin,,Koncert i Copenhagen Jazz House den 26.1.1995,music 

> fread("sample1.txt", sep=",") 
       materiale_id  dk5      description   creator subject-phrase 
1: 125030-katalog:000000003 [78.793] Privatoptagelse. - Liveoptagelse Frederik Lundin    NA 
              title type 
1: Koncert i Copenhagen Jazz House den 26.1.1995 music 


sample2.txt, a good and a bad record: 

materiale_id,dk5,description,creator,subject-phrase,title,type 
125030-katalog:000000003,[78.793],Privatoptagelse. - Liveoptagelse,Frederik Lundin,,Koncert i Copenhagen Jazz House den 26.1.1995,music 
150012-leksikon:100019,,"Databehandling vedrører rutiner og procedurer for datarepræsentation, lagring af data, overførsel af data mellem forskellige instanser eller brugere af data, beregninger eller andre operationer udført med...",,"[""Informatik"",""it"",""It, teknik og naturvidenskab"",""leksikonartikel"",""Software, programmering, internet og webkommunikation""]",it - elementer i databehandling,article 

> fread("sample2.txt", sep=",") 
Empty data.table (0 rows) of 11 cols: 150012-leksikon:100019,V2,Databehandling vedrører rutiner og procedurer for datarepræsentation, lagring af data, overførsel af data mellem forskellige instanser eller brugere af data, beregninger eller andre operationer udført med...,V4,[""Informatik","it"... 

EDIT 2:

Aggiornamento a R versione 3.2.3 e 1.9.6 data.table . aiuta a quanto sopra, ma crea problemi con altri record:

sample3.txt, a good and a bad record: 

materiale_id,dk5,description,creator,subject-phrase,title,type 
125030-katalog:000236595,,,Red Tampa Solist prf,"[""Tom"",""Georgia"",""1929-1930""]","Georgia Tom, 1929-1930",music 
125030-katalog:000236596,,,Jane Lucas (Solist),"[""1928-1931"",""Tom,\""The"",""Georgia"",""Accompanist""]","Georgia Tom,""The Accompanist"" (1928-1931)",music 

> s3 <- fread("sample3.txt", sep=",") 
Error in fread("sample3.txt", sep = ",") : 
    Expecting 7 cols, but line 3 contains text after processing all cols. It is very likely that this is due to one or more fields having embedded sep=',' and/or (unescaped) '\n' characters within unbalanced unescaped quotes. fread cannot handle such ambiguous cases and those lines may not have been read in as expected. Please read the section on quotes in ?fread. 

EDIT 3:

l'aggiornamento alla versione di sviluppo 1.9.7 di tabelle di dati rompe fread() del tutto:

> s3 <- fread("sample3.txt", sep=",") 
Error in fread("sample3.txt", sep = ",") : 
    showProgress is not type integer but type 'logical'. Please report. 

EDIT 4:

Sembra che il problema lem nel mio file si verifica quando i record contengono la stringa \\" (litteraly, espressione non regolare). Apparentemente, c'è un backslash troppo grande, che causa fread() di interpretare erroneamente una virgoletta doppia come la fine di una stringa, dove avrebbe dovuto essere presa in letargo.

miei migliori soluzioni finora è di fare questo:

m1 <- readLines("data.csv", encoding="UTF-8") 
m2 <- gsub("\\\\\"", "\\\"", m1)  
writeLines(m2, "data_new.csv", useBytes = TRUE) 
m3 <- fread("data_new.csv", encoding="UTF-8", sep=",") 

che sembra funzionare.

Non capisco questo 100%, quindi qualsiasi chiarimento è più che benvenuto.

+0

Se è solo la riga di intestazione, è possibile saltare la 1a riga su read in. E quindi estrarla di nuovo tramite 'readLines()' e fare le regolazioni appropriate. –

+0

Grazie, ma sono le linee dati che causano problemi occidentali –

+2

Si consiglia di utilizzare qualcosa come [questo] (http://stackoverflow.com/questions/29499145/preventing-column-class-inference-in-fread/29499512 # 29499512), che rimuove le virgolette aggiuntive (solo la prima parte). –

risposta

2

Non un dati.tavolo soluzione, ma si potrebbe provare:

# read the file with 'readLines' 
tmp <- readLines("trl.txt") 

# create a column name vector of the first line 
nms <- trimws(strsplit(tmp[1],',')[[1]]) 

# convert 'tmp' to a dataframe except the first line 
tmp <- as.data.frame(tmp[-1]) 

# use 'separate' from 'tidyr' to split into two columns 
library(tidyr) 
df1 <- separate(tmp, "tmp[-1]", nms, sep=",", extra = "merge") 

che dà:

> df1 
    id        text 
1 1 """Oops"",\\""The"",""Georgia""" 

Aggiornamento per modificare 1: Con i nuovi dati di esempio fread sembra essere la lettura dei dati normalmente:

> s1 <- fread("sample1.txt", sep=",") 
> s1 
       materiale_id  dk5      description   creator subject-phrase           title type 
1: 125030-katalog:000000003 [78.793] Privatoptagelse. - Liveoptagelse Frederik Lundin    NA Koncert i Copenhagen Jazz House den 26.1.1995 music 


> s2 <- fread("sample2.txt", sep=",") 
> s2 
       materiale_id  dk5 
1: 125030-katalog:000000003 [78.793] 
2: 150012-leksikon:100019   
                                                      description 
1:                                             Privatoptagelse. - Liveoptagelse 
2: Databehandling vedrører rutiner og procedurer for datarepræsentation, lagring af data, overførsel af data mellem forskellige instanser eller brugere af data, beregninger eller andre operationer udført med... 
      creator                               subject-phrase 
1: Frederik Lundin                                  
2:     [""Informatik"",""it"",""It, teknik og naturvidenskab"",""leksikonartikel"",""Software, programmering, internet og webkommunikation""] 
              title type 
1: Koncert i Copenhagen Jazz House den 26.1.1995 music 
2:    it - elementer i databehandling article 

Aggiornamento per modificare 2 & 3:

Quando si guarda l'errore-messaggio:

errore in fread("sample3.txt", sep = ","): Previsione 7 colli, ma linea 3 contiene il testo dopo l'elaborazione di tutti i colli. È molto probabile che lo sia dovuto a uno o più campi che hanno incorporato sep=',' e/o (senza escape) caratteri '\ n' all'interno di virgolette non scalate. fread non è in grado di gestire casi così ambigui e tali righe potrebbero non essere state lette come previsto. Si prega di leggere la sezione sulle quotazioni in ?fread.

e quindi quando si guarda la seconda riga di sample3.txt vedrete che la quarta colonna contiene anche le virgole. È possibile risolvere questo in tre fasi:

1: Leggere il file con readLines e sostituire l'apertura e il carattere chiusura della quarta colonna con un'altra citazione caratteri:

r3 <- readLines("sample3.txt") 
r3 <- gsub('\"[',"'",r3,fixed=TRUE) 
r3 <- gsub(']\"',"'",r3,fixed=TRUE) 

2: scrittura di nuovo a un file di testo:

writeLines(r3, "sample3-1.txt") 

3: Ora si può leggere con fread (o read.table/read.csv). Poiché il numero di titoli di colonna non è uguale al numero di colonne, sarà necessario utilizzare header = FALSE. esplicitamente impostare anche la citazione caratteri alla nuova quote-personaggio come inserito nel passaggio 2:

s3 <- fread("sample3-1.txt", quote = "\'", header = FALSE, skip = 1) 

che dà:

> s3 
         V1 V2 V3     V4              V5   V6        V7 V8 
1: 125030-katalog:000236595 NA NA Red Tampa Solist prf       ""Tom"",""Georgia"",""1929-1930"" "Georgia Tom      1929-1930" music 
2: 125030-katalog:000236596 NA NA Jane Lucas (Solist) ""1928-1931"",""Tom,\\""The"",""Georgia"",""Accompanist"" "Georgia Tom ""The Accompanist"" (1928-1931)" music 

Dopo di che è possibile assegnare i nomi delle colonne come segue:

names(s3) <- c("character","vector","with","eight","column","names") 

NOTA: Ho utilizzato una versione piuttosto recente (vecchia di due settimane) della v1.9.7 per questo

+0

Grazie @Jaap. Questo è molto innovativo e utile. Non sembra funzionare abbastanza nel mio caso particolare, poiché ci sono campi di testo contenenti virgole. Sto iniziando a pensare che il file sia così irregolare che potrebbe non esserci una soluzione. Grazie comunque, è stato un suggerimento informativo. –

+1

@LasseHjorthMadsen Potresti aggiungere un campione più ampio del testo che causa problemi? – Jaap

+0

Ho aggiunto un paio di punti dati reali. In sample2.txt sembra che sia la quinta colonna contenente una stringa di testo con virgole e virgolette, che sta causando problemi. Grazie ancora, @Jaap –

Problemi correlati