2013-01-23 19 views
8

Sử dụng gói data.table, có thể tóm tắt kết hợp bảo tồn dữ liệu của các biến không xuất hiện trong đầu vào không?Làm cách nào để giữ lại các kết hợp của các biến không xuất hiện trong dữ liệu đầu vào khi nhóm với dữ liệu.table?

Với plyr gói Tôi biết làm thế nào để làm điều này với lập luận .drop, ví dụ:

require(plyr) 
df <- data.frame(categories = c(rep("A",3), rep("B",3), rep("C",3)), groups = c(rep(c("X", "Y"),4), "Z"), values = rep(1, 9)) 

df1 <- ddply(df, c("categories","groups"), .drop = F, summarise, sum = sum(values)) 

đầu ra:

categories groups sum 
1   A  X 2 
2   A  Y 1 
3   A  Z 0 
4   B  X 1 
5   B  Y 2 
6   B  Z 0 
7   C  X 1 
8   C  Y 1 
9   C  Z 1 

Trong trường hợp này tôi duy trì tất cả các nhóm/loại kết hợp ngay cả khi tổng của nó là 0.

Trả lời

8

Câu hỏi hay. Dưới đây là hai cách. Cả hai đều sử dụng bằng cách không có.

DT = as.data.table(df) 
setkey(DT,categories,groups) 
DT[CJ(unique(categories),unique(groups)), sum(values,na.rm=TRUE)] 

    categories groups V1 
1:   A  X 2 
2:   A  Y 1 
3:   A  Z 0 
4:   B  X 1 
5:   B  Y 2 
6:   B  Z 0 
7:   C  X 1 
8:   C  Y 1 
9:   C  Z 1 

nơi CJ đứng cho Cross Tham gia, xem ?CJ. by-without-by chỉ có nghĩa là j được thực hiện trên mỗi nhóm mà mỗi hàng của i tham gia.

Được thừa nhận có vẻ khó khăn trong tầm nhìn đầu tiên. Ý tưởng là nếu bạn có một tập hợp con được biết của các nhóm, cú pháp này nhanh hơn so với nhóm tất cả mọi thứ và sau đó chỉ chọn kết quả từ đó bạn cần. Nhưng trong trường hợp này, bạn sẽ thích mọi thứ, vì vậy không có nhiều lợi thế, ngoài việc có thể tra cứu các nhóm không tồn tại trong dữ liệu (mà bạn không thể làm với by).

Một cách khác là để by đầu tiên như bình thường, sau đó tham gia các CJ() kết quả cho rằng:

DT[,sum(values),keyby='categories,groups'][CJ(unique(categories),unique(groups))] 
    categories groups V1 
1:   A  X 2 
2:   A  Y 1 
3:   A  Z NA 
4:   B  X 1 
5:   B  Y 2 
6:   B  Z NA 
7:   C  X 1 
8:   C  Y 1 
9:   C  Z 1 

nhưng sau đó bạn sẽ có được NA thay vì 0. mong muốn Những thể được thay thế bằng set() nếu cần thiết. Cách thứ hai có thể nhanh hơn vì hai cuộc gọi unique được cung cấp đầu vào nhỏ hơn nhiều.

Cả hai phương pháp đều có thể được bao bọc thành các hàm trợ giúp nhỏ nếu bạn thực hiện điều này rất nhiều.

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