2013-09-05 67 views
11

Tôi có dữ liệu bảng điều khiển (chủ đề/năm) mà tôi muốn chỉ giữ các đối tượng xuất hiện số lần tối đa mỗi năm. Tập dữ liệu lớn nên tôi đang sử dụng gói data.table. Có một giải pháp thanh lịch hơn những gì tôi đã thử dưới đây?Dữ liệu R.tệ số đếm số

library(data.table) 

DT <- data.table(SUBJECT=c(rep('John',3), rep('Paul',2), 
          rep('George',3), rep('Ringo',2), 
          rep('John',2), rep('Paul',4), 
          rep('George',2), rep('Ringo',4)), 
       YEAR=c(rep(2011,10), rep(2012,12)), 
       HEIGHT=rnorm(22), 
       WEIGHT=rnorm(22)) 
DT 

DT[, COUNT := .N, by='SUBJECT,YEAR'] 
DT[, MAXCOUNT := max(COUNT), by='YEAR'] 

DT <- DT[COUNT==MAXCOUNT] 
DT <- DT[, c('COUNT','MAXCOUNT') := NULL] 
DT 
+0

Vì vậy, về cơ bản bạn muốn có dữ liệu. Có thể với tất cả dữ liệu từ năm giàu dữ liệu nhất cho mỗi lần đánh bại? –

+0

Hãy suy nghĩ về nó, nó sẽ được tốt đẹp nếu 'data.table' có một số' cùng 'khả năng trong biểu thức' i' như trong các biểu thức 'j'. –

Trả lời

14

Tôi không chắc chắn bạn sẽ xem điều này như nhã nhưng làm thế nào về:

DT[, COUNT := .N, by='SUBJECT,YEAR'] 
DT[, .SD[COUNT == max(COUNT)], by='YEAR'] 

Đó là về cơ bản làm thế nào để áp dụng by để biểu thức i như @SenorO nhận xét. Bạn vẫn sẽ cần [,COUNT:=NULL] sau đó nhưng đối với một cột tạm thời thay vì hai.

Chúng tôi không khuyến khích .SD mặc dù vì lý do tốc độ, nhưng hy vọng chúng tôi sẽ sớm yêu cầu tính năng này để lời khuyên có thể bị xóa: FR#2330 Optimize .SD[i] query to keep the elegance but make it faster unchanged..

Cách tiếp cận khác như sau. Nó nhanh hơn và thành ngữ nhưng có thể được coi là ít thanh lịch hơn.

# Create a small aggregate table first. No need to use := on the big table. 
i = DT[, .N, by='SUBJECT,YEAR'] 

# Find the even smaller subset. (Do as much as we can on the small aggregate.) 
i = i[, .SD[N==max(N)], by=YEAR] 

# Finally join the small subset of key values to the big table 
setkey(DT, YEAR, SUBJECT) 
DT[i] 

Điều gì đó tương tự là here.