RODBC: символы и числа, преобразованные агрессивно (с / без as.is)
Относится кhttps://stackoverflow.com/a/33284035/3358272Я обнаружил противоречивое поведение при извлечении данных из SQL Server (2014).
library(RODBC)
sqlQuery(.conn, "CREATE TABLE r2test ( [mychar] [NVARCHAR](16), [mynum] [FLOAT])")
# character(0)
sqlQuery(.conn, "INSERT INTO r2test (mychar,mynum) VALUES ('1',3.141593),('2',6.283185)")
character(0)
str(sqlQuery(.conn, "SELECT * FROM r2test", stringsAsFactors = FALSE))
# 'data.frame': 2 obs. of 2 variables:
# $ mychar: int 1 2
# $ mynum : num 3.14 6.28
В этом примере мы видим нежелательное поведение: символыmychar
внутренне преобразуются в целые числа. Согласно ранее упомянутому SO-ответу,as.is
option побеждает это, но имеет неприятный побочный эффект, заключающийся в принудительном преобразовании десятичных представлений в строки:
str(sqlQuery(.conn, "SELECT * FROM r2test", stringsAsFactors = FALSE, as.is = TRUE))
# 'data.frame': 2 obs. of 2 variables:
# $ mychar: chr "1" "2"
# $ mynum : chr "3.1415929999999999" "6.2831849999999996"
Если хотя бы один изmychar
на самом деле не целочисленный, все хорошо:
sqlQuery(.conn, "INSERT INTO r2test (mychar,mynum) VALUES ('a',9.424778)")
# character(0)
str(sqlQuery(.conn, "SELECT * FROM r2test", stringsAsFactors = FALSE))
# 'data.frame': 3 obs. of 2 variables:
# $ mychar: chr "1" "2" "a"
# $ mynum : num 3.14 6.28 9.42
К сожалению, модель данных не поддерживает произвольное добавление чего-либо для поощрения такого поведения (или я просто не придумал достаточно хорошего способа сделать это). Модель данных такова, что значенияmychar
включают01
а также1
которые характерно различны. Единственный обходной путь, который я нашел, это использоватьas.is = TRUE
, что потребует от меняas.numeric
все связанные столбцы, что является утомительной и (теоретически) ненужной работой.
Поскольку документы предполагают необходимость установитьDBMSencoding
Я проверил текущую кодировку (помоглоhttps://stackoverflow.com/a/5182469/3358272):
sqlQuery(.conn, "SELECT SERVERPROPERTY('Collation')")
# 1 SQL_Latin1_General_CP1_CI_AS
Я пытался использовать (для ударов ногами):DBMSencoding="latin1"
, DBMSencoding="UTF-8"
и явно, хотя по умолчаниюDBMSencoding=""
без изменений в поведении.
Как я могу поощрять поведение, не приводящее к чрезмерному принуждению типов данных?
В настоящее время использую R-3.2.5 и RODBC-1.3.13 на Ubuntu.