如何快速查看 R 中超过 2 个向量的任何元素是否相等?
How can I quickly see if any elements of more than 2 vectors are equal in R?
(我预计这已经是 asked/answered。如果是这样,抱歉,我找不到答案。)
假设我有 6 个向量。如何快速检查每个向量的任何元素是否等于所有其他向量的任何元素?
我知道我可以做到以下几点,感觉真的cumbersome/pre-historic/error-prone:
any(vec1 %in% vec2, vec1 %in% vec3, vec1 %in% vec4, vec1 %in% vec5, vec1 %in% vec6,
vec2 %in% vec3, vec2 %in% vec4, vec2 %in% vec5, vec2 %in% vec6,
vec3 %in% vec4, vec3 %in% vec5, vec3 %in% vec6,
vec4 %in% vec5, vec4 %in% vec6,
vec5 %in% vec6)
谢谢。
顺便说一下,我检查了 How to find common elements from multiple vectors?,这似乎是在询问如何识别 each 向量中存在的元素,而不是是否有任何元素来自任何向量都相等。
我们可以使用combn
找到向量字符串的组合,获取数据,将它们与%in%
进行比较,如果需要的话用any
和unlist
换行
v1 <- unlist(combn(paste0("vec", 1:6), 2, FUN = function(x)
any(get(x[1]) %in% get(x[2])), simplify = FALSE))
names(v1) <- combn(paste0("vec", 1:6), 2, FUN = paste, collapse="-")
正如 OP 提到的效率,如果需要,可以使用 combn
的 faster version。
此外,combn
可以直接应用于 list
。因此,可以将 vector
放在 list
中,然后执行 combn
v2 <- combn(mget(paste0("vec", 1:6)), 2, FUN = function(x) any(x[[1]] %in% x[[2]]))
names(v2) <- names(v1)
此外,由于 OP 正在对所有比较进行包装 any
。我们也可以用一个 any
any(combn(mget(paste0("vec", 1:6)), 2, FUN = function(x) x[[1]] %in% x[[2]]))
但我不确定这是否正确。
数据
vec1 <- 1:6
vec2 <- 2:3
vec3 <- 5:7
vec4 <- 6:8
vec5 <- 9:10
vec6 <- 11:12
如果将向量放在列表中,使用它们会容易得多:
# make sample data
set.seed(47)
x <- replicate(6, rpois(3, 10), simplify = FALSE)
str(x)
# List of 6
# $ : int [1:3] 16 12 10
# $ : int [1:3] 9 10 6
# $ : int [1:3] 10 14 4
# $ : int [1:3] 7 6 4
# $ : int [1:3] 12 8 7
# $ : int [1:3] 7 11 8
现在用 lapply
迭代:
lapply(x, function(y){sapply(x, function(z){y %in% z})})
## [[1]]
## [,1] [,2] [,3] [,4] [,5] [,6]
## [1,] TRUE FALSE FALSE FALSE FALSE FALSE
## [2,] TRUE FALSE FALSE FALSE TRUE FALSE
## [3,] TRUE TRUE TRUE FALSE FALSE FALSE
##
## [[2]]
## [,1] [,2] [,3] [,4] [,5] [,6]
## [1,] FALSE TRUE FALSE FALSE FALSE FALSE
## [2,] TRUE TRUE TRUE FALSE FALSE FALSE
## [3,] FALSE TRUE FALSE TRUE FALSE FALSE
## ... ... ... ... ... ... ...
这是每个向量的矩阵,其中行是相应向量的元素,列是列表中的每个向量,值表示该元素是否在该向量中。显然每个都会匹配自己,所以第一个元素的第一列都是TRUE
,第二个元素的第二列也是,等等。其他TRUE
表示交叉向量匹配。如果长度不一致,它将 return 相同信息的嵌套列表而不是矩阵。如果您仍然希望有一个嵌套列表,请将 sapply
更改为 lapply
。
或者,如果您只需要每个向量的匹配向量,
str(lapply(x, function(y){which(sapply(x, function(z){any(y %in% z)}))}))
## List of 6
## $ : int [1:4] 1 2 3 5
## $ : int [1:4] 1 2 3 4
## $ : int [1:4] 1 2 3 4
## $ : int [1:5] 2 3 4 5 6
## $ : int [1:4] 1 4 5 6
## $ : int [1:3] 4 5 6
其中每个元素仍然包含自己作为匹配项。取出布尔值 which
而不是索引。
(我预计这已经是 asked/answered。如果是这样,抱歉,我找不到答案。)
假设我有 6 个向量。如何快速检查每个向量的任何元素是否等于所有其他向量的任何元素?
我知道我可以做到以下几点,感觉真的cumbersome/pre-historic/error-prone:
any(vec1 %in% vec2, vec1 %in% vec3, vec1 %in% vec4, vec1 %in% vec5, vec1 %in% vec6,
vec2 %in% vec3, vec2 %in% vec4, vec2 %in% vec5, vec2 %in% vec6,
vec3 %in% vec4, vec3 %in% vec5, vec3 %in% vec6,
vec4 %in% vec5, vec4 %in% vec6,
vec5 %in% vec6)
谢谢。
顺便说一下,我检查了 How to find common elements from multiple vectors?,这似乎是在询问如何识别 each 向量中存在的元素,而不是是否有任何元素来自任何向量都相等。
我们可以使用combn
找到向量字符串的组合,获取数据,将它们与%in%
进行比较,如果需要的话用any
和unlist
换行
v1 <- unlist(combn(paste0("vec", 1:6), 2, FUN = function(x)
any(get(x[1]) %in% get(x[2])), simplify = FALSE))
names(v1) <- combn(paste0("vec", 1:6), 2, FUN = paste, collapse="-")
正如 OP 提到的效率,如果需要,可以使用 combn
的 faster version。
此外,combn
可以直接应用于 list
。因此,可以将 vector
放在 list
中,然后执行 combn
v2 <- combn(mget(paste0("vec", 1:6)), 2, FUN = function(x) any(x[[1]] %in% x[[2]]))
names(v2) <- names(v1)
此外,由于 OP 正在对所有比较进行包装 any
。我们也可以用一个 any
any(combn(mget(paste0("vec", 1:6)), 2, FUN = function(x) x[[1]] %in% x[[2]]))
但我不确定这是否正确。
数据
vec1 <- 1:6
vec2 <- 2:3
vec3 <- 5:7
vec4 <- 6:8
vec5 <- 9:10
vec6 <- 11:12
如果将向量放在列表中,使用它们会容易得多:
# make sample data
set.seed(47)
x <- replicate(6, rpois(3, 10), simplify = FALSE)
str(x)
# List of 6
# $ : int [1:3] 16 12 10
# $ : int [1:3] 9 10 6
# $ : int [1:3] 10 14 4
# $ : int [1:3] 7 6 4
# $ : int [1:3] 12 8 7
# $ : int [1:3] 7 11 8
现在用 lapply
迭代:
lapply(x, function(y){sapply(x, function(z){y %in% z})})
## [[1]]
## [,1] [,2] [,3] [,4] [,5] [,6]
## [1,] TRUE FALSE FALSE FALSE FALSE FALSE
## [2,] TRUE FALSE FALSE FALSE TRUE FALSE
## [3,] TRUE TRUE TRUE FALSE FALSE FALSE
##
## [[2]]
## [,1] [,2] [,3] [,4] [,5] [,6]
## [1,] FALSE TRUE FALSE FALSE FALSE FALSE
## [2,] TRUE TRUE TRUE FALSE FALSE FALSE
## [3,] FALSE TRUE FALSE TRUE FALSE FALSE
## ... ... ... ... ... ... ...
这是每个向量的矩阵,其中行是相应向量的元素,列是列表中的每个向量,值表示该元素是否在该向量中。显然每个都会匹配自己,所以第一个元素的第一列都是TRUE
,第二个元素的第二列也是,等等。其他TRUE
表示交叉向量匹配。如果长度不一致,它将 return 相同信息的嵌套列表而不是矩阵。如果您仍然希望有一个嵌套列表,请将 sapply
更改为 lapply
。
或者,如果您只需要每个向量的匹配向量,
str(lapply(x, function(y){which(sapply(x, function(z){any(y %in% z)}))}))
## List of 6
## $ : int [1:4] 1 2 3 5
## $ : int [1:4] 1 2 3 4
## $ : int [1:4] 1 2 3 4
## $ : int [1:5] 2 3 4 5 6
## $ : int [1:4] 1 4 5 6
## $ : int [1:3] 4 5 6
其中每个元素仍然包含自己作为匹配项。取出布尔值 which
而不是索引。