如何找到至少2个向量中常见的元素?

时间:2014-10-03 08:18:47

标签: r vector set-operations

说我有5个向量:

a <- c(1,2,3)
b <- c(2,3,4)
c <- c(1,2,5,8)
d <- c(2,3,4,6)
e <- c(2,7,8,9)

我知道我可以使用Reduce()intersect()一起计算所有这些之间的交集,如下所示:

Reduce(intersect, list(a, b, c, d, e))
[1] 2

但是我怎样才能找到至少2个向量中常见的元素?即:

[1] 1 2 3 4 8

7 个答案:

答案 0 :(得分:5)

它比许多人看起来要简单得多。这应该非常有效。

  1. 将所有内容放入向量中:

    x <- unlist(list(a, b, c, d, e))
    
  2. 查找重复项

    unique(x[duplicated(x)])
    # [1] 2 3 1 4 8
    
  3. sort如果需要。

    注意:如果列表元素中可能存在重复项(您的示例似乎并未涉及),请将x替换为x <- unlist(lapply(list(a, b, c, d, e), unique))


    编辑:由于OP表示对更通用的解决方案感兴趣,其中n> = 2,我会这样做:

    which(tabulate(x) >= n)
    

    如果数据仅由自然整数(1,2等)组成,如示例中所示。如果不是:

    f <- table(x)
    names(f)[f >= n]
    

    现在距离詹姆斯解决方案并不太远,但它避免了昂贵的问题sort。它比计算所有可能的组合快几英里。

答案 1 :(得分:2)

您可以尝试所有可能的组合,例如:

## create a list
l <- list(a, b, c, d)

## get combinations
cbn <- combn(1:length(l), 2)

## Intersect them 
unique(unlist(apply(cbn, 2, function(x) intersect(l[[x[1]]], l[[x[2]]]))))
## 2 3 1 4

答案 2 :(得分:1)

这是另一种选择:

# For each vector, get a vector of values without duplicates
deduplicated_vectors <- lapply(list(a,b,c,d,e), unique)

# Flatten the lists, then sort and use rle to determine how many
# lists each value appears in
rl <- rle(sort(unlist(deduplicated_vectors)))

# Get the values that appear in two or more lists
rl$values[rl$lengths >= 2]

答案 3 :(得分:0)

这是一种计算每个唯一值出现的向量数量的方法。

unique_vals <- unique(c(a, b, c, d, e))

setNames(rowSums(!!(sapply(list(a, b, c, d, e), match, x = unique_vals)),
                 na.rm = TRUE), unique_vals)
# 1 2 3 4 5 8 6 7 9 
# 2 5 3 2 1 2 1 1 1 

答案 4 :(得分:0)

另一种方法是将矢量化函数应用于outer

L <- list(a, b, c, d, e)
f <- function(x, y) intersect(x, y)
fv <- Vectorize(f, list("x","y"))
o <- outer(L, L, fv)
table(unlist(o[upper.tri(o)]))

#  1  2  3  4  8 
#  1 10  3  1  1 

上面的输出给出了共享每个重复元素1,2,3,4和8的向量对的数量。

答案 5 :(得分:0)

@rengis方法的变体是:

unique(unlist(Map(`intersect`, cbn[1,], cbn[2,])))
#[1] 2 3 1 4 8

其中,

l <- mget(letters[1:5])
cbn <- combn(l,2)

答案 6 :(得分:0)

当向量很大时,duplicatedtabulate 之类的解决方案可能会溢出您的系统。在这种情况下,dplyr 可以派上用场,代码如下

library(dplyr) combination_of_vectors <- c(a, b, c, d, e)
#For more than 1 
combination_of_vectors %>% as_tibble() %>% group_by(x) %>% filter(n()>1)
#For more than 2 
combination_of_vectors %>% as_tibble() %>% group_by(x) %>% filter(n()>2)
#For more than 3 
combination_of_vectors %>% as_tibble() %>% group_by(x) %>% filter(n()>2)

希望对大家有所帮助