4

我遇到了函数的某种奇怪(或只是没想到?)的行为seq。创建简单序列时,某些值无法与 == 运算符正确匹配。看这个最小的例子:

my.seq <- seq(0, 0.4, len = 5)
table(my.seq)                  # ok! returns  0 0.1 0.2 0.3 0.4 
                               #              1   1   1   1   1 

which(my.seq == 0.2)           # ok! returns  3
which(my.seq == 0.3)           # !!! returns  integer(0)

手动创建我的序列时,它似乎可以工作,但是:

my.seq2 <- c(0.00, 0.10, 0.20, 0.30, 0.40)

which(my.seq2 == 0.3)           # ok! returns  4

你对此有什么解释吗?我通过使用解决了这个问题,which(round(my.seq, 2) == 0.3)但我会对导致问题的原因感兴趣。

提前感谢您的评论。

4

3 回答 3

4

计算机只是不能很好地表示浮点数。作为大多数人在计算机上处​​理数字的主要方式,电子表格隐藏这一点的一般趋势导致了许多问题。

永远不要匹配精确的浮点值。R 中有一些函数可以处理这个问题(例如all.equal),但我更喜欢以下函数。

假设您有一个未知的浮点变量 A,并且您想查看它是否等于 0.5。

abs(A - 0.5) < tol

将公差设置为您需要的接近程度为 0.5。例如,tol <- 0.0001可能适合您。

如果您的值看起来应该是整数,则只是四舍五入。或者,如果您知道要测试的十进制级别,则可以四舍五入到该十进制级别。

于 2012-07-31T15:05:04.040 回答
3

计算机很难存储准确的值。

> options(digits=22)
> seq(0, .4, len = 5)
[1] 0.0000000000000000000000 0.1000000000000000055511 0.2000000000000000111022
[4] 0.3000000000000000444089 0.4000000000000000222045
> .4
[1] 0.4000000000000000222045
> c(0, .1, .2, .3, .4)
[1] 0.0000000000000000000000 0.1000000000000000055511 0.2000000000000000111022
[4] 0.2999999999999999888978 0.4000000000000000222045

由于我们使用二进制浮点表示,我们无法准确表示感兴趣的值。看起来,因为 .4 的值比 0.4 高一点,所以 .3 的值比你自己键入 .3 的值高一点。我相信其他人会为此提供更好的解释,但希望这能对这个问题有所了解。

于 2012-07-31T14:40:21.223 回答
2

这是FAQ 7.31,它也有一个链接到一个更长的一般问题讨论。

于 2012-07-31T15:28:31.123 回答