2014-11-07 15 views
5

Tôi đã rất sốc bởi sự mượt mà của gói dplyr trong xử lý dữ liệu kiểu dòng chảy. Gần đây tôi đổ xô vào một vấn đề để tạo ra một khung dữ liệu mới cho mỗi ID nhóm và kết hợp các khung dữ liệu nhỏ đó vào một khung dữ liệu lớn hơn cuối cùng. Một ví dụ đồ chơi:Làm thế nào dplyr có thể tạo khung dữ liệu cho mỗi nhóm sau khi hoạt động group_by?

input.data.frame %>% 
    group_by(gid) %>% 
    {some operation to generate a new data frame for each group} ## FAILED!!!! 

Trong dplyr, hàm mutate thêm cột mới cho từng nhóm và summarise tóm tắt phát cho mỗi nhóm, cả hai đều không thể thực hiện yêu cầu của tôi. (Ý của tôi bỏ lỡ một cái gì đó?)

Ngoài ra, sử dụng ddply của gói plyr, các interation trước của dplyr, tôi có thể làm cho nó qua

ddply(input.data.frame, .(gid), function(x) { 
    some operation to generate a new data frame for each group 
} 

Nhưng sự thiếu hụt một số funcs trong dplyr sẽ được chèn thêm từ availableness khi tôi tải gói plyr.

+2

Bạn phải sử dụng toán tử 'do' trong trường hợp này. Tuy nhiên, sẽ tốt hơn nếu bạn cho chúng tôi thấy những gì bạn thực sự muốn làm/đạt được cuối cùng. Từ tệp trợ giúp: "Bạn có thể sử dụng để thực hiện tính toán tùy ý, trả về khung dữ liệu hoặc các đối tượng tùy ý sẽ được lưu trữ trong danh sách". –

+0

Giới thiệu tuyệt vời "Tôi đã rất sốc bởi sự mượt mà của gói dplyr trong xử lý dữ liệu kiểu dòng chảy." :) –

+1

Và bằng cách này, nếu bạn tải cả hai gói (plyr và dplyr), đề xuất là tải plyr trước và sau đó dplyr, do đó, gói "chuẩn" cho ví dụ: "tóm tắt" sẽ là dplyr, nhưng nếu bạn cần nó từ plyr, chỉ cần sử dụng 'plyr :: summaryise' để làm cho các gói rõ ràng. –

Trả lời

3

Biến nhận xét của tôi thành câu trả lời ..

Có, dplyr cung cấp cách tạo dữ liệu.frames cho mỗi nhóm. Sử dụng toán tử do trên một data.frame/tbl được nhóm lại sẽ cho phép bạn thực hiện điều này, chính xác hơn, nó cho phép bạn áp dụng các hàm tùy ý cho mỗi nhóm. Đây là tài liệu trong file trợ giúp cho do:

[...] Bạn có thể sử dụng làm gì để thực hiện tính toán tùy ý, trở về hoặc là một khung dữ liệu hoặc đối tượng tùy ý mà sẽ được lưu trữ trong một danh sách. này đặc biệt hữu ích khi làm việc với các mô hình: bạn có thể phù hợp với các mô hình cho mỗi nhóm có làm và sau đó linh hoạt trích xuất các thành phần bằng cách một công cụ khác hoặc tóm tắt.

Kinh nghiệm của tôi cho đến nay là bất cứ khi nào người ta có thể sử dụng một trong các chức năng dplyr chuyên ngành như đột biến/tóm tắt/mutate_each/vv, họ nên được ưa thích hơn do, vì họ thường có hiệu quả hơn việc sử dụng của do, nhưng tất nhiên là không linh hoạt.

+4

Bạn có thể vui lòng cung cấp câu trả lời cho câu hỏi của bạn sẽ hiển thị đoạn mã về cách sử dụng để thực hiện việc này không?Cảm ơn – MartinT

+0

@ user2731872, chỉ cần xem phần ví dụ được cung cấp trong trang trợ giúp của '? Do'. Hoặc cung cấp một ví dụ tối thiểu về vấn đề của bạn, nhưng sau đó sẽ tốt hơn nếu bạn hỏi một câu hỏi mới –

+0

Cảm ơn - Tôi đã làm và tôi không còn khôn ngoan hơn. Kết quả của các ví dụ cho thấy kết quả trong một grouped_df, không phải trong một danh sách các khung dữ liệu, đó là câu hỏi ban đầu ở đây, tôi nghĩ: 'by_cyl <- group_by (mtcars, cyl); do (by_cyl, head (., 2)) 'kết quả trong một nhóm df. Tôi muốn một danh sách các dfs. Tôi đã hỏi câu hỏi ở đây ngay bây giờ: [link] (http://stackoverflow.com/questions/33775239/emulate-split-with-dplyr-group-by-return-a-list-of-data-frames) – MartinT

6

Dưới đây là ví dụ sau câu trả lời của G. Grothendieck cho một câu hỏi tương tự. Adding rows in `dplyr` output

Trước tiên, chúng tôi tạo khung dữ liệu với x và g. Có 9 số ngẫu nhiên trong x và 3 nhóm a, b, c trong g. Chúng tôi muốn chọn 2 số lớn nhất từ ​​mỗi nhóm. Điều quan trọng cần nhớ là yêu cầu một khung dữ liệu làm giá trị trả về.

library(dplyr) 
set.seed(1) 
dat <- data.frame(x=runif(9),g=rep(letters[1:3],each=3)) 

dat 
     x g 
1 0.1765568 a 
2 0.6870228 a 
3 0.3841037 a 
4 0.7698414 b 
5 0.4976992 b 
6 0.7176185 b 
7 0.9919061 c 
8 0.3800352 c 
9 0.7774452 c 

## this works 
dat %>% dplyr::group_by(g) %>% do(data.frame(x=tail(sort(.$x),2))) 

## this works too 
dat %>% dplyr::group_by(g) %>% do(.[tail(order(.$x),2),]) 

      x  g 
     (dbl) (fctr) 
1 0.3841037  a 
2 0.6870228  a 
3 0.7176185  b 
4 0.7698414  b 
5 0.7774452  c 
6 0.9919061  c 

## no error, but x is treated as a 1x1 data frame 
dat %>% dplyr::group_by(g) %>% do(x=tail(sort(.$x),2)) 
     g  x 
    (fctr) (chr) 
1  a <dbl[2]> 
2  b <dbl[2]> 
3  c <dbl[2]> 

## you need a function to do more complicated stuff 
top2x <- function(df) { df[tail(order(df$x),2),] } 
dat %>% dplyr::group_by(g) %>% do(top2x(.)) 
+0

đây là một lời giải thích thực sự tốt 1 – Dan

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