2011-01-26 12 views
41

Ho questo file (http://b7hq6v.alterupload.com/en/) che voglio leggere in R con read.csv. Ma non sono in grado di rilevare la codifica corretta. Sembra essere una specie di UTF-8. Sto usando R 2.12.1 su un computer WindowsXP. Qualsiasi aiuto?Come rilevare la codifica corretta per read.csv?

+0

Il collegamento è guasto. – Augustin

risposta

41

Prima di tutto based on more general question on StackOverflow non è possibile rilevare la codifica di file nella certezza al 100%.

ho lottare molte volte e venire a una soluzione non automatico:

Usa iconvlist per ottenere tutte le possibili codifiche:

codepages <- setNames(iconvlist(), iconvlist()) 

quindi leggere i dati utilizzando ciascuno di essi

x <- lapply(codepages, function(enc) try(read.table("encoding.asc", 
        fileEncoding=enc, 
        nrows=3, header=TRUE, sep="\t"))) # you get lots of errors/warning here 

Importante qui è conoscere la struttura del file (separatore, intestazioni). Impostare la codifica usando l'argomento fileEncoding. Leggi solo poche righe.
Ora si potrebbe occhiata sui risultati:

unique(do.call(rbind, sapply(x, dim))) 
#  [,1] [,2] 
# 437  14 2 
# CP1200  3 29 
# CP12000 0 1 

Sembra come corretta è che con 3 righe e 29 colonne, così lascia vederli:

maybe_ok <- sapply(x, function(x) isTRUE(all.equal(dim(x), c(3,29)))) 
codepages[maybe_ok] 
# CP1200 UCS-2LE  UTF-16 UTF-16LE  UTF16 UTF16LE 
# "CP1200" "UCS-2LE" "UTF-16" "UTF-16LE" "UTF16" "UTF16LE" 

Si potrebbe guardare su dati troppo

x[maybe_ok] 

Per il tuo file tutte queste codifiche restituiscono dati identici (in parte perché c'è una certa ridondanza come vedi).

Se non si conosce specifica del file è necessario utilizzare readLines con alcune modifiche del flusso di lavoro (ad esempio non è possibile utilizzare fileEncoding, devono utilizzare length invece di dim, fare di più la magia di trovare quelle corrette).

+2

Ho fatto una cosa simile alla chiusura per iconvlist(), ma con un ciclo. La cosa fondamentale era l'uso di "fileEncoding". Ho usato erroneamente "codifica". Grazie per l'aiuto. – Alex

+5

Ho abbozzato un approccio simile su https://gist.github.com/837414 - Penso che sia più efficiente caricare i dati una volta, quindi provare diverse codifiche usando 'iconv'. – hadley

+1

@Marek Bel trucco. Almeno so che il mio problema 'read.csv' non ha a che fare con' fileEncoding'. – Tunn

0

Questo file ha la codifica UTF-16LE con BOM (byte order mark). Probabilmente dovresti usare encoding = "UTF-16LE"

+0

L'ho provato ma tutto quello che ottengo è questo: ÿþ – Alex

+3

Per completezza di questa risposta: nel parametro corretto 'read.table' è' fileEncoding'. – Marek

5

In primo luogo, devi capire qual è la codifica del file, cosa non può essere fatto in R (almeno come so). Ad esempio puoi utilizzare strumenti esterni, ad es. da Perl, python o es. l'utilità file sotto Linux/UNIX.

Come @ssmit suggerito, si dispone di una codifica UTF-16 (Unicode) qui, quindi caricare il file con questa codifica e utilizzare readLines per vedere quello che hai nei primi (ad esempio) 10 righe:

> f <- file('encoding.asc', open="r", encoding="UTF-16LE") # UTF-16LE, which is "called" Unicode in Windows 
> readLines(f,10) 
[1] "\tFe 2\tZn\tO\tC\tSi\tMn\tP\tS\tAl\tN\tCr\tNi\tMo\tCu\tV\tNb 2\tTi\tB\tZr\tCa\tH\tCo\tMg\tPb 2\tW\tCl\tNa 3\tAr"                               
[2] ""                                                           
[3] "0\t0,003128\t3,82E-05\t0,0004196\t0\t0,001869\t0,005836\t0,004463\t0,002861\t0,02148\t0\t0,004768\t0,0003052\t0\t0,0037\t0,0391\t0,06409\t0,1157\t0,004654\t0\t0\t0\t0,00824\t7,63E-05\t0,003891\t0,004501\t0\t0,001335\t0,01175"   
[4] "0,0005\t0,003265\t3,05E-05\t0,0003662\t0\t0,001709\t0,005798\t0,004395\t0,002808\t0,02155\t0\t0,004578\t0,0002441\t0\t0,003601\t0,03897\t0,06406\t0,1158\t0,0047\t0\t0\t0\t0,008026\t6,10E-05\t0,003876\t0,004425\t0\t0,001343\t0,01157" 
[5] "0,001\t0,003332\t2,54E-05\t0,0003052\t0\t0,001704\t0,005671\t0,0044\t0,002823\t0,02164\t0\t0,004603\t0,0003306\t0\t0,003611\t0,03886\t0,06406\t0,1159\t0,004705\t0\t0\t0\t0,008036\t5,09E-05\t0,003815\t0,004501\t0\t0,001246\t0,01155" 
[6] "0,0015\t0,003313\t2,18E-05\t0,0002616\t0\t0,001678\t0,005689\t0,004447\t0,002921\t0,02171\t0\t0,004621\t0,0003488\t0\t0,003597\t0,03889\t0,06404\t0,1158\t0,004752\t0\t0\t0\t0,008022\t4,36E-05\t0,003815\t0,004578\t0\t0,001264\t0,01144" 
[7] "0,002\t0,003313\t2,18E-05\t0,0002834\t0\t0,001591\t0,005646\t0,00436\t0,003008\t0,0218\t0\t0,004643\t0,0003488\t0\t0,003619\t0,03895\t0,06383\t0,1159\t0,004752\t0\t0\t0\t0,008\t4,36E-05\t0,003771\t0,004643\t0\t0,001351\t0,01142"  
[8] "0,0025\t0,003488\t2,18E-05\t0,000218\t0\t0,001657\t0,00558\t0,004338\t0,002986\t0,02175\t0\t0,004469\t0,0002616\t0\t0,00351\t0,03889\t0,06374\t0,1159\t0,004621\t0\t0\t0\t0,008131\t4,36E-05\t0,003771\t0,004708\t0\t0,001243\t0,01125" 
[9] "0,003\t0,003619\t0\t0,0001526\t0\t0,001591\t0,005668\t0,004207\t0,00303\t0,02169\t0\t0,00449\t0,0002834\t0\t0,00351\t0,03874\t0,06383\t0,116\t0,004665\t0\t0\t0\t0,007956\t0\t0,003749\t0,004796\t0\t0,001286\t0,01125"     
[10] "0,0035\t0,003422\t0\t4,36E-05\t0\t0,001482\t0,005711\t0,004185\t0,003292\t0,02156\t0\t0,004665\t0,0003488\t0\t0,003553\t0,03852\t0,06391\t0,1158\t0,004708\t0\t0\t0\t0,007717\t0\t0,003597\t0,004905\t0\t0,00133\t0,01136"     

Da questo, si può vedere che abbiamo un'intestazione e una riga vuota nella seconda riga (che verrà saltata per impostazione predefinita utilizzando la funzione read.table), il separatore è \t e il carattere decimale è ,.

> f <- file('encoding.asc', open="r", encoding="UTF-16LE") 
> df <- read.table(f, sep='\t', dec=',', header=TRUE) 

E vedere quello che abbiamo:

> head(df) 
     X  Fe.2  Zn   O C  Si  Mn  P  S 
1 0.0000 0.003128 3.82e-05 0.0004196 0 0.001869 0.005836 0.004463 0.002861 
2 0.0005 0.003265 3.05e-05 0.0003662 0 0.001709 0.005798 0.004395 0.002808 
3 0.0010 0.003332 2.54e-05 0.0003052 0 0.001704 0.005671 0.004400 0.002823 
4 0.0015 0.003313 2.18e-05 0.0002616 0 0.001678 0.005689 0.004447 0.002921 
5 0.0020 0.003313 2.18e-05 0.0002834 0 0.001591 0.005646 0.004360 0.003008 
6 0.0025 0.003488 2.18e-05 0.0002180 0 0.001657 0.005580 0.004338 0.002986 
     Al N  Cr  Ni Mo  Cu  V Nb.2  Ti  B Zr 
1 0.02148 0 0.004768 0.0003052 0 0.003700 0.03910 0.06409 0.1157 0.004654 0 
2 0.02155 0 0.004578 0.0002441 0 0.003601 0.03897 0.06406 0.1158 0.004700 0 
3 0.02164 0 0.004603 0.0003306 0 0.003611 0.03886 0.06406 0.1159 0.004705 0 
4 0.02171 0 0.004621 0.0003488 0 0.003597 0.03889 0.06404 0.1158 0.004752 0 
5 0.02180 0 0.004643 0.0003488 0 0.003619 0.03895 0.06383 0.1159 0.004752 0 
6 0.02175 0 0.004469 0.0002616 0 0.003510 0.03889 0.06374 0.1159 0.004621 0 
    Ca H  Co  Mg  Pb.2  W Cl  Na.3  Ar 
1 0 0 0.008240 7.63e-05 0.003891 0.004501 0 0.001335 0.01175 
2 0 0 0.008026 6.10e-05 0.003876 0.004425 0 0.001343 0.01157 
3 0 0 0.008036 5.09e-05 0.003815 0.004501 0 0.001246 0.01155 
4 0 0 0.008022 4.36e-05 0.003815 0.004578 0 0.001264 0.01144 
5 0 0 0.008000 4.36e-05 0.003771 0.004643 0 0.001351 0.01142 
6 0 0 0.008131 4.36e-05 0.003771 0.004708 0 0.001243 0.01125 
+1

Grazie, funziona. Ma perché devo saltare le prime 2 linee? E perché questo wirk non è in read.csv direttamente? – Alex

+2

@ user590885: hai ragione, 'skip = 2' può essere omesso (ho modificato la mia risposta in base a quello), la seconda riga vuota verrà saltata. Puoi anche usare la funzione 'read.csv' per leggere questo file (con gli stessi parametri forniti), ma poiché il tuo file non è delimitato da virgole, ma i tabulatori invece, non penso che sarebbe carino. Cerca '? Read.table' per i dettagli sulle somiglianze delle funzioni (le differenze possono essere trovate nei valori predefiniti). – daroczig

Problemi correlati