2015-03-19 41 views

回答

9

另一种选择方式:

which(!(vec %in% vec[duplicated(vec)])) 
#[1] 3 12 
3

你可以试试这个

which(vec %in% names(table(vec))[table(vec)==1]) 
# 3 12 
3

您也可以尝试ave,像这样:

> which(as.logical(ave(vec, vec, FUN = function(x) length(x) == 1))) 
[1] 3 12 

由于ave似乎并不流行,这里的一对duplicated一拧:

which(!(duplicated(vec) | duplicated(vec, fromLast = TRUE))) 

它的表现相当好,因为ave也由:-)

## A bigger vector to hunt through 
set.seed(1) 
vec <- sample(c(1:9, sample(10:1000, 100000, TRUE))) 

## Some functions to test 
roland <- function() which(!(vec %in% vec[duplicated(vec)])) 
am1 <- function() which(as.logical(ave(vec, vec, FUN = function(x) length(x) == 1))) 
am2 <- function() which(!(duplicated(vec) | duplicated(vec, fromLast = TRUE))) 
mb <- function() which(vec %in% names(table(vec))[table(vec)==1]) 

## The benchmarks 
library(microbenchmark) 
microbenchmark(roland(), am1(), am2(), mb()) 
# Unit: milliseconds 
#  expr  min   lq  mean  median   uq  max neval 
# roland() 6.869534 8.781927 13.83998 9.332151 10.577182 67.52081 100 
#  am1() 15.778865 16.992881 23.74078 18.394768 20.341746 74.58536 100 
#  am2() 4.764585 6.340731 11.20347 7.004970 7.492049 65.00799 100 
#  mb() 117.185928 122.187247 132.90390 124.526029 127.875117 233.82788 100 
+0

哪里'rle'解决方案? – 2015-03-19 12:33:15

+0

@DavidArenburg它说这取决于数字的增加序列。我没有看到一种快速的方法来修改它以消除这种限制。 – A5C1D2H2I1M1N2O1R2T1 2015-03-19 12:34:00

+0

@DavidArenburg我假设这是一个tongue舌的答案:-)。不幸的是,我担心你必须先用'which(unique(rle(data)$ values)&rle(data)$ lengths == 1)'(不是有效的代码) – 2015-03-19 12:59:48

2

使用rle另一种方法:

with(rle(sort(vec)), match(values[lengths==1], vec)) 
[1] 3 12