As @joran alluded to, you'll run into floating point issues with ==
and !=
in pretty much any other language too. One important aspect of them in R is the vectorization part.
It would be much better to define a new function almostEqual
, fuzzyEqual
or similar. It is unfortunate that there is no such base function. all.equal
isn't very efficient since it handles all kinds of objects and returns a string describing the difference when mostly you just want TRUE
or FALSE
.
Here's an example of such a function. It's vectorized like ==
.
almostEqual <- function(x, y, tolerance=1e-8) {
diff <- abs(x - y)
mag <- pmax( abs(x), abs(y) )
ifelse( mag > tolerance, diff/mag <= tolerance, diff <= tolerance)
}
almostEqual(1, c(1+1e-8, 1+2e-8)) # [1] TRUE FALSE
...it is around 2x faster than all.equal
for scalar values, and much faster with vectors.
x <- 1
y <- 1+1e-8
system.time(for(i in 1:1e4) almostEqual(x, y)) # 0.44 seconds
system.time(for(i in 1:1e4) all.equal(x, y)) # 0.93 seconds
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…