2009-12-17 2 views

ответ

356

Вы можете просто использовать table():

> a <- table(numbers) 
> a 
numbers 
    4 5 23 34 43 54 56 65 67 324 435 453 456 567 657 
    2 1 2 2 1 1 2 1 2 1 3 1 1 1 1 

Тогда вы можете подмножество его:

> a[names(a)==435] 
435 
    3 

Или превратить его в data.frame, если вы более комфортно работать с этим:

> as.data.frame(table(numbers)) 
    numbers Freq 
1  4 2 
2  5 1 
3  23 2 
4  34 2 
... 
+12

Не забывайте о потенциальных проблемах с плавающей запятой, особенно с таблицей, которая координирует числа строк. – hadley

+3

Это отличный момент. Это все целые числа, поэтому в этом примере это не проблема. Не так ли? – Shane

+0

не совсем. Элементы таблицы имеют класс целочисленного класса (таблица (числа) [1]), но 435 - число с плавающей запятой. Чтобы сделать его целым числом, вы можете использовать 435L. –

8

здесь один быстрый и грязный способ:

x <- 23 
length(subset(numbers, numbers==x)) 
43

я бы, вероятно, сделать что-то вроде этого

length(which(numbers==x)) 

Но на самом деле, лучший способ

table(numbers) 
+10

'table (numbers)' будет делать намного больше работы, чем простое решение, sum (numbers == x) ', потому что он также будет вычислять количество всех остальных чисел в списке. –

+1

проблема с таблицей заключается в том, что ее сложнее включить в более сложное исчисление, например, с помощью apply() на dataframes – skan

205

Самый прямой путь sum(numbers == x).

numbers == x создает логический вектор, ИСТИНА в любом месте, которое происходит х, и когда sum ИНГ, логический вектор приведен к цифровому, который преобразует значение TRUE 1 и FALSE 0.

Однако, обратите внимание, что для чисел с плавающей запятой лучше использовать что-то вроде: sum(abs(numbers - x) < 1e-6).

+1

хорошая точка зрения на проблему с плавающей запятой. Это кусает мою задницу больше, чем я обычно признаю. –

+3

@ Джейсон, когда он отвечает на вопрос напрямую, я предполагаю, что людям понравилось более общее решение, которое дает ответ для всех 'x' в данных, а не для определенного известного значения' x'. Справедливости ради, в этом и был исходный вопрос. Как я уже сказал в своем ответе ниже: «Я нахожу, что редко хочу узнать частоту одного значения, а не все значения ...» – JBecker

16

Существует стандартная функция R для этого

tabulate(numbers)

+0

Недостатком «табуляции» является то, что вы не можете иметь дело с нулем и отрицательные числа. – omar

+1

Но вы можете иметь дело с нулевыми экземплярами заданного числа, которые другие решения не обрабатывают – Dodgie

30

Мой предпочтительным решением использует rle, который будет возвращать значение (метку, x в вашем примере) и длиной, которая представляет сколько раз это значение появилось в последовательности.

Объединив rle с sort, у вас есть чрезвычайно быстрый способ подсчета количества раз, когда появилось какое-либо значение. Это может быть полезно при более сложных проблемах.

Пример:

> numbers <- c(4,23,4,23,5,43,54,56,657,67,67,435,453,435,324,34,456,56,567,65,34,435) 
> a <- rle(sort(numbers)) 
> a 
    Run Length Encoding 
    lengths: int [1:15] 2 1 2 2 1 1 2 1 2 1 ... 
    values : num [1:15] 4 5 23 34 43 54 56 65 67 324 ... 

Если значение, которое вы хотите не отображается, или вам нужно сохранить это значение для последующего использования, сделать adata.frame.

> b <- data.frame(number=a$values, n=a$lengths) 
> b 
    values n 
1  4 2 
2  5 1 
3  23 2 
4  34 2 
5  43 1 
6  54 1 
7  56 2 
8  65 1 
9  67 2 
10 324 1 
11 435 3 
12 453 1 
13 456 1 
14 567 1 
15 657 1 

Я считаю, что это редко, что я хочу знать частоту одного значения и не все значения, и RLE, кажется, самый быстрый способ получить подсчитывать и хранить их все.

+1

Является ли преимущество этого, vs table, результатом его получения в более удобном для использования формате? спасибо –

+0

@HeatherStark Я бы сказал, что есть два преимущества. Во-первых, определенно, что это более удобный формат, чем вывод таблицы. Во-вторых, иногда я хочу подсчитать количество элементов «в строке», а не в пределах всего набора данных. Например, 'c (rep ('A', 3), rep ('G', 4), 'A', rep ('G', 2), rep ('C', 10))' будет возвращать ' значения = c ('A', 'G', 'A', 'G', 'C') 'и' lengths = c (3, 4, 1, 2, 10) ', что иногда полезно. – JBecker

+1

, используя microbenchmark, кажется, что 'table' быстрее' когда вектор длинный' (я пробовал 100000), но немного дольше, когда он короче (я пробовал 1000) – clemlaflemme

30

Существует также count(numbers) от plyr упаковка. Намного удобнее, чем table.

2

Еще один способ я считаю удобным является:

numbers <- c(4,23,4,23,5,43,54,56,657,67,67,435,453,435,324,34,456,56,567,65,34,435) 
(s<-summary (as.factor(numbers))) 

Это преобразует набор данных к фактору, а затем резюме() дает нам контрольные суммы (Графы уникальных значений).

Выход:

4 5 23 34 43 54 56 65 67 324 435 453 456 567 657 
2 1 2 2 1 1 2 1 2 1 3 1 1 1 1 

Это может быть сохранена как dataframe, если предпочтительным.

as.data.frame (cbind (Number = имена (ы), Freq = S), stringsAsFactors = F, row.names = 1: длина (ы))

здесь строки. имена были использованы для переименования имен строк. без использования row.names, имена столбцов в S используются в качестве имен строк в новой dataframe

Выход:

 Number Freq 
1  4 2 
2  5 1 
3  23 2 
4  34 2 
5  43 1 
6  54 1 
7  56 2 
8  65 1 
9  67 2 
10 324 1 
11 435 3 
12 453 1 
13 456 1 
14 567 1 
15 657 1 
2

Используя таблицу, но без сравнения с names:

numbers <- c(4,23,4,23,5,43,54,56,657,67,67,435) 
x <- 67 
numbertable <- table(numbers) 
numbertable[as.character(x)] 
#67 
# 2 

table является полезно, когда вы используете подсчеты разных элементов несколько раз. Если вам нужен только один счет, использовать sum(numbers == x)

6

Если вы хотите, чтобы подсчитать количество появлений впоследствии, вы можете использовать sapply функции:

index<-sapply(1:length(numbers),function(x)sum(numbers[1:x]==numbers[x])) 
cbind(numbers, index) 

Выход:

 numbers index 
[1,]  4  1 
[2,]  23  1 
[3,]  4  2 
[4,]  23  2 
[5,]  5  1 
[6,]  43  1 
[7,]  54  1 
[8,]  56  1 
[9,]  657  1 
[10,]  67  1 
[11,]  67  2 
[12,]  435  1 
[13,]  453  1 
[14,]  435  2 
[15,]  324  1 
[16,]  34  1 
[17,]  456  1 
[18,]  56  2 
[19,]  567  1 
[20,]  65  1 
[21,]  34  2 
[22,]  435  3 
6

You может изменить номер по вашему желанию в следующей строке

length(which(numbers == 4)) 
4
numbers <- c(4,23,4,23,5,43,54,56,657,67,67,435 453,435,324,34,456,56,567,65,34,435) 

> length(grep(435, numbers)) 
[1] 3 


> length(which(435 == numbers)) 
[1] 3 


> require(plyr) 
> df = count(numbers) 
> df[df$x == 435, ] 
    x freq 
11 435 3 


> sum(435 == numbers) 
[1] 3 


> sum(grepl(435, numbers)) 
[1] 3 


> sum(435 == numbers) 
[1] 3 


> tabulate(numbers)[435] 
[1] 3 


> table(numbers)['435'] 
435 
    3 


> length(subset(numbers, numbers=='435')) 
[1] 3 

 Смежные вопросы

  • Нет связанных вопросов^_^