document how `waldo::compare` and `all.equal` differ for relative numeric comparison
Perhaps this issue is known or has been reported before - in that case, apologies.
all.equal uses its first argument to compute the denominator of the relative difference. waldo::compare uses its second argument, leading to differences in behaviour as here:
> x <- c( 0.077172645966023900, -0.000266267947825388, -0.01796820303767930,
+ -0.000266267947825388, 0.026773667457362100, 0.00885332514392564,
+ -0.017968203037679300, 0.008853325143925640, 0.03937164346237700)
> y <- c(0.04, 0, 0, 0, 0.04, 0, 0, 0, 0.04)
> tol <- 0.02
> all.equal(x, y, tolerance = tol)
[1] "Mean relative difference: 0.5326904"
> all.equal(y, x, tolerance = tol)
[1] TRUE
> waldo::compare(x, y, tolerance = tol)
✔ No differences
> waldo::compare(y, x, tolerance = tol)
`old`: 0.040 0.000 0.000 0.000 0.040 0.000 0.000 0.000 0.040
`new`: 0.077 -0.000 -0.018 -0.000 0.027 0.009 -0.018 0.009 0.039
>
help("compare", package="waldo") and help("expect_equal", package="testthat") don't claim that they are drop-in replacements for all.equal(...) and stopifnot(all.equal(...)), but that seems to be a prevailing belief. The situation would be improved with clearer documentation about the correspondence of the arguments.
A corollary is that testthat::expect_equal(x, y, tolerance = tol) can fail under edition 2 and pass under edition 3. In that case, with the arguments reversed, the test would pass under edition 2 and fail under edition 3.
Hmm I thought of this as a difference in signatures since testthat::expect_equal() does object,expected whereas all.equal() does target,current which (to me) maps to actual,expected vs. expected,actual.
But if we look carefully at waldo::compare()'s signature directly, it gives the same impression as all.equal():
waldo::compare
function (x, y, ..., x_arg = "old", y_arg = "new"...)
old ~~ expected
new ~~ actual
The terminology is admittedly all over the place as we can see :)
Hmmmmm, I think one principle of waldo is that if compare(x, y) reports differences then so should compare(y, x). So that suggests we should maybe deliberately deviate from all.equal(). But I don't know enough about numerical comparison to do that myself.
Slightly simpler variation of @jaganmn's code:
x <- c(0.0772, 0.0004, -0.018, 0.0004, 0.0268, 0.0089, -0.018, 0.0089, 0.0394)
y <- c(0.04, 0, 0, 0, 0.04, 0, 0, 0, 0.04)
tol <- 0.02
all.equal(x, y, tolerance = tol)
#> [1] "Mean relative difference: 0.5333333"
all.equal(y, x, tolerance = tol)
#> [1] TRUE
waldo::compare(x, y, tolerance = tol)
#> ✔ No differences
waldo::compare(y, x, tolerance = tol)
#> `old`: 0.040 0.000 0.000 0.000 0.040 0.000 0.000 0.000 0.040
#> `new`: 0.077 0.000 -0.018 0.000 0.027 0.009 -0.018 0.009 0.039
Created on 2025-07-07 with reprex v2.1.1