R 中的浮点困难,尤其是 Hmisc 中的 minor.tick

Floating point difficulties in R and in particular in Hmisc's minor.tick

当我打电话给

library(Hmisc)
plot(...)
minor.tick(...)

偶尔我会运行出现以下错误:

Error in seq.default(low.minor, hi.minor, by = distance.between.minor) : 
  'to' cannot be NA, NaN or infinite
In addition: Warning message:
In max(possible.minors[possible.minors <= range[2]]) :
  no non-missing arguments to max; returning -Inf

minor.tick中有以下几行:

range <- par("usr")[if (w == "x") 1:2 else 3:4]
tick.pos <- if (w == "x") par("xaxp") else par("yaxp")
...
possible.minors <- tick.pos[2] + (0:100) * distance.between.minor
hi.minor <- max(possible.minors[possible.minors <= range[2]])

当我打印出 possible.minorsrange[2] 的值时,我看到了,例如,

> possible.minors [1] 1.20 1.24 1.28 1.32 1.36 1.40 1.44 1.48 1.52 1.56 1.60 1.64 1.68 1.72 1.76 [16] 1.80 1.84 1.88 1.92 1.96 2.00 2.04 2.08 2.12 2.16 2.20 2.24 2.28 2.32 2.36 [31] 2.40 2.44 2.48 2.52 2.56 2.60 2.64 2.68 2.72 2.76 2.80 2.84 2.88 2.92 2.96 [46] 3.00 3.04 3.08 3.12 3.16 3.20 3.24 3.28 3.32 3.36 3.40 3.44 3.48 3.52 3.56 [61] 3.60 3.64 3.68 3.72 3.76 3.80 3.84 3.88 3.92 3.96 4.00 4.04 4.08 4.12 4.16 [76] 4.20 4.24 4.28 4.32 4.36 4.40 4.44 4.48 4.52 4.56 4.60 4.64 4.68 4.72 4.76 [91] 4.80 4.84 4.88 4.92 4.96 5.00 5.04 5.08 5.12 5.16 5.20

> range[2] [1] 1.2

这最终给了我们

> possible.minors[1]
[1] 1.2
> range[2]
[1] 1.2
> possible.minors[1] <= range[2]
[1] FALSE

所以1.2不小于等于1.2。好的,显然这里发生了一些浮点数废话。我该如何解决?

附录:

当我打印更多数字时,我发现

> print(possible.minors[1], digits=20)
[1] 1.2000000000000001776
> print(range[2], digits=20)
[1] 1.1999999999999999556

看来这个包的作者预料到了这一点,因为下一行检查结果是否为NA,如果是,则赋值。也许这在以前的 R 版本中有效,但现在似乎会导致程序包崩溃。无论如何,我认为正确的方法是检查是否有任何值使不等式成立,如果是,则选择最大值,如果不是,则执行其他操作。现在,我可以在我自己的机器上实现这个更改,但是我如何将它提供给全世界的 Hmisc 用户呢?

我已将其发布为 issue on the Hmisc github

我认为一个快速的解决方案是更改行

if (is.na(low.minor))

if (is.na(hi.minor))

if (is.na(low.minor) || is.infinite(low.minor))

if (is.na(hi.minor) || is.infinite(hi.minor))

但更好的解决方案是先检查是否

any(possible.minors >= range[1])

any(possible.minors <= range[2])

在进行任何索引之前避免出现警告消息。