RODBC: caracteres y números convertidos agresivamente (con / sin as.is)
Relacionado conhttps://stackoverflow.com/a/33284035/3358272, Encuentro un comportamiento inconsistente al extraer datos de 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
En ese ejemplo vemos el comportamiento no deseado: los caracteres demychar
se están convirtiendo internamente en enteros. Según la respuesta SO mencionada anteriormente, elas.is
la opción derrota esto, pero tiene el desafortunado efecto secundario de forzar también los flotadores representados con decimales a cadenas:
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"
Si al menos uno demychar
en realidad no es entero, las cosas están bien:
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
Desafortunadamente, el modelo de datos no admite agregar arbitrariamente algo para alentar este comportamiento (o simplemente no he pensado en una forma lo suficientemente buena de hacerlo). El modelo de datos es tal que los valores demychar
incluir01
y1
que son distintos en cuanto al carácter. La única solución que he encontrado es usaras.is = TRUE
, lo que requerirá queas.numeric
todas las columnas relacionadas, algo que es tedioso y (teóricamente) un trabajo innecesario.
Dado que los documentos sugieren la necesidad de establecerDBMSencoding
, Verifiqué la codificación actual (ayudado porhttps://stackoverflow.com/a/5182469/3358272):
sqlQuery(.conn, "SELECT SERVERPROPERTY('Collation')")
# 1 SQL_Latin1_General_CP1_CI_AS
He intentado usar (para patadas):DBMSencoding="latin1"
, DBMSencoding="UTF-8"
, y explícitamente aunque el valor predeterminadoDBMSencoding=""
sin cambio de comportamiento.
¿Cómo puedo fomentar el comportamiento de no forzar demasiado los tipos de datos?
Actualmente usando R-3.2.5 y RODBC-1.3.13 en ubuntu.