2013-05-15 35 views
44

Giả sử tôi có một bảng dữ liệu chứa một số cầu thủ bóng chày:tập hợp con của nhóm với data.table

library(plyr) 
library(data.table) 

bdt <- as.data.table(baseball) 

Đối với mỗi người chơi (do id), tôi muốn tìm các hàng tương ứng với năm, trong đó họ chơi nhiều trò chơi nhất. Điều này rất đơn giản trong plyr:

ddply(baseball, "id", subset, g == max(g)) 

Mã tương đương cho dữ liệu là gì?

tôi đã cố gắng:

setkey(bdt, "id") 
bdt[g == max(g)] # only one row 
bdt[g == max(g), by = id] # Error: 'by' or 'keyby' is supplied but not j 
bdt[, .SD[g == max(g)]] # only one row 

này hoạt động:

bdt[, .SD[g == max(g)], by = id] 

Nhưng nó là nhanh hơn so với plyr chỉ có 30%, cho thấy nó có lẽ không phải thành ngữ.

+2

Ồ, chậm, nhưng nếu bạn sử dụng "năm" thay cho ".SD" ... tôi nhận được 0,01, 1,58, 2,39 thời gian của người dùng trong năm, .SD, plyr, tương ứng. – Frank

+0

@Frank nhưng tôi muốn toàn bộ khung dữ liệu, không chỉ trong năm. Tôi sẽ làm rõ câu hỏi. – hadley

Trả lời

51

Đây là nhanh data.table cách:

bdt[bdt[, .I[g == max(g)], by = id]$V1] 

Điều này tránh xây dựng .SD, đó là nút cổ chai trong các biểu thức của bạn.

chỉnh sửa: Trên thực tế, lý do chính OP là chậm không chỉ là nó có .SD trong nó, nhưng thực tế là nó sử dụng nó trong một cách đặc biệt - bằng cách gọi [.data.table, mà tại thời điểm này có một khổng lồ trên không, do đó, chạy nó trong một vòng lặp (khi một không by) tích lũy một hình phạt rất lớn.

+4

+1 Tôi cá rằng Hadley muốn thực hiện điều này một cách có lập trình, trong trường hợp đó anh ta muốn sử dụng cú pháp này, 'bdt [bdt [, .I [g == max (g)], bởi = id] [, V1]] 'đúng không? – joran

+0

@joran Tôi đang xây dựng cuộc gọi theo cách thủ công, vì vậy nó không thực sự quan trọng – hadley

+4

@hadley Rõ ràng, tôi không nên đặt cược. :) – joran

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