What is an elegant solution to make multiple xor comparisons in R?

Viewed 196

I need to filter a dataset according to multiple, mutually exclusive conditions. The xor operator seems useful for this case, but it feels a bit awkward to use in the dplyr::filter function. The other logical operators (|, &, ==, etc.) allow me to chain the comparisons, but I have not found a way to do that with xor. Here are the two approaches I could think of:

library(tidyverse)

#a)
Orange %>%
  filter(xor(Tree == 1, xor(circumference == 75, age == 1582)))

#b)
Orange %>%
  filter((Tree == 1 & !(circumference == 75) & !(age == 1582)) |
         (Tree != 1 &   circumference == 75  & !(age == 1582)) |
         (Tree != 1 & !(circumference == 75) &   age == 1582))

Both seem a bit complicated. In my dataset I need to test five conditions and the nested version a) becomes confusing. It also follows a very different pattern from other types of comparisons. Approach b) is bloated and increases the risk of typos.

I thought that something in the form of the %in% operator could be useful, like %xor%, but it does not seem to exist:

library(tidyverse)

Orange %>%
  filter(Tree == 1 %xor% circumference == 75 %xor% age == 1582)

What would be a more elegant approach than a) or b) that actually works?

1 Answers

Use the explicit conversion of booleans to integers to just look where the vectorized sum of the 3 logical checks you're doing is 1.

Orange %>%
  filter((Tree == 1) + (circumference == 75) + (age == 1582) == 1)
Related