Текстовое кодирование UTF-8/Unicode с помощью RPostgreSQL
Я запускаю R на машине Windows, которая напрямую связана с базой данных PostgreSQL. Я не использую RODBC. Моя база данных закодирована в UTF-8, что подтверждается следующей командой R:
dbGetQuery(con, "SHOW CLIENT_ENCODING")
# client_encoding
# 1 UTF8
Однако, когда какой-либо текст читается в R, он отображается как странный текст в R.
Например, следующий текст показан в моей базе данных PostgreSQL:
"Stéphane"
После экспорта в R он отображается как:
"СТО © phane"
(é закодирован как Ã ©)
При импорте в R я использую команду dbConnect
для установления соединения и команды dbGetQuery
для запроса данных с использованием SQL. Я не указываю никакой текстовой кодировки нигде при подключении к базе данных или при выполнении запроса.
Я искал в Интернете и не могу найти прямое решение моей проблемы. Я нашел эту ссылку, но их проблема связана с RODBC, которую я не использую.
Эта ссылка помогает идентифицировать символы, но я не просто хочу найти и заменить в R... слишком много данных.
Я попытался выполнить следующие команды ниже, и я пришел к предупреждению.
Sys.setlocale("LC_ALL", "en_US.UTF-8")
# [1] ""
# Warning message:
# In Sys.setlocale("LC_ALL", "en_US.UTF-8") :
# OS reports request to set locale to "en_US.UTF-8" cannot be honored
Sys.setenv(LANG="en_US.UTF-8")
Sys.setenv(LC_CTYPE="UTF-8")
Предупреждение появляется в команде Sys.setlocale("LC_ALL", "en_US.UTF-8")
. Моя интуиция заключается в том, что это особая проблема Windows и не происходит с Mac/Linux/Unix.
Ответы
Ответ 1
После экспорта в R он отображается как: "Sté phane" (é закодирован как Ã ©)
В вашей среде R используется 1-байтовая незастроенная кодировка, такая как latin-1 или windows-1252. Свидетель этого теста на Python, демонстрируя, что utf-8 байт для é
, декодированные так, как если бы они были латинскими-1, вызывают текст, который вы видите:
>>> print u"é".encode("utf-8").decode("latin-1")
é
Либо SET client_encoding = 'windows-1252'
, либо исправить кодировку, используемую вашей средой R. Если он запущен в консоли cmd.exe
, вам нужно будет запутаться с консольной командой chcp
; в противном случае это зависит от вашего времени выполнения R.
Ответ 2
Как сказал Крейг Рингер, установка client_encoding
в windows-1252, вероятно, не лучшая вещь. Действительно, если данные, которые вы получаете, содержат один экзотический символ, у вас проблемы:
Ошибка в postgresqlExecStatement (conn, Statement,...): драйвер RS-DBI: (не удалось получить результат: ОШИБКА: символ 0xcca7 кодировки "UTF8" не имеет эквивалента в "WIN1252")
С другой стороны, заставить вашу среду R использовать Unicode может быть невозможно (у меня та же проблема, что и у вас с Sys.setlocale
... То же самое и в этом вопросе).
Обходной путь - вручную объявить кодировку UTF-8 для всех ваших данных, используя такую функцию:
set_utf8 <- function(x) {
# Declare UTF-8 encoding on all character columns:
chr <- sapply(x, is.character)
x[, chr] <- lapply(x[, chr, drop = FALSE], 'Encoding<-', "UTF-8")
# Same on column names:
Encoding(names(x)) <- "UTF-8"
x
}
И вы должны использовать эту функцию во всех ваших запросах:
set_utf8(dbGetQuery(con, "SELECT myvar FROM mytable"))
РЕДАКТИРОВАТЬ: Другая возможность заключается в использовании RPostgres вместо RPostgreSQL. Я протестировал его (с тем же конфигом, что и в вашем вопросе), и, насколько я вижу, все объявленные кодировки автоматически устанавливаются в UTF-8.
Ответ 3
Это устранит любые проблемы Unicode/UTF-8 в Windows. Он должен быть выполнен перед запросом базы данных.
postgresqlpqExec(con, "SET client_encoding = 'windows-1252'")
Нарисовано от неверующего автоответчика, видимого в истории пересмотра вопроса
Ответ 4
Сделай это:
con <- dbConnect("...", encoding = "latin1")