【问题标题】:Common elements of vectors with multiple elements具有多个元素的向量的公共元素
【发布时间】:2013-05-05 19:42:14
【问题描述】:

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

例子:

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

intersect 不能很好地处理重复元素。

【问题讨论】:

  • 两个向量的长度是否相等?
  • 不,不能假设。它们也没有排序。

标签: r vector intersection


【解决方案1】:

我喜欢intersecttables,所以...

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 - 我建议comtab &lt;- c(pmin(tv1[comvals], tv2[comvals]))。好吧,现在我知道这正是 @Carson 所做的。
【解决方案2】:

这是另一种选择:

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 的评论加快速度

【讨论】:

  • @Roland 你确定吗?对我来说似乎可以处理不同长度的向量。它不会被排序,但它对我有用。除非我没有尝试足够的测试用例......
  • 啊,这就是明确创建因子的目的。 +1
  • 也就是说,只计算一次unique(v1, v2)而不是两次就可以获得基本的加速。
【解决方案3】:

我确信有很多方法可以做到这一点,但我选择对其进行排序并使用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

【讨论】:

  • 它可以,但是我需要大量使用这个功能,我有点担心效率。您的解决方案使用:2 * rle、2 * 排序、2 * %in% 和 1 * 交集。我希望有一个聪明的方法来做这个。
  • 好吧,你从来没有提到问题中的效率,所以我提供了这个作为第一次尝试。但是又不能保证向量的长度相等,或者向量是否已排序或有关向量本身的任何其他知识......如果你想加快速度,你总是可以使用 Rcpp ......但话虽如此,这个解决方案似乎有效即使使用大向量,对我来说也相当快。
  • 我在问题的开头提到了效率:“如何有效地......”。我将测试您的解决方案的效率。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-11
  • 2012-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多