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).