2017-11-30 22 views
6

Tôi đang cố gắng tạo một số ô riêng lẻ từ cùng một data.frame với thứ tự khác nhau của các mức hệ số trên trục y cho mỗi ô. Mỗi cốt truyện được cho là sắp xếp các mức yếu tố trên y giảm dần.R: sắp xếp lại các mức hệ số cho một số ô riêng lẻ

Tôi biết rằng điều này có thể được thực hiện theo cách thủ công cho từng ô nhưng tôi đang tìm kiếm một cách hiệu quả và thanh lịch hơn vì tôi sẽ có khá nhiều ô mà tôi cần tạo. Điều này không phải bao gồm việc sử dụng facet_wrap, nếu có một cách khác, có thể với các vòng vv?

library(ggplot2) 
library(dplyr) 
data("diamonds") 

Lấy tập hợp dữ liệu và tổng hợp bởi hai mức yếu tố (rõ ràng và cắt):

means <- diamonds %>% 
group_by(clarity, cut) %>% 
summarise(carat = mean(carat)) 

Ở đây tôi sắp xếp lại bởi trung bình của một yếu tố nhưng cuối cùng tôi muốn sắp xếp lại riêng cho từng lô (bằng cách giảm ý nghĩa của sự rõ ràng).

means$clarity <- reorder(means$clarity, means$carat, FUN = mean) 

Tạo các ô riêng biệt với face_wrap. Sử dụng coord_flip để so sánh các ô dễ dàng hơn.

ggplot(means, aes(x = clarity, y = carat)) + 
    geom_col() + 
    facet_wrap(~cut, ncol = 1) + 
    coord_flip() 

Bạn sẽ thấy điều này tạo ra các ô riêng biệt cho từng loại cắt nhưng thứ tự của các mức yếu tố trên trục y không chính xác cho từng trường hợp riêng lẻ. Làm thế nào tôi có thể đặt hàng chúng một cách chính xác mà không cần phải làm điều đó bằng tay cho từng loại cắt?

+2

Rõ ràng là không chính xác những gì bạn muốn, nhưng kể từ khi bạn yêu cầu một giải pháp thanh lịch, tôi chỉ có thể nghĩ đến việc viết một hàm tạo ra các ô riêng lẻ (sử dụng 'ggplot (có nghĩa là, aes (x = sắp xếp lại (rõ ràng, carat), y = carat))', 'lapp ly' thông qua các khía cạnh và sau đó đoàn tụ lại các ô đơn lẻ bằng cách sử dụng 'gridExtra'. Nó sẽ chỉ thêm một vài dòng vào mã của bạn. – yoland

Trả lời

6

này có thể được thực hiện trong một cốt truyện bằng cách sử dụng hai chức năng:

reorder_within <- function(x, by, within, fun = mean, sep = "___", ...) { 
    new_x <- paste(x, within, sep = sep) 
    stats::reorder(new_x, by, FUN = fun) 
} 


scale_x_reordered <- function(..., sep = "___") { 
    reg <- paste0(sep, ".+$") 
    ggplot2::scale_x_discrete(labels = function(x) gsub(reg, "", x), ...) 
} 

sẵn trên github dgrtwo/drlib

ggplot(means, aes(x = reorder_within(clarity, carat, cut, mean), y = carat)) + 
    geom_col() + 
    scale_x_reordered() + 
    facet_wrap(~cut, scales = "free_y", ncol = 1) + 
    coord_flip() 

enter image description here

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