rlogical-operatorslogical-orlogical-and

Consolidating multiple OR and AND conditions in R


I want to consolidate multiple OR and AND conditions in R. I think x1 == 1 | x1 == 2 can be consolidated as x1 %in% c(1, 2). I'm wondering how x1 == 1 | y1 == 1 and x1 == 1 & y1 == 1 can be consolidated into more compact R code.

x1 <- c(1, 2, 3)
y1 <- c(1, 2, 4)

x1 == 1 | x1 == 2
#> [1]  TRUE  TRUE FALSE
x1 %in% c(1, 2)
#> [1]  TRUE  TRUE FALSE

x1 == 1 | y1 == 1
#> [1]  TRUE FALSE FALSE

intersect(x1, y1) == 1
#> [1]  TRUE FALSE
intersect(x1, y1) == 2
#> [1] FALSE  TRUE

intersect(x1, y1) %in% c(1, 2)
#> [1] TRUE TRUE

> x1 == 1 & y1 == 1
[1]  TRUE FALSE FALSE

Edited

The code (x1 == 1 | x1 == 2) & (y1 == 1 | y1 == 2) is equal to Reduce(any, lapply(list(x1), %in%, c(1, 2))) & Reduce(any, lapply(list(y1), %in%, c(1, 2))). Wondering to write this in more compact way.


Solution

  • I think you need lapply() and Reduce() for a clean "hackless" abstraction:

    x1 <- c(1, 2, 3)
    y1 <- c(1, 2, 4)
    y1 == 1 | x1 == 1
    #> [1]  TRUE FALSE FALSE
    Reduce(`|`, lapply(list(x1, y1), `==`, 1))
    #> [1]  TRUE FALSE FALSE
    

    You can win a few characters with apply(cbind(x1, y1) == 1, 1, all) (using matrix as an intermediate shape) but I don't know if it's worth it.

    Created on 2024-03-26 with reprex v2.0.2