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


when call

library(hmisc) plot(...) minor.tick(...) 

occasionally i'll run following error:

error in seq.default(low.minor, hi.minor, = distance.between.minor) :    'to' cannot na, nan or infinite in addition: warning message: in max(possible.minors[possible.minors <= range[2]]) :   no non-missing arguments max; returning -inf 

in minor.tick there following lines:

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]]) 

when print out values of possible.minors , range[2], see, example,

> 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

which gives

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

so 1.2 not less or equal 1.2. ok, floating point nonsense going on here. how can resolve this?

addendum:

when print more digits, find

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

it seems author of package anticipated this, because next line checks whether result na, , if so, assigns value. maybe worked in previous versions of r, seems cause package crash. in case, think correct way check if there values such inequality holds, , if pick max, , if not other thing. now, can implement change on own machine, how give fellow hmisc users of world?

i have posted issue on hmisc github.

i think 1 quick solution change lines

if (is.na(low.minor)) 

and

if (is.na(hi.minor)) 

to

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

and

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

but better solution first check whether

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

and

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

before doing indexing warning messages avoided.


Comments