简体   繁体   English

R:在ggplot2图中按值而不是字母顺序排序构面

[英]R: ordering facets by value rather than alphabetical order in a ggplot2 plot

A couple of weeks ago I used ggplot2 to create a faceted plot where the facets were ordered by the last value in the data frame. 几周前,我使用ggplot2创建了一个多面图,其中构面按数据框中的最后一个值排序。 I had no major problems until it came to reordering, as I haven't really assimilated all the complications of orders, factors and levels. 在重新排序之前我没有遇到任何重大问题,因为我没有真正理解订单,因素和水平的所有复杂情况。 Still, after an hour or two (or three) of referring to SO posts I got it working. 仍然,在提到SO帖子一两个小时(或三个)之后我就开始工作了。

When I came back to the script today it was no longer "working" in that it is now sorting the facets by alphabetical order rather than by the final value of the data frame. 当我今天回到剧本时,它不再“正在工作”,因为它现在按字母顺序而不是数据框的最终值对方面进行排序。 (I think that I originally "fixed" the problem while messing around at the R console and did not actually add the solution to the script.) Rather than spending another couple of hours on this tonight I'm going to throw myself on the mercy of SO. (我认为我最初“固定”了这个问题,同时在R控制台上乱搞并且实际上没有将解决方案添加到脚本中。)而不是在今晚花费另外几个小时,我会把自己放在怜悯SO。

Q. How can I sort the facets by a specified value rather than by the alphabetical order of the names of each facet? 问:如何按指定值而不是按每个方面名称的字母顺序对构面进行排序? Please note the following code is an example only; 请注意以下代码仅为示例; the real data has several dozen items. 真实的数据有几十个项目。

Edited code below to reflect additional input from @joran; 编辑下面的代码以反映@joran的其他输入; the facets are now sorted and filled appropriately. 现在可以对构面进行分类和填充。 Mission successful. 任务成功。

# 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)

图像显示正面现在已正确排序,但填充不再有效

You have two problems: 你有两个问题:

  1. The line that converts myitems$variable to a factor should specify ordered = TRUE , to assure that it will be an ordered factor. myitems$variable转换为factor的行应指定ordered = TRUE ,以确保它是一个有序因子。

  2. Your geom_text call uses a separate data frame whose corresponding variable isn't a factor (or ordered) so it's stomping on the ordered nature of the one in myitems . 你的geom_text调用使用一个单独的数据框,其相应的变量不是一个因子(或有序),因此它会踩踏myitems中的myitems的有序性质。

Convert them both or ordered factors, and you should be fine. 转换他们两个或有序因素,你应该没事。

Facet are ordered in the same order as variables in source data.frame. Facet的排序顺序与source data.frame中的变量的顺序相同。
Thus as a basic hack you can just order variables name when creating the data.frame : 因此,作为一个基本的hack,你可以在创建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)
        )

If you need to reorder at the end of the process, then arrange() might be the best solution. 如果您需要在流程结束时重新排序,那么arrange()可能是最佳解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM