2009-12-17 67 views

Trả lời

356

Bạn có thể chỉ cần sử dụng 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 

Sau đó, bạn có thể tập hợp con nó:

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

Hoặc chuyển đổi nó thành một data.frame nếu bạn cảm thấy thoải mái hơn khi làm việc với điều đó:

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

Đừng quên các vấn đề về dấu phẩy động tiềm ẩn, đặc biệt là với bảng, trong đó ép buộc các số thành chuỗi. – hadley

+3

Đó là một điểm tuyệt vời. Đây là tất cả các số nguyên, vì vậy nó không phải là một vấn đề thực sự trong ví dụ này, phải không? – Shane

+0

không chính xác. Các phần tử của bảng là lớp số nguyên lớp (bảng (số) [1]), nhưng 435 là một số dấu phẩy động. Để làm cho nó trở thành một số nguyên, bạn có thể sử dụng 435L. –

8

đây là một cách nhanh chóng và bẩn thỉu:

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

tôi có lẽ sẽ làm một cái gì đó như thế này

length(which(numbers==x)) 

Nhưng thực sự, một cách tốt hơn là

table(numbers) 
+10

'bảng (số)' sẽ thực hiện nhiều công việc hơn giải pháp đơn giản nhất, 'tổng (số == x) ', bởi vì nó sẽ tính toán số lượng của tất cả các số khác trong danh sách. –

+1

vấn đề với bảng là khó đưa nó vào bên trong phép tính phức tạp hơn, ví dụ sử dụng apply() trên dataframes – skan

205

Cách trực tiếp nhất là sum(numbers == x).

numbers == x tạo ra một vector logic là TRUE ở mọi vị trí đó x xảy ra, và khi sum ing, vector logic được cưỡng chế số mà chuyển đổi TRUE để 1 và FALSE để 0.

Tuy nhiên, lưu ý rằng đối các số dấu phẩy động, tốt hơn là sử dụng một số thứ như: sum(abs(numbers - x) < 1e-6).

+1

điểm tốt về vấn đề dấu chấm động. Điều đó cắn mông của tôi nhiều hơn tôi thường muốn thừa nhận. –

+3

@ Jason trong khi nó trả lời câu hỏi trực tiếp, tôi đoán là mọi người thích giải pháp tổng quát hơn cung cấp câu trả lời cho tất cả 'x' trong dữ liệu chứ không phải là giá trị đã biết cụ thể của' x'. Công bằng, đó là câu hỏi ban đầu. Như tôi đã nói trong câu trả lời dưới đây, "Tôi thấy hiếm khi tôi muốn biết tần số của một giá trị và không phải tất cả các giá trị ..." – JBecker

16

Có một chức năng tiêu chuẩn trong R cho rằng

tabulate(numbers)

+0

Điểm bất lợi của 'tabulate' là bạn không thể xử lý bằng 0 và số âm. – omar

+1

Nhưng bạn có thể đối phó với số không của một số cho sẵn, mà các giải pháp khác không xử lý – Dodgie

30

giải pháp ưa thích của tôi sử dụng rle, mà sẽ trả về một giá trị (nhãn, x trong ví dụ của bạn) và chiều dài, đại diện cho bao nhiêu lần giá trị xuất hiện theo thứ tự.

Bằng cách kết hợp rle với sort, bạn có cách cực nhanh để đếm số lần bất kỳ giá trị nào xuất hiện. Điều này có thể hữu ích với các vấn đề phức tạp hơn.

Ví dụ:

> 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 ... 

Nếu giá trị mà bạn muốn không hiển thị, hoặc bạn cần phải lưu trữ giá trị đó cho sau này, làm cho a một data.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 

Tôi hiếm khi biết tần suất của một giá trị và không phải tất cả giá trị, và rle có vẻ là cách nhanh nhất để đếm và lưu trữ tất cả.

+1

Lợi thế của điều này, so với bảng, rằng nó cho kết quả trong một định dạng dễ sử dụng hơn? cảm ơn –

+0

@HeatherStark Tôi sẽ nói có hai ưu điểm. Đầu tiên là chắc chắn rằng nó là một định dạng dễ sử dụng hơn so với đầu ra bảng. Thứ hai là đôi khi tôi muốn đếm số lượng các phần tử "liên tiếp" thay vì trong toàn bộ tập dữ liệu. Ví dụ, 'c (rep ('A', 3), đại diện ('G', 4), 'A', đại diện ('G', 2), đại diện ('C', 10))' sẽ trả về ' values ​​= c ('A', 'G', 'A', 'G', 'C') 'và' độ dài = c (3, 4, 1, 2, 10) 'đôi khi hữu ích. – JBecker

+1

sử dụng microbenchmark, có vẻ như 'bảng' là nhanh hơn' khi vectơ dài' (tôi đã thử 100000) nhưng hơi dài hơn khi nó ngắn hơn (tôi đã thử 1000) – clemlaflemme

30

Ngoài ra còn có count(numbers) từ gói plyr. Thuận tiện hơn nhiều so với table theo ý kiến ​​của tôi.

2

hơn Một cách tôi thấy thuận tiện là:

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))) 

này chuyển đổi dữ liệu đến yếu tố, và sau đó tóm tắt() cho chúng ta những tổng số kiểm soát (tội danh các giá trị duy nhất).

Output là:

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 

này có thể được lưu trữ như dataframe nếu ưa thích.

as.data.frame (cbind (Số = tên (s), Freq = s), stringsAsFactors = F, row.names = 1: length (s))

đây liên tiếp. tên đã được sử dụng để đổi tên tên hàng. mà không sử dụng row.names, tên cột trong s được sử dụng như tên hàng trong dataframe mới

Output là:

 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

Sử dụng bảng nhưng không có so sánh với 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 là hữu ích khi bạn đang sử dụng số lượng các yếu tố khác nhau nhiều lần. Nếu bạn chỉ cần một số, sử dụng sum(numbers == x)

6

Nếu bạn muốn đếm số lần xuất hiện sau đó, bạn có thể tận dụng các sapply chức năng:

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

Output:

 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

Bạn có thể thay đổi số thành bất kỳ thứ gì bạn muốn trong dòng sau

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 
Các vấn đề liên quan