2013-02-25 19 views
5

Ho alcuni dati e sto cercando di caricarlo in R. È in file .csv e posso visualizzare i dati sia in Excel che in OpenOffice. (Se sei curioso, sono i dati dei sondaggi del 2011 tratti dai dati di Elections Canada disponibili here).Problemi di quotazione durante la lettura dei dati in R

I dati sono codificati in modo insolito. Una linea tipica è:

12002,Central Nova","Nova-Centre"," 1","River John",N,N,"",1,299,"Chisholm","","Matthew","Green Party","Parti Vert",N,N,11 

C'è un " sulla fine della Centrale-Nova, ma non all'inizio. Quindi, per leggere i dati, ho soppresso le virgolette, che funzionavano bene per i primi file. vale a dire.

test<-read.csv("pollresults_resultatsbureau11001.csv",header = TRUE,sep=",",fileEncoding="latin1",as.is=TRUE,quote="") 

Ora qui è il problema: in un altro file (es. Pollresults_resultatsbureau12002.csv), v'è una riga di dati in questo modo:

12002,Central Nova","Nova-Centre"," 6-1","Pictou, Subd. A",N,N,"",0,168,"Parker","","David K.","NDP-New Democratic Party","NPD-Nouveau Parti democratique",N,N,28 

Perché ho bisogno di sopprimere le virgolette, la voce "Pictou, Subd. A" rende R vuole dividere questo in 2 variabili. I dati non possono essere letti poiché desidera aggiungere una colonna a metà della costruzione del dataframe.

Excel e OpenOffice possono entrambi aprire questi file senza problemi. In qualche modo, Excel e OpenOffice sanno che le virgolette contano solo se si trovano all'inizio di una voce variabile.

Sapete quale opzione devo abilitare su R per ottenere questi dati? Ho> 300 file che ho bisogno di caricare (ognuno con ~ 1000 righe ciascuno) quindi una correzione manuale non è un'opzione ...

Ho cercato dappertutto una soluzione ma non la trovo.

+0

Una sorta di soluzione regex per riparare le virgolette senza corrispondenza è probabilmente un'opzione. Probabilmente ci sono molti modi per farlo, ma una opzione R potrebbe essere quella di usare 'readLines', sostituire", [letters or spaces] "" con una versione fissa usando i riferimenti posteriori, respingere usando 'writeLines' ...? – joran

+0

un altro pensiero, se i 300 + file sono tutti dello stesso formato, sarebbe quello di ottenere loro concatenati in modo da poter operare su un file – kpierce8

+0

Si dice "per sopprimere le virgolette, la voce" Pictou, Sottodistretto A "rende R vuole dividi questo in 2 variabili ", si divide perché hai una virgola come separatore – agstudy

risposta

1

Sulla base dei miei commenti, ecco una soluzione che leggerebbe tutti i file CSV in un unico elenco.

# Deal with French properly 
options(encoding="latin1") 

# Set your working directory to where you have 
# unzipped all of your 308 CSV files 
setwd("path/to/unzipped/files") 

# Get the file names 
temp <- list.files() 

# Extract the 5-digit code which we can use as names 
Codes <- gsub("pollresults_resultatsbureau|.csv", "", temp) 

# Read all the files into a single list named "pollResults" 
pollResults <- lapply(seq_along(temp), function(x) { 
    T0 <- readLines(temp[x]) 
    T0[-1] <- gsub('^(.{6})(.*)$', '\\1\\"\\2', T0[-1]) 
    final <- read.csv(text = T0, header = TRUE) 
    final 
}) 
names(pollResults) <- Codes 

Si può facilmente lavorare con questo elenco in diversi modi. Se si desidera vedere il 90 ° data.frame è possibile accedervi utilizzando pollResults[[90]] o utilizzando pollResults[["24058"]] (in altre parole, per numero di indice o per numero di distretto).

Avere i dati in questo formato significa che puoi anche fare molte altre cose utili. Ad esempio, se si desidera correggere tutti i 308 CSV in una volta, è possibile utilizzare il seguente codice, che creerà nuovi CSV con il nome file preceduto da "Corretto_".

invisible(lapply(seq_along(pollResults), function(x) { 
    NewFilename <- paste("Corrected", temp[x], sep = "_") 
    write.csv(pollResults[[x]], file = NewFilename, 
      quote = TRUE, row.names = FALSE) 
})) 

Spero che questo aiuti!

1

Questa risposta è principalmente a @AnandaMahto (vedere i commenti alla domanda originale).

primo luogo, aiuta ad impostare alcune opzioni a livello globale a causa degli accenti francesi nei dati:

options(encoding="latin1") 

Avanti, leggere i dati testualmente utilizzando readLines():

temp <- readLines("pollresults_resultatsbureau13001.csv")

A seguito di questa , basta sostituire la prima virgola in ogni riga di dati con una virgola + quotazione. Funziona perché il primo campo è sempre lungo 5 caratteri. Si noti che lascia intatto l'intestazione.

temp[-1] <- gsub('^(.{6})(.*)$', '\\1\\"\\2', temp[-1])

Penultimately, scrivere il file originale.

fileConn<-file("pollresults_resultatsbureau13001.csv") writeLines(temp,fileConn) close(fileConn)

Infine, è sufficiente leggere i dati di nuovo in R:

data<-read.csv(file="pollresults_resultatsbureau13001.csv",header = TRUE,sep=",")

C'è probabilmente un modo più parsimoniosa per fare questo (e uno che può essere iterata più facilmente) ma questo processo aveva senso per me.

+0

Ottimo! +1 per aver preso gli sforzi per farlo funzionare. Sono contento che i commenti abbiano aiutato. Ho aggiunto una soluzione più snella [qui] (http://stackoverflow.com/a/15093849/1270695), ma non sono sicuro di quanto tu sia a tuo agio nel trattare con 'list's. Personalmente preferirei avere una sola lista nel mio spazio di lavoro per centinaia di oggetti. Dato che questi 'data.frame's sono tutti dello stesso formato, puoi anche usare' do.call (rbind, pollResults) '(dalla mia risposta) per ottenere un gigante' data.frame' che include tutti i distretti in un posto. Provalo e fai rapporto e buona fortuna con la tua analisi! – A5C1D2H2I1M1N2O1R2T1

Problemi correlati