我想合并R中的多个OR和AND条件。我认为
x1 == 1 | x1 == 2
可以合并为x1 %in% c(1, 2)
。我想知道如何将 x1 == 1 | y1 == 1
和 x1 == 1 & y1 == 1
合并为更紧凑的 R
代码。
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
由于
x1 == 1 | y1 == 1
看起来不太冗长,让我们创建更多向量:
set.seed(1)
lapply(1:10, \(.) sample(10, 10, replace = TRUE)) |>
setNames(paste0(c("x", "y"), c(1:5, 1:5))) |>
list2env(.GlobalEnv)
ls()
# [1] "x1" "x2" "x3" "x4" "x5" "y1" "y2" "y3" "y4" "y5"
现在写起来确实变得相当乏味:
x1 == 1 | y2 == 1 | x3 == 1 | y4 == 1 | x5 == 1 | y1 == 1 | x2 == 1 | y3 == 1 | x4 == 1 | y5 == 1
# [1] FALSE FALSE TRUE TRUE TRUE TRUE FALSE FALSE TRUE TRUE
我们使用逐元素逻辑运算符,因此保证向量的长度相同。让我们将它们放入数据框中进行比较:
compare <- function(..., op = c("==", "<", ">", ">=", "<=", "!="), compare_with = 1) {
fun = match.fun(match.arg(op))
rowSums(
fun(data.frame(...), compare_with)
) > 0
}
然后我们可以这样做:
compare(x1, y2, x3, y4, x5, y1, x2, y3, x4, y5)
# [1] FALSE FALSE TRUE TRUE TRUE TRUE FALSE FALSE TRUE TRUE
或者,如果这仍然需要太多的输入,我们可以将向量放入列表中(无论如何这更好),并将其提供给函数:
# Create a list of x1:x5 and y1:y5
l <- mget(ls(pattern = "[xy]\\d"))
compare(l)
# [1] FALSE FALSE TRUE TRUE TRUE TRUE FALSE FALSE TRUE TRUE
这也适用于
==
和其他运算符。
identical(
compare(x1, y2, x3, y4, x5, y1, x2, y3, x4, y5, op = "==", compare_with = 1),
x1 == 1 | y2 == 1 | x3 == 1 | y4 == 1 | x5 == 1 | y1 == 1 | x2 == 1 | y3 == 1 | x4 == 1 | y5 == 1
)
# [1] TRUE
identical(
compare(x1, y2, x3, y4, x5, y1, x2, y3, x4, y5, op = ">", compare_with = 9),
x1 > 9 | y2 > 9 | x3 > 9 | y4 > 9 | x5 > 9 | y1 > 9 | x2 > 9 | y3 > 9 | x4 > 9 | y5 > 9
)
# [1] TRUE
使用数据框(而不是矩阵)的一个优点是它只是指向每个向量的指针列表。这意味着不会创建数据副本。此外,数据框支持按元素进行这些比较操作,而无需迭代列(或行),因此即使您的数据很大,这也应该相当快。