C8H10N4O2
C8H10N4O2

Reputation: 19005

Test for equality between all members of list

What is the right syntax to check equality between all members of a list? I found that

do.call(all.equal, list(1,2,3))

returns TRUE.

My hunch is that it is checking equality within elements of a list, not between.

Ideally the solution would ignore the name of the element, but not those of the element components. For example, it should return TRUE given the input:

some_list <- list(foo = data.frame(a=1),
                  bar = data.frame(a=1))

But FALSE given the input:

some_other_list <- list(foo = data.frame(a=1),
                        bar = data.frame(x=1))

But I could live with a solution that was sensitive to the name of the element.


Edit: Clearly I need to review ?funprog. As a follow-up to the accepted answer, it's worth noting the following behavior:

Reduce(all.equal, some_list)  # returns TRUE

Reduce(all.equal, some_other_list) #returns [1] "Names: 1 string mismatch"

And for:

yet_another_list <- list(foo = data.frame(a=1),
                        bar = data.frame(x=2))
Reduce(all.equal, yet_another_list)
# returns: [1] "Names: 1 string mismatch"     "Component 1: Mean relative difference: 1"

Edit 2: My example was inadequate, and Reduce doesn't work in the case of 3 or more elements:

some_fourth_list <- list(foo = data.frame(a=1),
                  bar = data.frame(a=1),
                  baz = data.frame(a=1))
Reduce(all.equal, some_fourth_list) # doesn't return TRUE

Upvotes: 9

Views: 3286

Answers (2)

G. Grothendieck
G. Grothendieck

Reputation: 269852

1) IF the list has only two components as in the question then try this:

identical(some_list[[1]], some_list[[2]])
## [1] TRUE

2) or for a general approach with any number of components try this:

all(sapply(some_list, identical, some_list[[1]]))
## [1] TRUE

L <- list(1, 2, 3)
all(sapply(L, identical, L[[1]]))
## [1] FALSE

3) Reduce This is a bit verbose compared to the prior solution but since there was a discussion of Reduce, this is how it could be jmplemented:

Reduce(function(x, y) x && identical(y, some_list[[1]]), init = TRUE, some_list)
## [1] TRUE

Reduce(function(x, y) x && identical(y, L[[1]]), init = TRUE, L)
## [1] FALSE

Upvotes: 12

P. Denelle
P. Denelle

Reputation: 830

What about this :

identical(unlist(some_list), unlist(some_other_list))

Upvotes: 0

Related Questions