通常,在data.table
上设置密钥会对其进行排序:
> foo <- data.table(x = c(8,6,7,5,3,0,9))
> setkey(foo, x)
> foo
x
1: 0
2: 3
3: 5
4: 6
5: 7
6: 8
7: 9
但不是在这种情况下:
> foo <- data.table(x = c(1234567890.02, 1234567890.01))
> setkey(foo, x)
> foo - 1234567890
x
1: 0.01999998
2: 0.00999999
相反,基础sort
函数正确排序:
> sort(foo$x) - 1234567890
[1] 0.00999999 0.01999998
我认为在应用data.table
的排序算法时会有一些精度损失......但为什么呢?
答案 0 :(得分:0)
Matt Dowle在评论中基本上回答了这个问题,但总结一下:
在data.table
v1.9.6
及更早版本中,加入/分组/排序数字列时的默认行为是将有效数字的最后两个字节四舍五入。可以通过调用setNumericRounding
来更改此行为。
此默认值的理由不是为了速度,而是为了避免出现令人惊讶的结果,例如:
DT = data.table(a=seq(0,1,by=0.2),b=1:2, key="a")
DT
setNumericRounding(0) # turn off rounding
DT[.(0.4)] # works
DT[.(0.6)] # no match, confusing since 0.6 is clearly there in DT
(摘自?setNumericRounding
文档。link)
但是,这个默认行为会产生意外排序,就像我在这个问题中提到的那样。另请参阅here
要解决此类问题,默认设置已更改为setNumericRounding(0)
中的v1.9.7
(此帖子发布时目前正在github开发)。