What is the best way to compare more than two objects with all.equal()
?
Here's one way:
foo <- c(1:10)
bar <- letters[1:10]
baz <- c(1:10)
# doesn't work because all.equal() returns a character vector when objects not all equal
all(sapply(list(bar, baz), all.equal, foo))
# this works
mode(sapply(list(bar, baz), all.equal, foo)) == "logical" #FALSE
bar <- c(1:10)
mode(sapply(list(bar, baz), all.equal, foo)) == "logical" #TRUE
UPDATE: @BrodieG pointed out that the one-liner above only tells you whether the objects are all equal or not, whereas all.equal()
tells you what isn't equal about them if they aren't equal.
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 Language is used to return TRUE when two objects are equal else return FALSE.
Method 2: Using length() and unique() function By using unique function if all the elements are the same then the length is 1 so by this way if the length is 1, we can say all elements in a vector are equal.
Check if Two Objects are Equal in R Programming – setequal() Function. setequal() function in R Language is used to check if two objects are equal. This function takes two objects like Vectors, dataframes, etc. as arguments and results in TRUE or FALSE, if the Objects are equal or not.
Here is an option:
objs <- mget(c("foo", "bar", "faz"))
outer(objs, objs, Vectorize(all.equal))
It's better than yours because it will detect when bar
and faz
are the same, even when foo
isn't. That said, it does a lot of unnecessary comparisons and will be slow. For example, if we change foo
to be letters[1:10]
we get:
foo bar faz
foo TRUE Character,2 Character,2
bar Character,2 TRUE TRUE
faz Character,2 TRUE TRUE
For details on what went wrong, just subset:
outer(objs, objs, Vectorize(all.equal))[1, 2]
Produces:
[[1]]
[1] "Modes: character, numeric"
[2] "target is character, current is numeric"
If all you care about is that all the objects must be all.equal
, then your solution is pretty good.
Also, as per comments to limit some of the duplicate calculations:
res <- outer(objs, objs, function(x, y) vector("list", length(x)))
combs <- combn(seq(objs), 2)
res[t(combs)] <- Vectorize(all.equal)(objs[combs[1,]], objs[combs[2,]])
res
Produces
foo bar faz
foo NULL Character,2 Character,2
bar NULL NULL TRUE
faz NULL NULL NULL
This still shows the full matrix, but makes it obvious what comparisons produced what.
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