Testing multiple vectors for equality

Load packages

library(tidyverse)

Problem statement

Assume we have some vectors (eg, 3), and we want to check if they are equal (the same elements in each vector). Assume further we do not in advance the number of vectors to check.

Here’s some toy data.

a<- c(1,2,3,4)
b<- c(1,2,3,5)
c<- c(1,3,4,5)

The gist

This soluation is based on the code of Akrun from this SO post (slightly adapted).

sum(reduce(map2(list(a,b,c), list(a), `==`), `&`))
#> [1] 1

Explanation

Let’s break that in handy pieces to get a grip on it.

First, let’s take the three lists (a, b, c), and test if each elements is equal to the corresponding element from the first list (a):

list(a, b, c) %>% 
  map2(list(a), `==`)
#> [[1]]
#> [1] TRUE TRUE TRUE TRUE
#> 
#> [[2]]
#> [1]  TRUE  TRUE  TRUE FALSE
#> 
#> [[3]]
#> [1]  TRUE FALSE FALSE FALSE

The result tells us for each of the three lists (a, b, c) whether its \(i\)th element is identical to the \(i\)th element from the first list (a).

Now we need to summarise (reduce) that. For example, the first of the \(i\) (here, four) elements should be T if and only if all (three) are T. This is accomplished by the function & in conjunction with reduce.

list(a, b, c) %>% 
  map2(list(a), `==`) %>% 
  reduce(`&`)
#> [1]  TRUE FALSE FALSE FALSE

The above results tells us that none of the i (here, four) elements are identical across the (three) lists. That is, at least one of the elements of the list differs.

Finally, we again have to summarise (reduce) this list to one element. Again, the result should only be true, if all are true.

list(a, b, c) %>% 
  map2(list(a), `==`) %>% 
  reduce(`&`) %>% 
  reduce(`&`)
#> [1] FALSE

Maybe more telling, we can exchange the second reduce by mean:

list(a, b, c) %>% 
  map2(list(a), `==`) %>% 
  reduce(`&`) %>% 
  mean()
#> [1] 0.25

This coefficient is as a result scaled from 0 (no element is identical across all lists) to 1 (all elements at a given position are identical).