如何从向量中删除唯一值

时间:2014-02-01 05:34:06

标签: r

我有一个大数字向量 - 如何有效地从中删除唯一值?

举一个简单的例子,我如何从向量a到向量b

> a = c(1, 2, 3, 3, 2, 4) # 1 and 4 are the unique values
> b = c(2, 3, 3, 2)

4 个答案:

答案 0 :(得分:3)

添加到现有选项:

a[duplicated(a) | duplicated(a, fromLast=TRUE)]
# [1] 2 3 3 2

更新 :更多基准!

将Prasanna的回答与我的回答进行比较,并将其与asieira的功能进行比较,我们得到以下信息:

fun1 <- function(x) x[x %in% x[duplicated(x)]]
fun2 <- function(x) x[duplicated(x) | duplicated(x, fromLast=TRUE)]

set.seed(1)
a <- ceiling(runif(1000000, min=0, max=100))

library(microbenchmark)
microbenchmark(remove.uniques1(a), remove.uniques2(a), 
               fun1(a), fun2(a), times = 20)
# Unit: milliseconds
#                expr       min        lq    median        uq       max neval
#  remove.uniques1(a) 1957.9565 1971.3125 2002.7045 2057.0911 2151.1178    20
#  remove.uniques2(a) 2049.9714 2065.6566 2095.4877 2146.3000 2210.6742    20
#             fun1(a)  213.6129  216.6337  219.2829  297.3085  303.9394    20
#             fun2(a)  154.0829  155.5459  155.9748  158.9121  246.2436    20

我怀疑独特值的数量也会对这些方法的效率产生影响。

答案 1 :(得分:2)

a[a %in% a[duplicated(a)]]
[1] 2 3 3 2

答案 2 :(得分:1)

这应该给出正确答案。

a = c(1, 2, 3, 3, 2, 4)
dups <- duplicated(a)
dup.val <- a[dups]
a[a %in% dup.val]

答案 3 :(得分:1)

执行此操作的一种向量化方法是使用内置表函数来查找仅出现一次的值,然后将其从向量中删除:

> a = c(1, 2, 3, 3, 2, 4)
> tb.a = table(a)
> appears.once = as.numeric(names(tb.a[tb.a==1]))
> appears.once
[1] 1 4
> b = a[!a %in% appears.once]
> b
[1] 2 3 3 2

请注意,表函数将原始向量中的值转换为名称,即字符。所以我们需要在你的例子中将它转换回数字。

使用data.table执行此操作的另一种方法:

> dt.a = data.table(a=a)
> dt.a[,count:=.N,by=a]
> b = dt.a[count>1]$a
> b
[1] 2 3 3 2

现在让我们给他们时间:

remove.uniques1 <- function(x) {
  tb.x = table(x)
  appears.once = as.numeric(names(tb.x[tb.x==1]))
  return(x[!x %in% appears.once])
}

remove.uniques2 <- function(x) {
  dt.x = data.table(data=x)
  dt.x[,count:=.N,by=data]
  return(dt.x[count>1]$data)
}

> a = ceiling(runif(1000000, min=0, max=100))
> system.time( remove.uniques1(a) )
     user    system   elapsed 
    1.598     0.033     1.658 
> system.time( remove.uniques2(a) )
     user    system   elapsed 
    0.845     0.007     0.855

所以两者都非常快,但data.table版本显然更快。更不用说remove.uniques2保留输入向量的任何类型。但是,对于remove.uniques1,您必须将对.numeric的调用替换为适合原始矢量类型的调用。