Can someone please explain to me the tolerance parameter of all.equal
?
The manual says (?all.equal
):
tolerance
: numeric ≥ 0. Differences smaller than tolerance are not considered.Numerical comparisons for scale = NULL (the default) are done by first computing the mean absolute difference of the two numerical vectors. If this is smaller than tolerance or not finite, absolute differences are used, otherwise relative differences scaled by the mean absolute difference.
Example:
all.equal(0.3, 0.26, tolerance=0.1)
returns Mean relative difference: 0.1333333
Why is the mean relative difference returned here? Isn't the mean absolute difference of the two numerical vectors smaller than tolerance?
0.3 - 0.26 = 0.04 < 0.1
Thank you!
Description. all. equal(x, y) is a utility to compare R objects x and y testing 'near equality'. If they are different, comparison is still made to some extent, and a report of the differences is returned.
Identical function in R is one of the best way to test whether two objects are exactly equal. R Identical function, returns TRUE when two objects are equal and it returns FALSE when two objects are not equal.
If target
is greater than tolerance
, it seems to check for relative error <= tolerance
. That is, abs(current-target)/target <= tolerance
in:
all.equal(target, current, tolerance)
For ex:
all.equal(3, 6, tolerance = 1)
# TRUE --> abs(6-3)/3 <= 1
Instead, if target
is smaller than tolerance
, all.equal
uses mean absolute difference
.
all.equal(0.01, 4, tolerance = 0.01)
# [1] "Mean absolute difference: 3.99"
all.equal(0.01, 4, tolerance = 0.00999)
# [1] "Mean relative difference: 399"
all.equal(4, 0.01, tolerance = 0.01)
# [1] "Mean relative difference: 0.9975"
However, this is not what the documentation states. To look further as to why this is happening, let's look at the relevant snippet from all.equal.numeric
:
# take the example: all.equal(target=0.01, current=4, tolerance=0.01)
cplx <- is.complex(target) # FALSE
out <- is.na(target) # FALSE
out <- out | target == current # FALSE
target <- target[!out] # = target (0.01)
current <- current[!out] # = current (4)
xy <- mean((if(cplx) Mod else abs)(target - current)) # else part is run = 3.99
# scale is by default NULL
what <- if (is.null(scale)) {
xn <- mean(abs(target)) # 0.01
if (is.finite(xn) && xn > tolerance) { # No, xn = tolerance
xy <- xy/xn
"relative"
}
else "absolute" # this is computed for this example
}
else {
xy <- xy/scale
"scaled"
}
All that is being checked in the code above (shown only the necessary parts for the example from OP) is: to remove any NA and equal values (of target
and current
) from target
and current
. Then compute xy
as the mean absolute difference of target
and current
. But deciding if it is going to be relative
or absolute
depends on the part what
. And here xy
is not checked for any conditions. It depends only on xn
which is mean(abs(target))
.
So, in conclusion, the part pasted by the OP (pasted here for convenience):
If this (meaning, mean absolute difference) is smaller than tolerance or not finite, absolute differences are used, otherwise relative differences scaled by the mean absolute difference.
seems wrong/misleading.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With