Festlegen einzelner Achsengrenzen mit facet_wrap und scale = "free" in ggplot2


115

Ich erstelle ein facettiertes Diagramm, um vorhergesagte und tatsächliche Werte neben einem Diagramm mit vorhergesagten Werten und Residuen anzuzeigen. Ich werde shinyhelfen, die Ergebnisse der Modellierungsbemühungen anhand verschiedener Trainingsparameter zu untersuchen. Ich trainiere das Modell mit 85% der Daten, teste die verbleibenden 15% und wiederhole dies fünfmal, wobei ich jedes Mal tatsächliche / vorhergesagte Werte sammle. Nach der Berechnung der Residuen data.framesieht mein so aus:

head(results)
       act     pred       resid
2 52.81000 52.86750 -0.05750133
3 44.46000 42.76825  1.69175252
4 54.58667 49.00482  5.58184181
5 36.23333 35.52386  0.70947731
6 53.22667 48.79429  4.43237981
7 41.72333 41.57504  0.14829173

Was ich möchte:

  • Nebeneinander Handlung von predvs. actund predvs.resid
  • Der x / y-Bereich / die Grenzen für predvs. actsind gleich, idealerweise von min(min(results$act), min(results$pred))bismax(max(results$act), max(results$pred))
  • Der x / y-Bereich / die Grenzen für predvs. sollen resid nicht davon beeinflusst werden, was ich mit dem tatsächlichen vs. vorhergesagten Plot mache. Plotten fürxy ist in Ordnung, nur über die vorhergesagten Werte und nur über den Restbereich zu zeichnen.

Um beide Diagramme nebeneinander anzuzeigen, schmelze ich die Daten:

library(reshape2)
plot <- melt(results, id.vars = "pred")

Jetzt Handlung:

library(ggplot2)
p <- ggplot(plot, aes(x = pred, y = value)) + geom_point(size = 2.5) + theme_bw()
p <- p + facet_wrap(~variable, scales = "free")

print(p)

Das kommt dem, was ich will, ziemlich nahe:

Geben Sie hier die Bildbeschreibung ein

Was ich möchte, ist, dass die x- und y-Bereiche für tatsächliche und vorhergesagte Werte gleich sind, aber ich bin mir nicht sicher, wie ich das spezifizieren soll, und ich brauche das nicht für die vorhergesagten und verbleibenden Diagramme seit dem Bereiche sind völlig unterschiedlich.

Ich habe versucht, so etwas für beide hinzuzufügen scale_x_continousund scale_y_continuous:

min_xy <- min(min(plot$pred), min(plot$value))
max_xy <- max(max(plot$pred), max(plot$value))

p <- ggplot(plot, aes(x = pred, y = value)) + geom_point(size = 2.5) + theme_bw()
p <- p + facet_wrap(~variable, scales = "free")
p <- p + scale_x_continuous(limits = c(min_xy, max_xy))
p <- p + scale_y_continuous(limits = c(min_xy, max_xy))

print(p)

Aber das greift min()die Restwerte auf.

Geben Sie hier die Bildbeschreibung ein

Eine letzte Idee, die ich hatte, war, den Wert des Minimums actund der predVariablen vor dem Schmelzen zu speichern und sie dann zum geschmolzenen Datenrahmen hinzuzufügen, um zu bestimmen, in welcher Facette sie erscheinen:

head(results)
       act     pred       resid
2 52.81000 52.86750 -0.05750133
3 44.46000 42.76825  1.69175252
4 54.58667 49.00482  5.58184181
5 36.23333 35.52386  0.70947731

min_xy <- min(min(results$act), min(results$pred))
max_xy <- max(max(results$act), max(results$pred))

plot <- melt(results, id.vars = "pred")

plot <- rbind(plot, data.frame(pred = c(min_xy, max_xy),
  variable = c("act", "act"), value = c(max_xy, min_xy)))

p <- ggplot(plot, aes(x = pred, y = value)) + geom_point(size = 2.5) + theme_bw()
p <- p + facet_wrap(~variable, scales = "free")

print(p)

Das macht was ich will, mit der Ausnahme, dass auch die Punkte auftauchen:

Geben Sie hier die Bildbeschreibung ein

Irgendwelche Vorschläge für so etwas?


Ich habe gesehen, wie diese Idee hinzugefügt werden geom_blank()soll, bin mir aber nicht sicher, wie ich das aes()Bit angeben und es richtig funktionieren lassen soll oder was der geom_point()Verwendung des Histogramms entspricht aes(y = max(..count..)).


Hier sind Daten zum Spielen (meine tatsächlichen, vorhergesagten und verbleibenden Werte vor dem Schmelzen):

> dput(results)
structure(list(act = c(52.81, 44.46, 54.5866666666667, 36.2333333333333, 
53.2266666666667, 41.7233333333333, 35.2966666666667, 30.6833333333333, 
39.25, 35.8866666666667, 25.1, 29.0466666666667, 23.2766666666667, 
56.3866666666667, 42.92, 41.57, 27.92, 23.16, 38.0166666666667, 
61.8966666666667, 37.41, 41.6333333333333, 35.9466666666667, 
48.9933333333333, 30.5666666666667, 32.08, 40.3633333333333, 
53.2266666666667, 64.6066666666667, 38.5366666666667, 41.7233333333333, 
25.78, 33.4066666666667, 27.8033333333333, 39.3266666666667, 
48.9933333333333, 25.2433333333333, 32.67, 55.17, 42.92, 54.5866666666667, 
23.16, 64.6066666666667, 40.7966666666667, 39.0166666666667, 
41.6333333333333, 35.8866666666667, 25.1, 23.2766666666667, 44.46, 
34.2166666666667, 40.8033333333333, 24.5766666666667, 35.73, 
61.8966666666667, 62.1833333333333, 74.6466666666667, 39.4366666666667, 
36.6, 27.1333333333333), pred = c(52.8675013282404, 42.7682474758679, 
49.0048248585123, 35.5238560262515, 48.7942868566949, 41.5750416040131, 
33.9548164913007, 29.9787449128663, 37.6443975781139, 36.7196211666685, 
27.6043278172077, 27.0615724310721, 31.2073056885252, 55.0886903524179, 
43.0895814712768, 43.0895814712768, 32.3549865881578, 26.2428426737583, 
36.6926037128343, 56.7987490221996, 45.0370788180147, 41.8231642271826, 
38.3297859332601, 49.5343916620086, 30.8535641206809, 29.0117492750411, 
36.9767968381391, 49.0826677983065, 54.4678549541069, 35.5059204731218, 
41.5333417555995, 27.6069075391361, 31.2404889715121, 27.8920960978598, 
37.8505531149324, 49.2616631533957, 30.366837650159, 31.1623492639066, 
55.0456078770405, 42.772538591063, 49.2419293590535, 26.1963523976241, 
54.4080781796616, 44.9796700541254, 34.6996927469131, 41.6227713664027, 
36.8449646519306, 27.5318686661673, 31.6641793552795, 42.8198894266632, 
40.5769177148146, 40.5769177148146, 29.3807781312816, 36.8579132935989, 
55.5617033901752, 55.8097119335638, 55.1041728261666, 43.6094641699075, 
37.0674887276681, 27.3876960746536), resid = c(-0.0575013282403773, 
1.69175252413213, 5.58184180815435, 0.709477307081826, 4.43237980997177, 
0.148291729320228, 1.34185017536599, 0.704588420467079, 1.60560242188613, 
-0.832954500001826, -2.50432781720766, 1.98509423559461, -7.93063902185855, 
1.29797631424874, -0.169581471276786, -1.51958147127679, -4.43498658815778, 
-3.08284267375831, 1.32406295383237, 5.09791764446704, -7.62707881801468, 
-0.189830893849219, -2.38311926659339, -0.541058328675241, -0.286897454014273, 
3.06825072495888, 3.38653649519422, 4.14399886836018, 10.1388117125598, 
3.03074619354486, 0.189991577733821, -1.82690753913609, 2.16617769515461, 
-0.088762764526507, 1.47611355173427, -0.268329820062384, -5.12350431682565, 
1.5076507360934, 0.124392122959534, 0.147461408936991, 5.34473730761318, 
-3.03635239762411, 10.1985884870051, -4.18300338745873, 4.31697391975358, 
0.0105619669306023, -0.958297985263961, -2.43186866616734, -8.38751268861282, 
1.64011057333683, -6.36025104814794, 0.226415618518729, -4.80411146461488, 
-1.1279132935989, 6.33496327649151, 6.37362139976954, 19.5424938405001, 
-4.17279750324084, -0.467488727668119, -0.254362741320246)), .Names = c("act", 
"pred", "resid"), row.names = c(2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 
10L, 11L, 12L, 13L, 15L, 16L, 17L, 18L, 19L, 20L, 21L, 22L, 23L, 
24L, 25L, 26L, 28L, 29L, 30L, 31L, 32L, 33L, 34L, 35L, 36L, 37L, 
38L, 39L, 41L, 42L, 43L, 44L, 45L, 46L, 47L, 48L, 49L, 50L, 51L, 
52L, 54L, 55L, 56L, 57L, 58L, 59L, 60L, 61L, 62L, 63L, 64L, 65L
), class = "data.frame")

Nur neugierig - warum nicht Ist und Rest in derselben Grafik darstellen?
Ricardo Saporta

2
Ich würde die Diagramme separat erstellen und dann verwenden grid.arrange.
Joran

@ RicardoSaporta Gibt es ein Google-Bild, auf das Sie als Beispiel verlinken könnten? Schlagen Sie unter Verwendung der ggplot(plot, aes(x = pred, y = value)) + geom_point()nachgeschmolzenen Daten vor, dass ich nur ohne Facettierung auskommen würde? Würde das nicht wirklich die Skalierung der Residuen verkleinern, um es schwierig zu machen, Nicht-Zufälligkeit / Versatz zu erkennen?
Hendy

1
Mein anderer Kommentar ist , dass Facettierung ist weniger Code ... Ich habe gerade schmelzen muß, dann plotten und Facette durch den variableWert erstellt von melt(). Andererseits könnte ich diese in einer Liste speichern, die erstellt wurde lapply, um verschiedene Kombinationen zu zeichnen. Danke für die Eingabe. Wenn Sie eine gridLösung erstellen möchten , kann ich die Antwort akzeptieren. Wenn dies jedoch der Weg ist, den wir einschlagen, kann dies genauso gut ein Duplikat der anderen gridLösungen sein.
Hendy

1
@joran und ich finde, ich rate den Leuten routinemäßig, nicht zu verwenden, grid.arrangewas das Layout fast immer durcheinander bringt . Ich wünschte, die langjährigen Fehler von gtable würden behoben.
Baptiste

Antworten:


115

Hier ist ein Code mit einer Dummy- geom_blankEbene:

range_act <- range(range(results$act), range(results$pred))

d <- reshape2::melt(results, id.vars = "pred")

dummy <- data.frame(pred = range_act, value = range_act,
                    variable = "act", stringsAsFactors=FALSE)

ggplot(d, aes(x = pred, y = value)) +
  facet_wrap(~variable, scales = "free") +
  geom_point(size = 2.5) + 
  geom_blank(data=dummy) + 
  theme_bw()

Geben Sie hier die Bildbeschreibung ein


11
Eine schöne Variante dazu ist expand_limits(pred=range_act, value=range_act), die verwendet, geom_blankaber einfacher zu bedienen ist.
Eregon

6
Dies erweitert nur die Grenzen (zieht sie aber nicht zusammen). Gibt es eine Möglichkeit, die Reichweite zu verkürzen? @ Baptiste
Indranil Gayen

32

Ich bin nicht sicher, ob ich verstehe, was Sie wollen, aber basierend auf dem, was ich verstanden habe

Die x-Skala scheint gleich zu sein, es ist die y-Skala, die nicht gleich ist, und das liegt daran, dass Sie scale = "free" angegeben haben.

Sie können scale = "free_x" angeben, um nur zuzulassen, dass x frei ist (in diesem Fall ist es dasselbe, wie pred per Definition denselben Bereich hat).

p <- ggplot(plot, aes(x = pred, y = value)) + geom_point(size = 2.5) + theme_bw()
p <- p + facet_wrap(~variable, scales = "free_x")

hat für mich gearbeitet, siehe Bild

Geben Sie hier die Bildbeschreibung ein

Ich denke, Sie haben es zu schwierig gemacht - ich erinnere mich an ein Mal, als ich die Grenzwerte basierend auf einer Formel mit min und max definiert habe, und wenn facettiert, denke ich, dass nur diese Werte verwendet wurden, aber ich kann den Code nicht finden


7

Sie können den Bereich auch mit dem Befehl coord_cartesian angeben, um den gewünschten Bereich für die y-Achse festzulegen, ähnlich wie im vorherigen Beitrag. Verwenden Sie scale = free_x

p <- ggplot(plot, aes(x = pred, y = value)) +
     geom_point(size = 2.5) +
     theme_bw()+
     coord_cartesian(ylim = c(-20, 80))
p <- p + facet_wrap(~variable, scales = "free_x")
p

Geben Sie hier die Bildbeschreibung ein

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.