tipo de dados equivalente long / bigint / decimal em R

Quais opções de dados temos para lidar com grandes números em R? Por padrão, o tamanho de um número inteiro parece ser de 32 bits, portanto, números bigint do sql server, assim como qualquer número grande passado de python via rpy2, são desconfigurados.

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

Ao ler um valor bigint de 123456789123456789 usando RODBC, ele retorna como 123456789123456784 (veja o último dígito), e o mesmo número quando desserializado via RJSONIO, retorna como -1395630315L (que parece ser um bug / limitação adicional de RJSONIO).

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

Na verdade, eu preciso ser capaz de lidar com grandes números provenientes de JSON, portanto, com a limitação do RJSONIO, posso não ter uma solução alternativa, exceto para encontrar uma biblioteca JSON melhor (o que parece ser uma não-opção agora). Eu gostaria de ouvir o que os especialistas têm a dizer sobre isso, assim como em geral.

Veja 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. 

então eu recomendo usar numeric (ou seja, ‘double’) – um número de precisão dupla.

Eu entendi sua pergunta um pouco diferente contra os dois que postaram antes que eu fiz.

Se o maior valor padrão de R não for grande o suficiente para você, você tem algumas opções (disclaimer: Eu usei cada uma das bibliotecas mencionadas abaixo, mas não através das ligações R, em vez de outras ligações de idioma ou da biblioteca nativa)

O pacote Brobdingnag : usa logs naturais para armazenar os valores; (como o Rmpfr, implementado usando a nova estrutura de classs do R). Estou sempre impressionado com qualquer pessoa cujo trabalho requeira números dessa escala.

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

O pacote gmp : ligações R para o venerável GMP (biblioteca GNU Multi-precision). Isso deve voltar 20 anos porque eu usei na Universidade. O lema desta biblioteca é "Aritmética Sem Limites", que é uma afirmação confiável - números inteiros, racionais, flutuantes, o que for, até os limites da RAM em sua checkbox.

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

O pacote Rmpfr : R vincula a interface tanto para o gmp (acima) quanto para o MPFR (o MPFR é uma implementação contemporânea do gmp. Eu usei os bindings do Python (bigfloat) e posso recomendá-lo altamente. opção dos três, dado seu escopo, dado que parece ser o mais ativamente mantido, e finalmente dado o que parece ser a documentação mais completa.

Nota: para usar os dois últimos, você precisará instalar as bibliotecas nativas, GMP e MPFR .

Depois que esta pergunta foi feita, os pacotes int64 de Romain Francois e bit64 de Jens Oehlschlägel já estão disponíveis.

Dirk está certo. Você deve estar usando o tipo numeric (que deve ser definido como double). A outra coisa a notar é que você pode não estar recebendo de volta todos os dígitos. Veja a configuração dos dígitos:

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

Você pode estender isso:

 options(digits=14) 

Alternativamente, você pode reformatar o número:

 format(big.int, digits=14) 

Eu testei o seu número e estou recebendo o mesmo comportamento (mesmo usando o tipo de dados double ), então isso pode ser um bug:

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

Eu fixei alguns problemas relacionados a inteiros em rpy2 (Python pode swich de int para long quando necessário, mas R não parece ser capaz de fazer isso. Incrustações de inteiro agora devem retornar NA_integer_.

EU.

Eu estava tentando encontrar uma solução para este problema nos últimos dois dias e finalmente encontrei hoje. Temos 19 dígitos em ids longos em nosso database SQL e, anteriormente, eu usei o RODBC para obter dados bigint do servidor. Eu tentei int64 e bit64, também opções definidas (dígitos = 19), mas RODBC continuou dando problemas. Eu substituí o RODBC pelo RJDBC e, ao recuperar os dados bigint do SQL Server, manipulei a consulta SQL usando a conversão de dados bigint para string.

Então aqui está o código de exemplo:

 #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); 

Com essa solução, obtive dados bigint sem qualquer modificação, mas não funcionou com o RODBC. Agora, a velocidade de interação do servidor SQL com o R afetou porque o RJDBC é mais lento que o RODBC, mas não é tão ruim.

Há muitas opções que você pode usar para R para um grande número. Você também pode usar as.numeric (). O problema com as.numeric () é que eu encontrei um bug na function para a versão R 3.02. Se você multiplicar números usando o tipo de dados as.numeric () e os números produzirem um resultado com cerca de 16 dígitos, você obterá um resultado de erro. Este bug do as.numeric () foi testado em muitas bibliotecas.

Existe outra opção.

Eu escrevi dois programas para R, um é chamado infiX e o outro é infiXF para R. Esta biblioteca atualmente suporta apenas cálculos de multiplicação. Ambos calculam números para o decimal preciso. Foi testado mais de 100.000 vezes. O infiX irá lidar com o número em formato de string onde o infiXF irá levá-lo para a base do sistema de arquivos.

Quando você armazena o número na memory, você está limitado a 8 – 128 Gb dependem da sua memory. Às vezes, até menos, se o compilador não permite utilizar todos os resources disponíveis. Quando você calcula números em uma base de arquivos de texto, você pode calcular 1/5 do tamanho do disco rígido. O único problema é o tempo necessário para um cálculo.

Por exemplo, se eu estivesse calculando 1 terabyte de dígitos para outro terabyte de dígitos. Isso é cerca de 2 trilhões de dígitos. Isso é possível em um disco rígido de 8 terabytes. No entanto, tenho tempo para fazer o cálculo?

O InfiX for R pode ser encontrado aqui. http://kevinhng86.iblog.website/2017/02/21/working-with-number-infinity-multiplication-optimised-the-code-r/