在data.table上设置键会产生与sort()不同的顺序吗?

时间:2016-09-09 10:00:04

标签: r data.table

通常,在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的排序算法时会有一些精度损失......但为什么呢?

1 个答案:

答案 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开发)。