Как обнаружить правильное кодирование для read.csv?

StackOverflow https://stackoverflow.com/questions/4806823

  •  24-10-2019
  •  | 
  •  

Вопрос

У меня есть этот файл (http://b7hq6v.alterupload.com/en/), который я хочу прочитать в R с read.csv. Анкет Но я не могу обнаружить правильное кодирование. Кажется, это своего рода UTF-8. Я использую R 2.12.1 на машине WindowsXP. Любая помощь?

Это было полезно?

Решение

Прежде всего на основе более общего вопроса на Stackoverflow Невозможно обнаружить кодирование файла в 100% уверенности.

Я борюсь так много раз и прихожу к неавтоматическому решению:

Использовать iconvlist Чтобы получить все возможные кодировки:

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

Затем прочитайте данные, используя каждый из них

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

Важно знать структуру файла (разделитель, заголовки). Установить кодирование с помощью fileEncoding аргумент Прочитайте только несколько рядов.
Теперь вы можете поискать результаты:

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

Похоже, что правильно, с 3 рядами и 29 столбцами, так что давайте посмотрим на них:

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" 

Вы тоже можете посмотреть на данные

x[maybe_ok]

Для вашего файла все эти кодировки возвращают идентичные данные (частично потому, что, как вы видите, есть некоторая избыточность).

Если вы не знаете конкретного вашего файла, вам нужно использовать readLines С некоторыми изменениями в рабочем процессе (например, вы не можете использовать fileEncoding, должен использовать length вместо dim, сделайте больше магии, чтобы найти правильные).

Другие советы

Посылка readr, https://cran.r-project.org/web/packages/readr/readr.pdf, Включает функцию, называемую guess_encoding Это вычисляет вероятность того, что файл кодируется в нескольких кодировках:

guess_encoding("your_file", n_max = 1000)

Во -первых, вы должны выяснить, что такое кодирование файла, что нельзя сделать в R (по крайней мере, как я знаю). Вы можете использовать внешние инструменты для этого, например, из Perl, Python или EG. а file Утилита под Linux/Unix.

Как предложил @SSMIT, здесь есть кодирование UTF-16LE (Unicode), поэтому загрузите файл с помощью этого кодирования и используйте readLines Чтобы увидеть, что у вас есть в первых (например,) 10 строках:

> 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"                   

Из этого видно, что у нас есть заголовок и пустая линия во втором ряду (которая будет пропущена по умолчанию, используя read.table функция), сепаратор \t и десятичный персонаж ,.

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

И посмотреть, что у нас есть:

> 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

В дополнение к использованию readr-Паки, вы также можете использовать использование stringi :: stri_enc_detect2. Анкет Эта функция особенно эффективна, если локаль известен, и если вы имеете дело с какой -либо формой UTF или ASCII: «.. Оказывается, это (эмпирически) stri_enc_detect2 работает лучше, чем на основе интенсивной терапии [stringi :: stri_enc_detect используется угадание] Если предоставлен текст. "

Подробная информация о stringi :: stri_enc_detect.

Подробная информация о stringi :: stri_enc_detect2.

Изменение-запрос для ugply_encoding

Этот файл имеет кодирование UTF-16LE с BOM (байт-отметка). Вы, вероятно, должны использовать encoding = "UTF-16LE"

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top