R проблемы с кодировкой после чтения из MS SQL через ODBC - PullRequest
0 голосов
/ 22 апреля 2020

У нас есть база данных и R-скрипты, работающие на разных виртуальных машинах. Сначала мы подключаемся к db

con <- dbConnect(
  odbc(),
  Driver = "SQL Server",
  Server = "server", Database = "db", UID = "uid", PWD = "pwd",
  encoding = "UTF-8"
)

и собираем данные

data <- dbGetQuery(con, "SELECT * FROM TableName")

Проблема заключается в следующем: когда на разных машинах выполняется один и тот же скрипт, для некоторых из них мы сталкиваемся с проблемами кодирования символьных переменных .

Например, это то, что мы имеем на машине A

> data$char_var[1]
[1] "фамилия"
> Encoding(data$char_var[1])
[1] "UTF-8"
> Sys.getlocale()
[1] "LC_COLLATE=Russian_Russia.1251;LC_CTYPE=Russian_Russia.1251;LC_MONETARY=Russian_Russia.1251;LC_NUMERIC=C;LC_TIME=Russian_Russia.1251"
> Encoding(data$char_var[1]) <- "1251"
> data$char_var[1]
[1] "гревцев"

, и это то, что мы имеем на машине B

> data$char_var[1]
[1] "<e3><f0><e5><e2><f6><e5><e2>"
> Encoding(data$char_var[1])
[1] "UTF-8"
> Sys.getlocale()
[1] "LC_COLLATE=Russian_Russia.1251;LC_CTYPE=Russian_Russia.1251;LC_MONETARY=Russian_Russia.1251;LC_NUMERIC=C;LC_TIME=Russian_Russia.1251"
> Encoding(data$char_var[1]) <- "1251"
> data$char_var[1]
[1] "фамилия"

Первый скрипт возвращает gibberi sh, но правильно печатает начальное значение. Тот же код, работающий на машине B, сначала печатает utf-8, а затем возвращает закодированные значения. В чем может быть причина такой разницы?

В результате мы хотим, чтобы скрипт, который имел бы такое же выходное значение "фамилия", отображал его на панели инструментов.

1 Ответ

1 голос
/ 22 апреля 2020

В соответствии с результатом вашего звонка на Encoding(data$char_var[1]), обе машины объявляют возвращаемые результаты для кодирования с использованием UTF-8.

На первой машине это выглядит так, потому что вы видите правильный вывод. Затем вы запутываетесь, неправильно объявляя кодировку "1251", и видите gibberi sh.

На второй машине результат приходит к вам, объявлен как UTF-8, но это не так (вот почему это выглядит как гиббери sh для начала). Когда вы изменяете объявленную кодировку на "1251", она выглядит нормально, так что, должно быть, это было всегда.

Итак, у вас есть два варианта:

  • Make убедитесь, что обе машины согласуются с тем, что они возвращают из dbGetQuery. Вы можете обрабатывать любую кодировку, но вам нужно знать, что это такое, и убедиться, что она объявлена ​​правильно.

  • В качестве альтернативы попытайтесь определить, что возвращается, и объявить это соответствующим образом. Один из способов сделать это - поместить известную строку в базу данных и сравнить результат с этим. Если вы знаете, что должны получить "фамилия", а вы получили что-то еще, переключите объявленную кодировку. Вы также можете попробовать функцию readr::guess_encoding().

Еще одна проблема заключается в том, что некоторая последующая функция может обрабатывать только одну или другую кодировку UTF-8 и 1251. (Windows R действительно плохо работает с не родными кодировками, а UTF-8 никогда не является родным для Windows.) В этом случае вы можете захотеть преобразовать в общую кодировку. Для этого вы используете функцию iconv(), например,

iconv(char_var, from = "cp1251", to = "UTF-8")

попытается конвертировать в UTF-8.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...