2012-03-11 154 views
5

幾個星期前,我使用ggplot2創建刻面圖,其中刻面按數據框中的最後一個值排序。在重新排序之前,我沒有遇到任何重大問題,因爲我沒有真正吸收訂單,因素和層次的所有複雜因素。儘管如此,在引用SO帖子一兩個小時(或三個)之後,我纔開始工作。R:在ggplot2圖中按值而不是按字母順序排列刻面

當我今天回到腳本時,它不再「工作」,因爲它現在按字母順序排序各個方面而不是數據框的最終值。 (我認爲我最初在解決R控制檯問題時「解決了」問題,並沒有真正將解決方案添加到腳本中。)與其今後幾個小時花費在這個今晚,我會拋棄自己的憐憫的SO。

問:我怎樣才能按指定值排序構面而不是按每個構面名稱的字母順序排序?請注意以下代碼僅爲示例;真實的數據有幾十個項目。

以下編輯代碼反映來自@joran的額外輸入;現在分面和適當填充。任務成功。

# 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

回答

3

你有兩個問題:

  1. ,其將myitems$variable的因素該行應指定ordered = TRUE,以確保這將是一個有序的因素。

  2. geom_text呼叫使用一個單獨的數據幀,其相應的變量是不是一個因素(或有序),所以它踩所述一個在myitems的有序性質。

轉換他們或有序的因素,你應該罰款。

+0

謝謝,我想我明白了。明天我會再來一次。 – SlowLearner 2012-03-12 14:08:11

+0

我向myvals數據框和myitems數據框添加了'ordered = TRUE',現在它們都按照人們的預期排序。然而...現在我發現填充已經破裂,大概是因爲它填充填充列而不是已排序的因子水平。也就是說,如果「ddd」在第二個方面,第二個方面應該是藍色,其餘的是綠色,但它總是第四個方面 - 「ddd」的原始位置 - 填充藍色。我已嘗試嘗試訂購填充列來解決此問題,但無法使其正常工作。這應該是一個單獨的問題嗎? – SlowLearner 2012-03-15 02:59:25

+1

@SlowLearner將'fill = myitems $ fill'更改爲'fill = fill'。這是一個細微的差別,但是否則你的填充變量不會綁定到數據框中的其他變量,因爲你剛剛通過了一個獨立的向量。 – joran 2012-03-15 03:09:59

0

小面排列的順序相同源data.frame變量。
因此,作爲一個基本的黑客創建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) 
     ) 

如果您需要在過程結束時重新排序,然後安排()可能是最好的解決方案。

+0

謝謝你的建議。在我的問題中,我沒有說清楚,但真正的數據有幾十個項目,並且這些方面應該訂購的值將會頻繁更改,所以手動重新排序會相當麻煩。 – SlowLearner 2012-03-11 15:46:44