2015-09-04 24 views
7

Tôi muốn nhóm dữ liệu.table dựa trên giá trị của một cột giá trị, làm cách nào tôi có thể thực hiện việc này với thư viện dplyr?Làm cách nào để nhóm phạm vi trên một cột bằng cách sử dụng dplyr?

Ví dụ, bảng dữ liệu của tôi là như dưới đây:

library(data.table) 
library(dplyr) 
DT <- data.table(A=1:100, B=runif(100), Amount=runif(100, 0, 100)) 

Bây giờ tôi muốn nhóm DT thành 20 nhóm tại 0,05 khoảng thời gian cột B, và đếm có bao nhiêu hàng trong mỗi nhóm. ví dụ: bất kỳ hàng nào có giá trị cột B trong phạm vi [0, 0,05) sẽ tạo thành một nhóm; bất kỳ hàng nào có giá trị cột B trong phạm vi [0,05, 0,1) sẽ tạo thành một nhóm khác, v.v. Có cách nào hiệu quả để thực hiện chức năng nhóm này không?

Cảm ơn bạn rất nhiều.

----------------------------- Câu hỏi khác về câu trả lời của akrun. Cảm ơn akrun cho câu trả lời của bạn. Tôi có một câu hỏi mới về chức năng "cắt". Nếu DT của tôi là như dưới đây:

DT <- data.table(A=1:10, B=c(0.01, 0.04, 0.06, 0.09, 0.1, 0.13, 0.14, 0.15, 0.17, 0.71)) 

bằng cách sử dụng đoạn mã sau:

DT %>% 
    group_by(gr=cut(B, breaks= seq(0, 1, by = 0.05), right=F)) %>% 
    summarise(n= n()) %>% 
    arrange(as.numeric(gr)) 

tôi mong đợi để xem kết quả như thế này:

  gr n 
1 [0,0.05) 2 
2 [0.05,0.1) 2 
3 [0.1,0.15) 3 
4 [0.15,0.2) 2 
5 [0.7,0.75) 1 

nhưng kết quả tôi nhận được là như thế này :

  gr n 
1 [0,0.05) 2 
2 [0.05,0.1) 2 
3 [0.1,0.15) 4 
4 [0.15,0.2) 1 
5 [0.7,0.75) 1 

Dường như t giá trị 0,15 không được phân bổ chính xác. Bất kỳ suy nghĩ về điều này?

+0

Bạn có thể sử dụng 'cut' – akrun

+0

Nếu đối tượng ban đầu là dữ liệu. Có thể sử dụng phương thức data.table' DT [,. N,. (Gr = cut (B, breaks = seq (0, max (B), by = 0,05)))] ' – akrun

+0

Fyi, rất hay khi sử dụng' set.seed' khi tạo dữ liệu ví dụ ngẫu nhiên, để tất cả chúng ta đều nhìn vào cùng một dữ liệu. – Frank

Trả lời

13

Chúng tôi có thể sử dụng cut để thực hiện việc nhóm. Chúng tôi tạo cột 'gr' trong group_by, sử dụng summarise để tạo số phần tử trong mỗi nhóm (n()) và đặt hàng đầu ra (arrange) dựa trên 'gr'.

library(dplyr) 
DT %>% 
    group_by(gr=cut(B, breaks= seq(0, 1, by = 0.05))) %>% 
    summarise(n= n()) %>% 
    arrange(as.numeric(gr)) 

Như các đối tượng ban đầu là data.table, điều này có thể được thực hiện bằng data.table phương pháp (bao gồm @ đề nghị Frank sử dụng keyby)

library(data.table) 
DT[,.N , keyby = .(gr=cut(B, breaks=seq(0, 1, by=0.05)))] 

EDIT:

Dựa trên các bản cập nhật trong bài đăng của OP, chúng tôi có thể trừ một số nhỏ vào seq

lvls <- levels(cut(DT$B, seq(0, 1, by =0.05))) 
DT %>% 
    group_by(gr=cut(B, breaks= seq(0, 1, by = 0.05) - 
       .Machine$double.eps, right=FALSE, labels=lvls)) %>% 
    summarise(n=n()) %>% 
    arrange(as.numeric(gr)) 
#   gr n 
#1 (0,0.05] 2 
#2 (0.05,0.1] 2 
#3 (0.1,0.15] 3 
#4 (0.15,0.2] 2 
#5 (0.7,0.75] 1 
+1

@Frank Cảm ơn, tôi đã sửa đổi nó. – akrun

+0

Hi akrun, tôi thêm câu hỏi mới trong bài đăng này vì nó là một phần của vấn đề của tôi. Một khi điều này được giải quyết, tôi sẽ chấp nhận giải pháp. Cảm ơn. – Carter

+0

@Carter Cảm ơn, tôi nghĩ bạn đã hỏi một câu hỏi hoàn toàn mới. – akrun

Các vấn đề liên quan