2015-06-19 19 views
5

Tôi có một data.table như:R data.table: nhóm trọng phần trăm của nhóm

library(data.table) 
widgets <- data.table(serial_no=1:100, 
         color=rep_len(c("red","green","blue","black"),length.out=100), 
         style=rep_len(c("round","pointy","flat"),length.out=100), 
         weight=rep_len(1:5,length.out=100)) 

Mặc dù tôi không chắc chắn đây là data.table cách mà hầu hết, tôi có thể tính toán tần số phân nhóm theo nhóm sử dụng tablelength trong một bước-- ví dụ, để trả lời câu hỏi "Phần trăm vật dụng màu đỏ là gì?"

chỉnh sửa: mã này không cung cấp câu trả lời đúng

# example A 
widgets[, list(style = unique(style), 
       style_pct_of_color_by_count = 
       as.numeric(table(style)/length(style))), by=color] 

# color style style_pct_of_color_by_count 
# 1: red round      0.32 
# 2: red pointy      0.32 
# 3: red flat      0.36 
# 4: green pointy      0.32 
# ... 

Nhưng tôi không thể sử dụng phương pháp đó để trả lời những câu hỏi như "Bằng cách cân, bao nhiêu phần trăm của các widget đỏ có hình tròn?" Tôi chỉ có thể đưa ra một cách tiếp cận hai bước:

# example B 
widgets[,list(cs_weight=sum(weight)),by=list(color,style)][,list(style, style_pct_of_color_by_weight=cs_weight/sum(cs_weight)),by=color] 

# color style style_pct_of_color_by_weight 
# 1: red round     0.3466667 
# 2: red pointy     0.3466667 
# 3: red flat     0.3066667 
# 4: green pointy     0.3333333 
# ... 

Tôi đang tìm kiếm một phương pháp duy nhất bước đến B, và A nếu có thể làm tốt thêm, trong một lời giải thích rằng đào sâu sự hiểu biết của tôi về data.table cú pháp cho by- hoạt động nhóm. Xin lưu ý rằng câu hỏi này khác với Weighted sum of variables by groups with data.table vì tôi liên quan đến các nhóm con và tránh nhiều bước. TYVM.

+0

Nhìn vào phản hồi từ @Frank dưới đây tôi nhận thấy rằng nỗ lực của tôi A không chỉ là vụng về nhưng không chính xác - ví dụ, tôi đã kiểm tra 'widget [, sum (style == "round" & color == "red")/sum (color == "red")] # 0.36' – C8H10N4O2

Trả lời

7

này gần như là một bước duy nhất:

# A 
widgets[,{ 
    totwt = .N 
    .SD[,.(frac=.N/totwt),by=style] 
},by=color] 
    # color style frac 
# 1: red round 0.36 
# 2: red pointy 0.32 
# 3: red flat 0.32 
# 4: green pointy 0.36 
# 5: green flat 0.32 
# 6: green round 0.32 
# 7: blue flat 0.36 
# 8: blue round 0.32 
# 9: blue pointy 0.32 
# 10: black round 0.36 
# 11: black pointy 0.32 
# 12: black flat 0.32 

# B 
widgets[,{ 
    totwt = sum(weight) 
    .SD[,.(frac=sum(weight)/totwt),by=style] 
},by=color] 
# color style  frac 
# 1: red round 0.3466667 
# 2: red pointy 0.3466667 
# 3: red flat 0.3066667 
# 4: green pointy 0.3333333 
# 5: green flat 0.3200000 
# 6: green round 0.3466667 
# 7: blue flat 0.3866667 
# 8: blue round 0.2933333 
# 9: blue pointy 0.3200000 
# 10: black round 0.3733333 
# 11: black pointy 0.3333333 
# 12: black flat 0.2933333 

Làm thế nào nó hoạt động: Xây dựng mẫu cho nhóm cấp cao nhất (color) trước khi chuyển sang nhóm mịn (color với style) để lập bảng.


Lựa chọn thay thế. Nếu style s lặp lại trong mỗi color và điều này chỉ dành cho mục đích hiển thị, hãy thử một table:

# A 
widgets[, 
    prop.table(table(color,style),1) 
] 
#  style 
# color flat pointy round 
# black 0.32 0.32 0.36 
# blue 0.36 0.32 0.32 
# green 0.32 0.36 0.32 
# red 0.32 0.32 0.36 

# B 
widgets[,rep(1L,sum(weight)),by=.(color,style)][, 
    prop.table(table(color,style),1) 
] 

#  style 
# color  flat pointy  round 
# black 0.2933333 0.3333333 0.3733333 
# blue 0.3866667 0.3200000 0.2933333 
# green 0.3200000 0.3333333 0.3466667 
# red 0.3066667 0.3466667 0.3466667 

Đối với B, điều này mở rộng dữ liệu để có một quan sát cho mỗi đơn vị trọng lượng. Với dữ liệu lớn, việc mở rộng như vậy sẽ là một ý tưởng tồi (vì nó tốn quá nhiều bộ nhớ). Ngoài ra, weight phải là số nguyên; nếu không, tổng của nó sẽ được cắt bớt âm thầm thành một (ví dụ: thử rep(1,2.5) # [1] 1 1).

+0

Đây là những gì tôi làm, nhưng tôi cũng muốn tìm cách tốt hơn. – Frank

+1

Cảm ơn @Frank - nó sẽ đưa tôi một thời gian để grok ký hiệu chấm và các bài tập nhúng, nhưng đây là một cách tiếp cận tuyệt vời. – C8H10N4O2

+1

Phiên bản đầu tiên của bạn có thể được viết lại mà không có biến temp như sau: 'widgets [,. (Frac = .SD [, .N, by = style] $ N/.N), bởi = color]' – Arun

0

nó có thể là một ý tưởng tốt để sử dụng dplyr

df <- widgets %>% 
    group_by(color, style) %>% 
    summarise(count = n()) %>% 
    mutate(freq = count/sum(count)) 

df2 <- widgets %>% 
    group_by(color, style) %>% 
    summarise(count_w = sum(weight)) %>% 
    mutate(freq = count_w/sum(count_w)) 
+0

Cảm ơn @ drsh1 Tôi đánh giá cao rằng 'dplyr' là trực quan và hữu ích ở đây. Câu hỏi của tôi đặc biệt là cách sử dụng cú pháp 'data.table'. – C8H10N4O2

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