R中的long/bigint/decimal等效数据类型

R中的long/bigint/decimal等效数据类型,r,types,R,Types,在R中,我们必须选择哪些数据类型来处理大数?默认情况下,整数的大小似乎是32位,因此来自sql server的bigint数字以及通过rpy2从python传递的任何大数字都会被破坏 > 123456789123 [1] 123456789123 > 1234567891234 [1] 1.234568e+12 当使用RODBC读取123456789123456789的bigint值时,它返回为123456789123456784(参见最后一位数字),当通过RJSONIO反序列化时

在R中,我们必须选择哪些数据类型来处理大数?默认情况下,整数的大小似乎是32位,因此来自sql server的bigint数字以及通过rpy2从python传递的任何大数字都会被破坏

> 123456789123
[1] 123456789123
> 1234567891234
[1] 1.234568e+12
当使用RODBC读取123456789123456789的bigint值时,它返回为123456789123456784(参见最后一位数字),当通过RJSONIO反序列化时,相同的数字返回为-1395630315L(这似乎是RJSONIO的一个附加错误/限制)

事实上,我确实需要能够处理来自JSON的大量数据,因此由于RJSONIO的限制,除了找到一个更好的JSON库之外,我可能没有其他解决方法(现在看来这是一个非选项)。我想听听专家们对此以及一般情况的看法。

请参阅
帮助(整数)

 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.

因此,我建议使用
数字(即“double”)——一个双精度数字。

Dirk是正确的。您应该使用
numeric
类型(应设置为double)。另一件需要注意的事情是,您可能无法返回所有数字。请看数字设置:

> options("digits")
$digits
[1] 7
您可以扩展此功能:

options(digits=14)
或者,您可以重新设置号码的格式:

format(big.int, digits=14)
我测试了您的号码,得到了相同的行为(甚至使用了
double
数据类型),因此这可能是一个bug:

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

我对你的问题的理解与之前的两位有所不同

如果R的最大默认值对您来说不够大,那么您有几个选择(免责声明:我使用了下面提到的每个库,但不是通过R绑定,而是通过其他语言绑定或本机库)

包:使用自然日志存储值;(与Rmpfr类似,使用R的新类结构实现)。任何人的工作都需要如此规模的数字,我对此印象深刻

library(Brobdingnag)

googol <- as.brob(1e100)   
包:与gmp(如上)和MPFR接口的R绑定(MPFR又是gmp的当代实现。我使用了Python绑定('bigfloat'))考虑到它的范围,考虑到它似乎是维护得最积极的,最后考虑到它似乎是最彻底的文档,这可能是三者中您最好的选择


注意:要使用后两种方法中的任何一种,您需要安装本机库,并且。

我修复了rpy2中与整数相关的一些问题(Python可以在需要时从int切换到long,但R似乎无法做到这一点)。 整数溢出现在应该返回NA_Integer_


L.

在提出这个问题后,Romain Francois和Jens Oehlschlägel的软件包现在可以使用了。

过去两天我一直在试图找到解决这个问题的方法,今天终于找到了。我们的SQL数据库中有19位长的ID,早些时候我使用RODBC从服务器获取bigint数据。我尝试了int64和bit64也定义了选项(digits=19),但RODBC一直在给出问题。我用RJDBC替换了RODBC,在从SQL server检索bigint数据时,我通过将bigint数据转换为字符串来操作SQL查询

下面是示例代码:

#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);
#包含统计数据包
需要(统计);
图书馆(RJDBC);
#设置工作目录
setwd(“W:/Users/dev/Apps/R/Data/201401_2”);
#获取JDBC驱动程序

驱动程序对于R,有许多选项可用于大数字。您也可以使用as.numeric()。as.numeric()的问题是,我在版本R 3.02的函数中发现了一个错误。如果使用as.numeric()乘以数字如果数据类型和数字恰好产生一个长度约为16位的结果,您将得到一个错误结果

还有另一种选择

我为R编写了两个程序,一个称为infiX,另一个称为infiXF for R。这个库目前只支持乘法计算。它们都计算精确的十进制数。经过100000多次测试。infiX将以字符串格式处理数字,infiXF将其带到文件系统库

当您将数字存储在内存中时,根据您的内存限制为8-128 Gb。如果编译器不允许您利用所有可用资源,有时甚至更少。当您在文本文件基础上计算数字时,您可以计算硬盘大小的1/5。唯一的问题是,计算所需的时间

例如,如果我计算的是1 TB的数字到另一TB的数字。这大约是2万亿位。这在8 TB的硬盘上是可行的。然而,我有时间进行计算吗


可以在此处找到R的中缀。

感谢您指出选项()和格式(),它们非常有用。但是,这些选项似乎只控制数字的显示格式,因此在使用as.double()或as.numeric()时不应更改数字的解析方式。该行为可能是一个错误。我认为这不起作用,您正在将整数转换为双精度,并且会丢失精度,因此您将无法将索引返回到引用的数组中。我查看了as.numeric()函数,但被模式(1)也给出“numeric”这一事实所迷惑作为类型,所以我认为我已经在处理它们了。然后我尝试了.numeric(“123456789123456789”)并看到只打印了几个数字,所以假设它失去了精度。我以前不知道选项(“数字”)。啊,是的,数字的事情。另外,如果你需要更高的精度或更大的数字,CRAN有相应的软件包,例如(奇怪的名字:-)Brobdingnag包用于大数,还有gmp包用于接口GNU gmp。(我知道Dirk知道这一点,但我的评论是为了提醒其他搜索者。)较新版本的R允许更无缝地转换为整数存储(双倍)。矩阵维度仍然没有使用那种自动模式
library(gmp)

x = as.bigq(8000, 21)
#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);