2012-03-11 46 views
5

Một vài tuần trước, tôi đã sử dụng ggplot2 để tạo một âm mưu mặt, trong đó các mặt được sắp xếp theo giá trị cuối cùng trong khung dữ liệu. Tôi đã không có vấn đề lớn cho đến khi nó đến để sắp xếp lại, như tôi đã không thực sự đồng hóa tất cả các biến chứng của các đơn đặt hàng, các yếu tố và các cấp. Tuy nhiên, sau một hoặc hai giờ (hoặc ba) đề cập đến các bài viết SO tôi đã nhận nó làm việc.R: sắp xếp các khía cạnh theo giá trị chứ không phải thứ tự bảng chữ cái trong ô ggplot2

Khi tôi quay trở lại tập lệnh hôm nay, nó không còn "hoạt động" ở chỗ nó sắp xếp các khía cạnh theo thứ tự bảng chữ cái thay vì bằng giá trị cuối cùng của khung dữ liệu. (Tôi nghĩ rằng tôi ban đầu "cố định" vấn đề trong khi rối tung xung quanh bàn điều khiển R và không thực sự thêm giải pháp cho kịch bản.) Thay vì chi tiêu một vài giờ vào tối nay tôi sẽ ném bản thân mình vào lòng thương xót của SO.

Q. Làm cách nào để sắp xếp các khía cạnh theo giá trị được chỉ định thay vì theo thứ tự bảng chữ cái của tên của từng khía cạnh? Xin lưu ý đoạn mã sau chỉ là một ví dụ; dữ liệu thực có vài chục mục.

Mã được chỉnh sửa bên dưới để phản ánh đầu vào bổ sung từ @joran; các khía cạnh bây giờ được sắp xếp và điền một cách thích hợp. Nhiệm vụ thành công.

# Version 3 
require(ggplot2) ## NB This script assumes you have ggplot2 v0.90 
require(scales) 
require(plyr) 
require(lubridate) 
require(reshape) 

set.seed(12345) 
monthsback <- 15 
date <- as.Date(paste(year(now()),month(now()),"1",sep="-")) - months(monthsback) 
myitems <- data.frame(mydate=seq(as.Date(date), by="month", length.out=monthsback), 
         aaa = runif(monthsback, min = 600, max = 800), 
         bbb = runif(monthsback, min = 100, max = 200), 
         ccc = runif(monthsback, min = 1400, max = 2000), 
         ddd = runif(monthsback, min = 50, max = 120)) 

myitems <- melt(myitems, id = c('mydate')) 

change_from_start <- function(x) { 
    (x - x[1])/x[1] 
} 

myitems <- ddply(myitems, .(variable), transform, value = change_from_start(value)) 
myitems$mydate <- as.Date(myitems$mydate, format = "%Y-%m-%d") 
myvals <- myitems[myitems$mydate == myitems$mydate[nrow(myitems)],] # get values on which to sort facets 
myvals <- within(myvals, variable <- factor(variable, as.character(myvals[order(myvals$value, decreasing = T),]$variable),ordered = TRUE)) 
myitems <- within(myitems, variable <- factor(variable, as.character(myvals[order(myvals$value, decreasing = T),]$variable),ordered = TRUE)) 
print(levels(myitems$variable)) # check to see if ordering succeeded 
myitems$fill <- ifelse(myitems$variable == "ddd", "blue", "darkgreen") 

    p <- ggplot(myitems, aes(y = value, x = mydate, group = variable)) + 
     geom_rect(aes(xmin = as.Date(myitems$mydate[1]), xmax = Inf, fill = fill), ymin = -Inf, ymax = Inf) + 
     scale_fill_manual(values = c("blue", "darkgreen")) + 
     geom_line(colour = "black") + 
     geom_text(data = myvals, aes(x = as.Date(myitems$mydate[1]) + 250, y = 0.2, label = sprintf("%1.1f%%", value * 100))) + 
     facet_wrap(~ variable, ncol = 2) + 
     geom_hline(yintercept = 0, size = 0.6, linetype = "dotdash") + 
     scale_y_continuous(label = percent_format()) + 
     scale_x_date(expand = c(0,0), labels = date_format("%Y-%m"), breaks = date_breaks("year")) + 
     xlab(NULL) + 
     ylab(NULL) + 
     opts(legend.position = "none") + 
     opts(panel.grid.minor = theme_blank()) + 
     opts() 

print(p) 

Image showing that facets are now sorted properly but that the fill is no longer working

Trả lời

3

Bạn có hai vấn đề:

  1. Điểm mấu chuyển đổi myitems$variable đến một yếu tố nên xác định ordered = TRUE, để đảm bảo rằng nó sẽ là một yếu tố ra lệnh.

  2. gọi geom_text của bạn sử dụng một riêng khung dữ liệu mà tương ứng biến không phải là một yếu tố (hoặc đặt hàng) vì vậy nó dậm theo tính chất ra lệnh của một trong myitems.

Chuyển đổi chúng cả hai hoặc các yếu tố đặt hàng và bạn sẽ ổn.

+0

Cảm ơn, tôi nghĩ rằng tôi thấy. Tôi sẽ có một người khác đi vào nó vào ngày mai. – SlowLearner

+0

Tôi đã thêm 'ordered = TRUE' vào khung dữ liệu myvals và khung dữ liệu myitems và bây giờ cả hai đều sắp xếp như mong đợi. Tuy nhiên ... Bây giờ tôi đang tìm thấy rằng điền là bị hỏng, có lẽ bởi vì nó được điền vào cột điền và không phải là mức độ yếu tố được sắp xếp. Đó là, nếu "ddd" nằm trong khía cạnh thứ hai thì khía cạnh thứ hai phải có màu xanh và phần còn lại màu xanh lá cây, nhưng nó luôn là khía cạnh thứ tư - vị trí ban đầu của "ddd" - được tô màu xanh. Tôi đã thử nghiệm với việc cố gắng đặt hàng cột điền để giải quyết điều này nhưng không thể làm cho nó hoạt động. Đây có phải là một câu hỏi riêng biệt không? – SlowLearner

+1

@SlowLearner Thay đổi 'fill = myitems $ fill' thành' fill = fill'.Đó là một sự khác biệt tinh tế, nhưng nếu không biến điền của bạn không bị ràng buộc với các biến khác trong khung dữ liệu, vì bạn vừa truyền cho nó một vectơ đứng miễn phí. – joran

0

Facet được sắp xếp theo thứ tự giống như các biến trong nguồn data.frame.
Như vậy là một hack cơ bản bạn có thể chỉ cần đặt biến tên khi tạo data.frame:

myitems <- data.frame(mydate=seq(as.Date(date), by="month", length.out=monthsback), 
     'ccc' = runif(monthsback, min = 1400, max = 2000), 
     'aaa' = runif(monthsback, min = 600, max = 800), 
     'ddd' = runif(monthsback, min = 50, max = 120), 
     'bbb' = runif(monthsback, min = 100, max = 200) 
     ) 

Nếu bạn cần phải sắp xếp lại ở phần cuối của quá trình này, sau đó sắp xếp() có thể là giải pháp tốt nhất.

+0

Cảm ơn bạn đã đề xuất này. Tôi đã không nói rõ trong câu hỏi của tôi, nhưng dữ liệu thực có vài chục mục và các giá trị mà theo đó các khía cạnh nên được đặt hàng sẽ thay đổi thường xuyên, vì vậy việc sắp xếp lại thủ công sẽ khá nặng nề. – SlowLearner

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