2017-11-30 2 views
6

Ich versuche, mehrere einzelne Plots aus demselben data.frame mit einer anderen Reihenfolge der Faktorstufen auf der y-Achse für jede Plot zu erstellen. Jedes Diagramm soll die Faktorstufen auf y abnehmend ordnen.R: Reorder-Faktor-Ebenen für mehrere einzelne Plots

Ich weiß, dass dies manuell für jede Handlung getan werden kann, aber ich suche nach einem effizienteren und eleganteren Weg, da ich eine ganze Reihe von Plots haben werde, die ich erstellen muss. Dies muss nicht die Verwendung von facet_wrap beinhalten, wenn es einen anderen Weg gibt, vielleicht mit Schleifen etc.?

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

Unter den Datensatz und die Aggregation von zwei Faktorstufen (Klarheit und Schnitt):

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

Here I durch den Mittelwert eines Faktors neu ordnen, aber schließlich würde ich für jedes Grundstück einzeln nachbestellen möchten (durch Verringerung des Mittelwerts der Klarheit).

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

Erstellen von separaten Plots mit Face_wrap. Mit coord_flip können Sie Diagramme einfacher vergleichen.

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

Sie sehen werden, dass dies für jede Art von Schnitt getrennte Diagramme erstellt, aber die Reihenfolge der Faktorstufen auf der y-Achse sind für jeden Einzelfall nicht korrekt. Wie kann ich sie richtig bestellen, ohne dass ich das für jede Art von Schnitt manuell machen muss?

+2

Offensichtlich nicht genau auf Github verfügbar, was Sie wollen, aber da Sie gefragt eine elegante Lösung, ich kann nur daran denken, eine Funktion zu schreiben, die individuelle Plots erstellt (mit 'ggplot (bedeutet, aes (x = reorder (Klarheit, Karat), y = Karat))', 'lapp durch die Facetten und vereinigen Sie dann die einzelnen Plots mit 'gridExtra'. Es würde nur ein paar Zeilen zu Ihrem Code hinzufügen. – yoland

Antwort

6

Dies kann durch die Verwendung von zwei Funktionen in einem Plot erfolgen:

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), ...) 
} 

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