我遇到了函数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)
解决了这个问题,但我会对导致问题的原因感兴趣。
提前感谢您的意见。
答案 0 :(得分:3)
计算机只是不能很好地表示浮点数。电子表格隐藏这一点的一般趋势,作为大多数人处理计算机上的数字的主要方式,导致了许多问题。
永远不会与精确的浮点值匹配。 R中有一些功能可以解决这个问题(例如all.equal
),但我更喜欢以下内容。
假设您有一个未知的浮点变量A,并且您想要查看它是否等于0.5。
abs(A - 0.5) < tol
将容差设置为0.5。例如,tol <- 0.0001
可能适合您。
如果你的值看起来像是整数,那么它们应该是整数。或者,如果您知道要测试的小数级别,则可以舍入到该十进制级别。
答案 1 :(得分:2)
计算机很难存储确切的值。
> 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的值略高于.4,.3的值比你输入.3本身的值稍微高一点。我相信其他人会为此提供一个更好的解释,但希望这可以解释这个问题。
答案 2 :(得分:2)
这是FAQ 7.31,它也提供了对问题进行更长时间讨论的链接。