tipo de datos long / bigint / decimal equivalente en R

¿Qué opciones de tipo de datos tenemos para manejar números grandes en R? De forma predeterminada, el tamaño de un entero parece ser de 32 bits, por lo que los números grandes del servidor SQL y cualquier número grande pasado de Python a través de rpy2 se destruyen.

> 123456789123 [1] 123456789123 > 1234567891234 [1] 1.234568e+12 

Al leer un valor grande de 123456789123456789 usando RODBC, regresa como 123456789123456784 (ver el último dígito), y el mismo número cuando se deserializa a través de RJSONIO, regresa como -1395630315L (lo cual parece un error / limitación adicional de RJSONIO).

 > fromJSON('[1234567891]') [1] 1234567891 > fromJSON('[12345678912]') [1] -539222976 

En realidad, necesito poder manejar grandes cantidades provenientes de JSON, así que con la limitación de RJSONIO, es posible que no tenga una solución alternativa, salvo para encontrar una mejor biblioteca JSON (que parece no ser una opción en este momento). Me gustaría saber qué opinan los expertos sobre esto y en general.

Ver help(integer) :

  Note that on almost all implementations of R the range of representable integers is restricted to about +/-2*10^9: 'double's can hold much larger integers exactly. 

así que recomendaría usar un número numeric (es decir, “doble”), un número de precisión doble.

Entendí tu pregunta un poco diferente contra los dos que publicaron antes que yo.

Si el valor predeterminado más grande de R no es lo suficientemente grande para usted, tiene algunas opciones (descargo de responsabilidad: he utilizado cada una de las bibliotecas que menciono a continuación, pero no a través de las vinculaciones R, a través de otras vinculaciones de idiomas o la biblioteca nativa)

El paquete de Brobdingnag : usa registros naturales para almacenar los valores; (como Rmpfr, implementado usando la nueva estructura de clases de R). Siempre me impresiona cualquier persona cuyo trabajo requiera números de esta escala.

 library(Brobdingnag) googol < - as.brob(1e100) 

El paquete gmp : enlaces R a la venerable GMP (biblioteca de precisión múltiple GNU). Esto debe remontarse a 20 años porque lo usé en la Universidad. El lema de esta biblioteca es "Aritmética sin límites", que es una afirmación creíble: enteros, racionales, flotantes, lo que sea, hasta los límites de la memoria RAM en su caja.

 library(gmp) x = as.bigq(8000, 21) 

El paquete Rmpfr : enlaces R que se conectan a ambos gmp (arriba) y MPFR, (MPFR es a su vez una implementación contemporánea de gmp. He usado los enlaces de Python ('bigfloat') y puedo recomendarlo altamente. Este podría ser tu mejor opción de los tres, dado su scope, dado que parece ser el más activamente mantenido, y finalmente se le dio la que parece ser la documentación más completa.

Nota: para utilizar cualquiera de los dos últimos, deberá instalar las bibliotecas nativas, GMP y MPFR .

Después de esta pregunta, los paquetes int64 de Romain Francois y bit64 de Jens Oehlschlägel ya están disponibles.

Dirk tiene razón. Debería usar el tipo numeric (que debe establecerse en el doble). La otra cosa a tener en cuenta es que es posible que no recuperes todos los dígitos. Mira la configuración de los dígitos:

 > options("digits") $digits [1] 7 

Puedes extender esto:

 options(digits=14) 

Alternativamente, puede reformatear el número:

 format(big.int, digits=14) 

Probé tu número y estoy obteniendo el mismo comportamiento (incluso usando el tipo de datos double ), por lo que puede ser un error:

 > as.double("123456789123456789") [1] 123456789123456784 > class(as.double("123456789123456789")) [1] "numeric" > is.double(as.double("123456789123456789")) [1] TRUE 

Resolví algunos problemas relacionados con los enteros en rpy2 (Python puede cambiar de int a long cuando sea necesario, pero R does no parece poder hacerlo. Los desbordamientos de enteros ahora deberían devolver NA_integer_.

L.

Estuve tratando de encontrar una solución para este problema en los últimos dos días y finalmente lo encontré hoy. Tenemos identificaciones largas de 19 dígitos en nuestra base de datos SQL y antes usé RODBC para obtener datos de gran tamaño del servidor. Probé int64 y bit64, también definí las opciones (dígitos = 19), pero RODBC siguió dando problemas. Reemplacé RODBC con RJDBC, y mientras recuperaba los datos de bigint del servidor SQL, manipulé la consulta SQL mediante el uso de datos bigint en cadena.

Así que aquí está el código de muestra:

 #Include stats package require(stats); library(RJDBC); #set the working directory setwd("W:/Users/dev/Apps/R/Data/201401_2"); #Getting JDBC Driver driver < - JDBC("com.microsoft.sqlserver.jdbc.SQLServerDriver", "W:/Users/dev/Apps/R/Data/sqljdbc/enu/sqljdbc4.jar"); #Connect with DB connection <- dbConnect(driver, "jdbc:sqlserver://DBServer;DatabaseName=DB;", "BS_User", "BS_Password"); #Query string sqlText <- paste("SELECT DISTINCT Convert(varchar(19), ID) as ID FROM tbl_Sample", sep=""); #Execute query queryResults <- dbGetQuery(connection, sqlText); 

Con esta solución, obtuve datos bigint sin ninguna modificación, pero no funcionó con RODBC. Ahora la velocidad de la interacción del servidor SQL con R se ha visto afectada porque RJDBC es más lento que RODBC, pero no está tan mal.

Hay muchas opciones que puede usar para R para números grandes. También puedes usar as.numeric (). El problema con as.numeric () es que encontré un error en la función para la versión R 3.02. Si multiplica los números usando el tipo de datos as.numeric () y los números producen un resultado de alrededor de 16 dígitos, obtendrá un resultado de error. Este error de as.numeric () se ha probado en muchas bibliotecas.

Hay otra opción

Escribí dos progtwigs para R, uno se llama infiX y el otro es infiXF para R. Actualmente, esta biblioteca solo admite cálculos de multiplicación. Ambos calculan números con el decimal preciso. Ha sido probado más de 100,000 veces. infiX se ocupará del número en formato de cadena donde infiXF lo llevará a la base del sistema de archivos.

Cuando almacena el número en la memoria, está limitado a 8 – 128 Gb dependiendo de su memoria. A veces, incluso menos si el comstackdor no le permite utilizar todos los recursos disponibles. Cuando calcule los números en una base de archivos de texto, puede calcular 1/5 del tamaño del disco duro. El único problema es el tiempo que necesitaría para un cálculo.

Por ejemplo, si estaba calculando 1 terabyte de dígitos a otro terabyte de dígitos. Eso es alrededor de 2 billones de dígitos. Eso es factible en un disco duro de 8 terabytes. Sin embargo, ¿tengo tiempo para hacer el cálculo?

InfiX for R se puede encontrar aquí. http://kevinhng86.iblog.website/2017/02/21/working-with-number-infinity-multiplication-optimised-the-code-r/