R中的long / bigint / decimal等效数据types
我们必须在R中处理大量的数据typesselect? 默认情况下,一个整数的大小似乎是32位,所以sqlint的bigint数字以及从python通过rpy2传递的任何大数字都会被破坏。
> 123456789123 [1] 123456789123 > 1234567891234 [1] 1.234568e+12
当使用RODBC读取123456789123456789的bigint值时,它会以123456789123456784(参见最后一位数字)的forms返回,而通过RJSONIO进行反序列化时的相同数字会返回为-1395630315L(这看起来像是RJSONIO的一个额外的bug /限制)。
> fromJSON('[1234567891]') [1] 1234567891 > fromJSON('[12345678912]') [1] -539222976
实际上,我确实需要能够处理来自JSON的大量数据,所以对于RJSONIO的限制,除了find一个更好的JSON库(现在看起来像是一个非选项)之外,我可能没有任何解决方法。 我想听听专家们对此以及一般情况的意见。
查看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.
所以我会build议使用numeric
(即“双”) – 一个双精度数字。
我对你的问题和我之前发布的两个人有一点不同。
如果R的最大默认值不够大,你有几个select(免责声明:我已经使用了下面提到的每个库,但不是通过R绑定,而是通过其他语言绑定或本地库)
Brobdingnag包:使用自然日志来存储值; (如Rmpfr,使用R的新类结构实现)。 任何人的工作都需要这样的规模,我一直对此印象深刻。
library(Brobdingnag) googol <- as.brob(1e100)
gmp包:R绑定到古老的GMP(GNU多精度库)。 这必须回溯20年,因为我在大学使用它。 这个图书馆的座右铭是“没有限制的算术”,这是一个可信的主张 – 整数,理性,浮动,任何,直到你的盒子上的RAM的限制。
library(gmp) x = as.bigq(8000, 21)
Rmpfr包:与gmp(上面)和MPFR接口的R绑定,(MPFR反过来是gmp的一个当代实现,我使用了Python绑定('bigfloat'),并且可以推荐它。因为它看起来是最积极维护的,并且最终给出了看来是最彻底的文件。
注意:要使用后两者中的任何一个,您需要安装本地库GMP和MPFR 。
在问了这个问题之后,Romain Francois的package64和JensOehlschlägel的bit64现在都可以使用了。
德克是对的。 你应该使用numeric
types(应该设置为double)。 另外要注意的是,你可能不会收回所有的数字。 看数字设置:
> options("digits") $digits [1] 7
你可以扩展这个:
options(digits=14)
或者,您可以重新格式化数字:
format(big.int, digits=14)
我testing了你的号码,并得到相同的行为(即使使用double
数据types),所以这可能是一个错误:
> as.double("123456789123456789") [1] 123456789123456784 > class(as.double("123456789123456789")) [1] "numeric" > is.double(as.double("123456789123456789")) [1] TRUE
我在rpy2中解决了一些与整数有关的问题(Python在需要的时候可以从int变成long,但是R似乎不能这样做,整数溢出现在应该返回NA_integer_。
L.
我试图从过去两天find这个问题的解决方法,最后我今天find了。 我们的SQL数据库中有19位数字的长ID,早些时候我使用RODBC从服务器获取bigint数据。 我尝试了int64和bit64,也定义了选项(数字= 19),但RODBC不断给出问题。 我用RJDBCreplaceRODBC,并从SQL服务器检索bigint数据时,我通过使用bigint数据string操纵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);
有了这个解决scheme,我得到了bigint数据没有任何修改,但它不适用于RODBC。 现在SQL服务器与R交互的速度已经受到影响,因为RJDBC比RODBC慢,但也不是太糟糕。
有很多选项可以用于R大数字。 你也可以使用as.numeric()。 as.numeric()的问题是我在R 3.02版本的函数中发现了一个bug。 如果您使用as.numeric()数据types来乘数,并且数字碰巧产生长度大约为16位的结果,您将得到一个错误结果。 as.numeric()的这个bug已经在许多库上进行了testing。
还有另一种select。
我为R写了两个程序,一个叫做infiX,另一个是R的infiXF。这个库目前只支持乘法计算。 他们都计算精确到小数的数字。 已经testing了100,000次以上。 infiX将处理string格式的数字,infiXF将把它带到文件系统库。
当你把这个号码存储在内存中时,你的内存限制在8 – 128GB。 如果编译器不让你利用所有可用的资源,有时甚至更less。 当您计算文本文件基础上的数字时,可以计算硬盘大小的1/5。 唯一的问题是,它需要计算的时间。
例如,如果我正在计算1 TB的数字到另一个TB的数字。 那大概是2万亿位数。 这在8TB的硬盘上是可行的。 不过,我有时间做这个计算吗?
InfiX for R可以在这里find。 http://kevinhng86.iblog.website/2017/02/21/working-with-number-infinity-multiplication-optimised-the-code-r/