具有多个元素的向量的共同元素

时间:2013-05-05 19:42:15

标签: r vector intersection

如何有效地找到具有重复元素的两个向量的公共元素?

示例:

v1 <- c(1, 1, 2, 3, 3, 4)  
v2 <- c(1, 1, 1, 3, 4, 5)  
commonElements <- c(1, 1, 3, 4)

intersect无法很好地处理重复元素。

3 个答案:

答案 0 :(得分:6)

我喜欢intersecttable s,所以......

tv1 <- table(v1)
tv2 <- table(v2)
comvals <- intersect(names(tv1),names(tv2))
comtab <- apply(rbind(tv1[comvals],tv2[comvals]),2,min)

信息仍然存在,但在(我认为)更好的格式:

> comtab
1 3 4 
2 1 1 

编辑:如果你真的想要那个矢量,那就是:as.numeric(rep(names(comtab),comtab))

答案 1 :(得分:5)

这是另一种选择:

common <- function(v1, v2) {
  lvls <- unique(c(v1, v2))
  v1a <- factor(v1, levels=lvls)
  v2a <- factor(v2, levels=lvls)
  v <- pmin(table(v1a), table(v2a))
  as.numeric(rep(names(v), v))
}

common(rep(1:3, 1:3), rep(1:2, 1:2))
[1] 1 2 2

common(rep(c(1,3,5), 1:3), rep(c(5,2), 2))
[1] 5 5

编辑:包装一个函数,展示不同的案例,并根据@Dason的评论加快速度

答案 2 :(得分:4)

我确信有很多方法可以做到这一点,但我选择对其进行排序并使用rle来获取值和计数。 table也可能完成同样的任务。

common <- function(v1, v2){
  r1 <- rle(sort(v1))
  r2 <- rle(sort(v2))
  vals <- intersect(r1$values, r2$values)
  l1 <- r1$lengths[r1$values %in% vals]
  l2 <- r2$lengths[r2$values %in% vals]
  rep(vals, pmin(l1, l2))
}

common(v1, v2)

一些例子

> common(v1, v2)
[1] 1 1 3 4
> common(c(1,1), c(3,2,1,3,1))
[1] 1 1
> common(c(1,2,3,2), c(1,2,3))
[1] 1 2 3