2011-10-11 29 views
7

Tôi đã gặp phải một ứng dụng mà tôi cần phải sắp xếp dữ liệu. Khung theo số cột và không ai trong số usual solutions dường như cho phép điều đó.Đặt hàng trên một danh sách

Ngữ cảnh đang tạo phương thức as.data.frame.by. Vì đối tượng by sẽ có cột cuối cùng làm cột giá trị và cột ncol-1 đầu tiên làm cột chỉ mục. melt trả về nó được sắp xếp ngược - chỉ số 3, sau đó chỉ mục 2, sau đó chỉ mục 1. Để tương thích với latex.table.by Tôi muốn sắp xếp nó chuyển tiếp. Nhưng tôi đang gặp khó khăn khi làm điều đó một cách đầy đủ. Dòng nhận xét trong chức năng dưới đây là nỗ lực tốt nhất của tôi cho đến nay.

as.data.frame.by <- function(x, colnames=paste("IDX",seq(length(dim(x))),sep=""), ...) { 
    num.by.vars <- length(dim(x)) 
    res <- melt(unclass(x)) 
    res <- na.omit(res) 
    colnames(res)[seq(num.by.vars)] <- colnames 
    #res <- res[ order(res[ , seq(num.by.vars)]) , ] # Sort the results by the by vars in the heirarchy given 
    res 
} 

dat <- transform(ChickWeight, Time=cut(Time,3), Chick=cut(as.numeric(Chick),3)) 
my.by <- by(dat, with(dat,list(Time,Chick,Diet)), function(x) sum(x$weight)) 
> as.data.frame(my.by) 
      IDX1   IDX2 IDX3 value 
1 (-0.021,6.99] (0.951,17.3] 1 3475 
2  (6.99,14] (0.951,17.3] 1 5969 
3  (14,21] (0.951,17.3] 1 8002 
4 (-0.021,6.99] (17.3,33.7] 1 640 
5  (6.99,14] (17.3,33.7] 1 1596 
6  (14,21] (17.3,33.7] 1 2900 
13 (-0.021,6.99] (17.3,33.7] 2 2253 
14  (6.99,14] (17.3,33.7] 2 4734 
15  (14,21] (17.3,33.7] 2 7727 
22 (-0.021,6.99] (17.3,33.7] 3 666 
23  (6.99,14] (17.3,33.7] 3 1391 
24  (14,21] (17.3,33.7] 3 2109 
25 (-0.021,6.99] (33.7,50] 3 1647 
26  (6.99,14] (33.7,50] 3 3853 
27  (14,21] (33.7,50] 3 7488 
34 (-0.021,6.99] (33.7,50] 4 2412 
35  (6.99,14] (33.7,50] 4 5448 
36  (14,21] (33.7,50] 4 8101 

Với dòng chưa được chú giải, nó trả về vô nghĩa (nó chỉ xử lý toàn bộ dữ liệu.như véc tơ, với kết quả tai hại).

Tôi thậm chí đã thử các công cụ thông minh như res <- res[ order(...=list(res[,1],res[,2])) , ] nhưng vô ích.

Tôi nghi ngờ có một cách đơn giản để thực hiện việc này, nhưng tôi không thấy nó.

Chỉnh sửa để làm rõ: Tôi không muốn chỉ định tên cột. Thay vào đó, tôi muốn có thể sắp xếp nó theo một vectơ số (ví dụ: sắp xếp theo các cột 1: 4).

Trả lời

7
mydf <- as.data.frame(my.by) 
mydf[order(mydf$IDX3, mydf$IDX2, mydf$IDX1) , ] 
      IDX1   IDX2 IDX3 value 
1 (-0.021,6.99] (0.951,17.3] 1 3475 
3  (14,21] (0.951,17.3] 1 8002 
2  (6.99,14] (0.951,17.3] 1 5969 
4 (-0.021,6.99] (17.3,33.7] 1 640 
6  (14,21] (17.3,33.7] 1 2900 
5  (6.99,14] (17.3,33.7] 1 1596 
13 (-0.021,6.99] (17.3,33.7] 2 2253 
15  (14,21] (17.3,33.7] 2 7727 
14  (6.99,14] (17.3,33.7] 2 4734 
22 (-0.021,6.99] (17.3,33.7] 3 666 
24  (14,21] (17.3,33.7] 3 2109 
23  (6.99,14] (17.3,33.7] 3 1391 
25 (-0.021,6.99] (33.7,50] 3 1647 
27  (14,21] (33.7,50] 3 7488 
26  (6.99,14] (33.7,50] 3 3853 
34 (-0.021,6.99] (33.7,50] 4 2412 
36  (14,21] (33.7,50] 4 8101 
35  (6.99,14] (33.7,50] 4 5448 

Hoặc;

my.by <- by(dat, with(dat,list(Diet,Chick, Time)), function(x) sum(x$weight)) 
mydf <- as.data.frame(my.by) 

EDIT: Hoặc này tạo ra cùng một sản lượng như lên hàng đầu sử dụng chỉ số cột số:

mydf <- as.data.frame(my.by) 
mydf[ do.call(order, mydf[, 3:1]) , ] 
+0

Xin lỗi cần phải có được rõ ràng hơn: Tôi muốn không phải chỉ rõ tên cột. Thay vào đó, tôi muốn có thể sắp xếp nó theo một vectơ số (ví dụ: sắp xếp theo các cột 1: 4). –

+0

Xem ở trên. Phương thức do.call truyền các dataframes tới 'order' được minh họa trên trang' help (order) '. –

+0

Rất đẹp. Cảm ơn. Tôi cần phải nhìn kỹ hơn vào 'do.call', vì tôi nghi ngờ nó sẽ giải quyết được nhiều vấn đề của tôi :-) –

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