2016-07-26 16 views
0

Ein Muster, das ich viel mache, ist Facetten Diagramme auf Kürzungen von numerischen Werten. facet_wrap in ggplot2 erlaubt es nicht, eine Funktion von innen aufzurufen, daher müssen Sie eine temporäre Faktorvariable erstellen. Dies ist in Ordnung mit Mutate von dplyr. Der Vorteil besteht darin, dass Sie EDA spielen und die Anzahl der Quantile variieren oder zu Schnittpunkten usw. wechseln und die Änderungen in einer Zeile anzeigen können. Der Nachteil ist, dass die Facetten nur durch die Faktorstufe gekennzeichnet sind; Sie müssen zum Beispiel wissen, dass es eine Temperatur ist. Das ist nicht schlecht für dich selbst, aber selbst ich werde verwirrt, wenn ich ein facet_grid auf zwei solcher Variablen mache und mich erinnern muss, welches was ist. Es ist also wirklich schön, die Facetten durch einen aussagekräftigen Namen neu zu benennen.(Re) Namen Faktor Ebenen (oder Variable Namen) in ggplot2 facet_ Anruf

Die Hauptpunkte dieses Problems sind, dass sich die Ebenen ändern, wenn Sie die Anzahl der Quantile ändern. Sie wissen nicht, was sie im Voraus sind. Sie könnten die Funktion base levels() verwenden, aber das bedeutet, dass Sie den Datenrahmen mit der ausgeschnittenen Variable erweitern, dann level() aufrufen und diesen erweiterten Datenrahmen an ggplot() übergeben.

Mit plyr :: mapvalues ​​können wir all dies in ein dplyr :: mutate umwandeln, aber die erforderlichen Argumente für mapvalues ​​() machen es ziemlich klobig. "Temp.f" mehrmals eingeben zu müssen ist nicht sehr "dplyr"!

Gibt es eine bessere Möglichkeit, solche Faktorstufen "on the fly" umzubenennen? Ich hoffe, dass diese Beschreibung klar genug ist und das folgende Codebeispiel hilft.

library(ggplot2) 
library(plyr) 
library(dplyr) 
library(Hmisc) 
df <- data.frame(Temp = seq(-100, 100, length.out = 1000), y = rnorm(1000)) 

# facet_wrap doesn't allow functions so have to create new, temporary factor 
# variable Temp.f 
ggplot(df %>% mutate(Temp.f = cut2(Temp, g = 4))) + geom_histogram(aes(x = y)) + facet_wrap(~Temp.f) 
# fine, but facet headers aren't very clear, 
# we want to highlight that they are temperature 
ggplot(df %>% mutate(Temp.f = paste0("Temp: ", cut2(Temp, g = 4)))) + geom_histogram(aes(x = y)) + facet_wrap(~Temp.f) 
# use of paste0 is undesirable because it creates a character vector and 
# facet_wrap then recodes the levels in the wrong numerical order 

# This has the desired effect, but is very long! 
ggplot(df %>% mutate(Temp.f = cut2(Temp, g = 4), Temp.f = mapvalues(Temp.f, levels(Temp.f), paste0("Temp: ", levels(Temp.f))))) + geom_histogram(aes(x = y)) + facet_wrap(~Temp.f) 
+0

Benennen Sie die Faktoren vor dem Zeichnen mit 'df $ newFactor <- Faktor (df $ oldFactor, levels = c (...))' oder verwenden Sie 'levels (df $ oldFactor) <- c (...)' – lmo

+1

Als Alternative zu 'cut2' können Sie auch die Funktion' cut' von Basis R mit dem Parameter 'labels' verwenden. – Jaap

Antwort

2

Ich glaube, Sie dies aus facet_wrap tun können eine benutzerdefinierte Etikettierer-Funktion, etwa so:

myLabeller <- function(x){ 
    lapply(x,function(y){ 
    paste("Temp:", y) 
    }) 
} 

ggplot(df %>% mutate(Temp.f = cut2(Temp, g = 4))) + 
    geom_histogram(aes(x = y)) + 
    facet_wrap(~Temp.f 
      , labeller = myLabeller) 

Das Etikettierer klobig ist, aber zumindest ein Beispiel. Sie könnten einen für jede Variable schreiben, die Sie verwenden werden (z. B. tempLabeller, yLabeller, usw.).

enter image description here

Eine leichte zwicken macht dies noch besser: es automatisch den Namen der Sache verwendet Sie Facettieren auf:

betterLabeller <- function(x){ 
    lapply(names(x),function(y){ 
    paste0(y,": ", x[[y]]) 
    }) 
} 

ggplot(df %>% mutate(Temp.f = cut2(Temp, g = 4))) + 
    geom_histogram(aes(x = y)) + 
    facet_wrap(~Temp.f 
      , labeller = betterLabeller) 

enter image description here

1

Okay, mit Dank an Mark Peterson für Zeig mir in Richtung des Etikettierers Argument/Funktion, die genaue Antwort, ich bin glücklich mit:

ggplot(df %>% mutate(Temp.f = cut2(Temp, g = 4))) + geom_histogram(aes(x = y)) + facet_wrap(~Temp.f, labeller = labeller(Temp.f = label_both)) 

Ich bin ein Fan von faul und "Label_both" bedeutet, ich kann einfach eine sinnvolle temporäre (oder überschreiben die ursprüngliche) Variable Spalte erstellen und sowohl den Namen und den Wert angegeben werden. Die eigene Labeler-Funktion zu rollen ist leistungsfähiger, aber die Verwendung von label_both ist eine gute, einfache Option.