2013-08-05 5 views
19

У меня есть вектор скалярных значений, которые я пытаюсь получить: «Сколько разных значений есть».Подсчет числа различных значений в векторе

Например, в group <- c(1,2,3,1,2,3,4,6) уникальными значениями являются 1,2,3,4,6, поэтому я хочу получить 5.

я придумал:

length(unique(group)) 

Но я не уверен, что это самый эффективный способ сделать это. Разве нет лучшего способа сделать это?

Примечание: Мое дело более сложное, чем пример, состоящий из около 1000 номеров с не более чем 25 различными значениями.

ответ

26

Вот несколько идей, все точки к вашему решению уже очень быстро. length(unique(x)) это то, что я бы использовал, а также:

x <- sample.int(25, 1000, TRUE) 

library(microbenchmark) 
microbenchmark(length(unique(x)), 
       nlevels(factor(x)), 
       length(table(x)), 
       sum(!duplicated(x))) 
# Unit: microseconds 
#     expr  min  lq median  uq  max neval 
# length(unique(x)) 24.810 25.9005 27.1350 28.8605 48.854 100 
# nlevels(factor(x)) 367.646 371.6185 380.2025 411.8625 1347.343 100 
#  length(table(x)) 505.035 511.3080 530.9490 575.0880 1685.454 100 
# sum(!duplicated(x)) 24.030 25.7955 27.4275 30.0295 70.446 100 
+0

Я бы добавил длину (таблица (x)) к проверенным функциям. –

+0

@WojciechSobala: Нет, см., Что 'length (tabulate (x))' не дает правильного результата, например, с помощью flodel

+0

Никогда не доверяйте (полностью) ощущению кишки. ^^ Благодаря @flodel за то, что я открыл функцию 'sample' и microbenchmark lib! :) – AdrieanKhisbe

5

Я использовал эту функцию

length(unique(array)) 

и она отлично работает, и не требует внешних библиотек.

+2

Любопытно, почему это было downvoted – allthesignals

+7

@allthesignals Мне любопытно, почему это было поддержано. Я не понимаю, как это отвечает на вопрос? (Что было «Разве нет лучшего способа сделать это?») – Calimo

3

Вы можете использовать rle из base пакета

x<-c(1,2,3,1,2,3,4,6) 
    length(rle(sort(x))$values) 

rle производит два вектора (lengths и values). Длина вектора values дает вам уникальные значения.

2

uniqueN Функция от data.table эквивалентна length(unique(group)). Это также в несколько раз быстрее на больших наборах данных, но не столько на вашем примере.

library(data.table) 
library(microbenchmark) 

xSmall <- sample.int(25, 1000, TRUE) 
xBig <- sample.int(2500, 100000, TRUE) 
microbenchmark(length(unique(xSmall)), uniqueN(xSmall), 
       length(unique(xBig)), uniqueN(xBig)) 

#Unit: microseconds 
#     expr  min  lq  mean median  uq  max neval cld 
#1 length(unique(xSmall)) 17.742 24.1200 34.15156 29.3520 41.1435 104.789 100 a 
#2  uniqueN(xSmall) 12.359 16.1985 27.09922 19.5870 29.1455 97.103 100 a 
#3 length(unique(xBig)) 1611.127 1790.3065 2024.14570 1873.7450 2096.5360 3702.082 100 c 
#4   uniqueN(xBig) 790.576 854.2180 941.90352 896.1205 974.6425 1714.020 100 b 
Смежные вопросы