2015-03-19 39 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