我有一个大数字向量 - 如何有效地从中删除唯一值?
举一个简单的例子,我如何从向量a
到向量b
?
> a = c(1, 2, 3, 3, 2, 4) # 1 and 4 are the unique values
> b = c(2, 3, 3, 2)
答案 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的调用替换为适合原始矢量类型的调用。