R Corpus испортил мой текст в кодировке UTF-8

Я просто пытаюсь создать корпус из русского текста в кодировке UTF-8. Проблема в том, что метод Corpus из пакета tm неправильно кодирует строки.

Вот воспроизводимый пример моей проблемы:

Загрузить на русском языке:

> data <- c("Renault Logan, 2005","Складское помещение, 345 м²",
          "Су-шеф","3-к квартира, 64 м², 3/5 эт.","Samsung galaxy S4 mini GT-I9190 (чёрный)")

Создайте векторный источник:

> vs <- VectorSource(data)
> vs # outputs correctly

Затем создайте корпус:

> corp <- Corpus(vs)
> inspect(corp) # output is not encoded properly

Результат, который я получаю:

> inspect(corp)
<<VCorpus (documents: 5, metadata (corpus/indexed): 0/0)>>

[[1]]
<<PlainTextDocument (metadata: 7)>>
Renault Logan, 2005

[[2]]
<<PlainTextDocument (metadata: 7)>>
Ñêëàäñêîå ïîìåùåíèå, 345 ì<U+00B2>

[[3]]
<<PlainTextDocument (metadata: 7)>>
Ñó-øåô

[[4]]
<<PlainTextDocument (metadata: 7)>>
3-ê êâàðòèðà, 64 ì<U+00B2>, 3/5 ýò.

[[5]]
<<PlainTextDocument (metadata: 7)>>
Samsung galaxy S4 mini GT-I9190 (÷¸ðíûé)

Почему он выводит неправильно? Кажется, нет возможности установить кодировку для метода Корпуса. Есть ли способ установить его постфактум? Я пробовал это:

> title_corpus <- tm_map(title_corpus, enc2utf8)
Error in FUN(X[[1L]], ...) : argumemt is not a character vector

Но это ошибки, как показано.


person user1477388    schedule 23.07.2014    source источник
comment
Я не могу повторить. Когда я запускаю inspect, он выглядит так же, как и в data. Какую версию tm и R вы используете (sessionInfo() должен сказать вам обе).   -  person MrFlick    schedule 24.07.2014
comment
@MrFlick Я использую R version 3.1.0 (2014-04-10) Platform: x86_64-w64-mingw32/x64 (64-bit) и tm_0.6. Я на Windows.   -  person user1477388    schedule 24.07.2014
comment
OK. У меня компьютер с 3.0.2, поэтому я не могу получить последнюю версию tm. Но у Корпуса нет параметра кодирования, а у VectorSource должен быть. Что происходит с VectorSource(data, encoding="UTF-8"). Что-то другое?   -  person MrFlick    schedule 24.07.2014
comment
Там написано Error in VectorSource(raw_test$title, encoding = "UTF-8") : unused argument (encoding = "UTF-8")   -  person user1477388    schedule 24.07.2014
comment
Фу. Похоже, что по какой-то причине он был удален из последней версии tm. Последний выстрел, VectorSource(enc2utf8(data)). Может быть, я могу попробовать на своем другом компьютере, если это не сработает.   -  person MrFlick    schedule 24.07.2014
comment
Вроде не влияет.   -  person user1477388    schedule 24.07.2014


Ответы (3)


Ну, кажется, есть хорошие новости и плохие новости.

Хорошей новостью является то, что с данными все в порядке, даже если они неправильно отображаются с помощью inspect(). Попробуйте посмотреть на

content(corp[[2]])
# [1] "Складское помещение, 345 м²"

Причина, по которой это выглядит забавно в inspect(), заключается в том, что авторы изменили способ работы функции print.PlainTextDocument. Раньше он cat выводил значение на экран. Однако теперь они передают данные через writeLines(). Эта функция использует языковой стандарт системы для форматирования символов/байтов в документе. (Это можно посмотреть с помощью Sys.getlocale()). Оказывается, Linux и OS X имеют правильную кодировку «UTF-8», но Windows использует кодовые страницы для конкретного языка. Поэтому, если символов нет на кодовой странице, они экранируются или преобразуются в забавные символы. Это означает, что это должно нормально работать на Mac, но не на ПК.

Попробуйте сделать еще один шаг и создать DocumentTermMatrix.

dtm <- DocumentTermMatrix(corp)
Terms(dtm)

Надеюсь, вы увидите (как и я) правильно отображаемые слова.

Если хотите, эту статью о записи файлов UTF-8 в Windows содержит дополнительную информацию об этой конкретной проблеме ОС. Я не вижу простого способа заставить writeLines выводить UTF-8 в stdout() в Windows. Я не уверен, почему сопровождающие пакета изменили метод печати, но можно попросить или отправить запрос функции, чтобы изменить его обратно.

person MrFlick    schedule 23.07.2014
comment
Возможно, сопровождающий должен быть уведомлен. +1 - person Tyler Rinker; 24.07.2014
comment
Вы правы, если я создам DTM, все будет в порядке. Спасибо за ваше руководство. - person user1477388; 24.07.2014
comment
У меня похожая проблема, я использую docs<- VCorpus(DirSource(directory = inputdir, encoding ="UTF-8")), и мои файлы txt сохраняются в кодировке UTF-8, но я все равно получаю ‹U+FB01›scal вместо fiscal и выгода‹U+FB01›t вместо пользы, когда я экспортирую наиболее часто встречающиеся слова и в распределении тем по словам. Есть ли что-то, что я делаю неправильно? Буду очень признателен за любой совет - person Michael; 27.04.2020
comment
@Майкл, я не уверен, что там происходит. Возможно, упаковка снова изменилась. Было бы лучше, если бы вы создали свой собственный вопрос с минимальным воспроизводимым примером чтобы помочь вам. - person MrFlick; 27.04.2020
comment
@MrFlick Спасибо за предложение. Я пошел дальше и создал новую тему. Вот ссылка, если вы можете помочь. Спасибо! stackoverflow.com/questions/61463661/ - person Michael; 27.04.2020

Я удивлен, что ответ еще не опубликован. Не заморачивайтесь с локалью. Я использую пакет tm версии 0.6.0, и он работает абсолютно нормально, если вы добавите следующую маленькую магию:

Encoding(data)  <- "UTF-8"

Ну вот воспроизводимый код:

data <- c("Renault Logan, 2005","Складское помещение, 345 м²","Су-шеф","3-к квартира, 64 м², 3/5 эт.","Samsung galaxy S4 mini GT-I9190 (чёрный)")

Encoding(data)
# [1] "unknown" "unknown" "unknown" "unknown" "unknown"

Encoding(data)  <- "UTF-8"
# [1] "unknown" "UTF-8"   "UTF-8"   "UTF-8"   "UTF-8"

Просто поместите его в текстовый файл, сохраненный в кодировке UTF-8, а затем создайте его обычным образом в R. Но не используйте source.with.encoding(..., encoding = "UTF-8"); это выдаст ошибку.

Я забыл, где я научился этому трюку, но я наткнулся на него где-то на прошлой неделе, во время серфинга в Интернете, пытаясь научиться обрабатывать текст UTF8 в R. В Python все было намного чище (просто конвертируйте все в Unicode!) . Подход R для меня гораздо менее прост, и не помогло то, что документация скудная и запутанная.

person Chiraz BenAbdelkader    schedule 05.02.2015
comment
Encoding() не работает с классом Corpus; он работает только с векторами символов. Вы уверены, что ваше решение работает для Корпуса, как того требует ОП? - person Tripartio; 30.04.2016
comment
Его можно использовать непосредственно перед преобразованием текста в корпус, и он отлично работает. - person Kenji Kina; 25.06.2016
comment
@KenjiKina Не могли бы вы предоставить пример кода для этого? - person Michael; 27.04.2020

У меня возникла проблема с немецкой кодировкой UTF-8 при импорте текстов. Мне помог следующий лайнер:

Sys.setlocale("LC_ALL", "de_DE.UTF-8")

Попробовать запустить то же самое с русским языком?

Sys.setlocale("LC_ALL", "ru_RU.UTF-8")

Конечно, это происходит после библиотеки (тм) и перед созданием корпуса.

person EugenieSH    schedule 01.04.2017