当尝试通过指定由大整数组成的字段的值来选择data.table
(R
的包)中的行时,我会得到奇怪的结果。也就是说,也选择了类似的整数。
require(data.table)
options(digits=15)
data <- data.table(A=c(1000200030001,1000200030002,1000200030003))
尝试通过检查A:
的值来访问第一行data[A==1000200030001]
A
1: 1000200030001
2: 1000200030002
3: 1000200030003
显示所有三行,我希望只返回第一行。
使用as.numeric
时问题解决了:
data[as.numeric(A)==1000200030001]
A
1: 1000200030001
数据的j
部分中没有问题。表:
data[,A == 1000200030001]
[1] TRUE FALSE FALSE
这似乎是比较大数字的精确度的问题。我很困惑,使用as.numeric
解决了问题,因为str(data)
显示A已经是数字类型:
str(data)
Classes ‘data.table’ and 'data.frame': 3 obs. of 1 variable:
$ A: num 1e+12 1e+12 1e+12
- attr(*, ".internal.selfref")=<externalptr>
- attr(*, "index")= atomic
..- attr(*, "A")= int
有关如何确保此问题未出现在(高效)代码中的任何提示都很受欢迎!
更新: 禁用自动索引时,上述问题不存在。
options(datatable.auto.index=FALSE)
但是,通过禁用自动索引无法解决聚合和合并/加入的问题:
data[,.(B=sum(A)),A]
A B
1: 1000200030001 1000200030001
正确的输出是:
A B
1: 1000200030001 1000200030001
2: 1000200030002 1000200030002
3: 1000200030003 1000200030003
我发现所有这些问题的最佳解决方案是使用所选答案中所述的bit64
包。谢谢大家!
答案 0 :(得分:4)
使用bit64::integer64
:
require(data.table)
options(digits=15)
library(bit64)
data <- fread("A
1000200030001
1000200030002
1000200030003", colClasses = "integer64")
data[A == as.integer64("1000200030001")]
#A
#1: 1000200030001
或者,停用自动索引(并从中失去性能优势):
options(datatable.auto.index=FALSE)
data <- data.table(A=c(1000200030001,1000200030002,1000200030003))
data[(A==1000200030001)]
# A
#1: 1000200030001