Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R: all.equal() for multiple objects?

Tags:

r

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.

like image 433
treysp Avatar asked Dec 05 '14 21:12

treysp


People also ask

What does all equal do in R?

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.

What does identical () do in R?

identical() function in R Language is used to return TRUE when two objects are equal else return FALSE.

How do you check if all elements in a vector are equal in R?

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.

Are two objects equal R?

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.


1 Answers

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.

like image 56
BrodieG Avatar answered Oct 08 '22 05:10

BrodieG