2017-08-22 8 views
-1

Ich möchte ein Plot wie im Bild mit ggplot2 und Facetten machen. Wie immer gibt es gruppierte Daten und jede Gruppe ist Facette zugeordnet. Schwieriger Teil ist, dass ich möchte, dass eine einzelne Facette aus drei unabhängigen Plots (nicht Schichten) besteht: Regressionslinie, Residuen, QQ-Plot.ggplot2: mehrere Plots pro einzelne Facette

link to picture

Chill out mit Downvote Kriegsführung. Hier ist der Code

library(dplyr) 
library(broom) 
library(tibble) 
library(tidyr) 
library(purrr) 
library(ggplot2) 

iris %>% 
group_by(Species) %>% 
nest %>% 
mutate(mod = map(data, ~lm(Sepal.Length ~ Sepal.Width, .))) %>% 
mutate(
    tidy = map(mod, broom::tidy), 
    glance = map(mod, broom::glance), 
    augment = map(mod, broom::augment) 
) -> models 

df <- models %>% select(Species, augment) %>% unnest 

df %>% print 

ggplot() + 
geom_count(data=df, aes(x=Sepal.Width, y=Sepal.Length, colour = Species), alpha=0.7) + 
geom_point(data=df, aes(x=Sepal.Width, y=.fitted), alpha=0.7, color="black", shape='x', size=5) + 
geom_point(data=df, aes(x=Sepal.Width, y=.resid, colour=Species), alpha=0.2) + 
stat_qq(data=df, aes(sample=.resid, colour=Species), distribution=qnorm, alpha=0.2) + 
facet_wrap(~Species, scales = "free") + 
theme(legend.position = "bottom", 
     legend.direction = "vertical") 

Resultierende Grundstück: enter image description here

Wie Sie sehen können Plots sind auf jeder Facette überlappen. Traurig! Inzwischen möchte ich eine "komplexe" Facette, in der jede Facette drei unabhängige Plots enthält.

+1

zeigen Bitte ein reproduzierbares Beispiel und was haben Sie bisher versucht. Und bitte lesen Sie dies: https://stackoverflow.com/tour –

Antwort

1

Da die Arten von Informationen in jedem Diagramm so unterschiedlich sind, müssen Sie drei Diagramme erstellen und sie miteinander verbinden.

library(ggplot2) 
library(broom) 
library(purrr) 
library(gridExtra) 

iris.lm <- lm(Sepal.Width ~ Sepal.Length*Species, iris) 

p1 <- ggplot(augment(iris.lm), aes(Sepal.Length, Sepal.Width, color = Species)) + 
    theme_classic() + guides(color = F) + 
    labs(title = "Regression") + 
    theme(strip.background = element_blank(), strip.text = element_blank(), 
     panel.background = element_rect(color = "black")) + 
    stat_smooth(method = "lm", colour = "black") + geom_point(shape = 1) + 
    facet_grid(Species~.) 

p2 <- ggplot(augment(iris.lm), aes(.fitted, .resid, color = Species)) + 
    theme_classic() + guides(color = F) + 
    labs(x = "Fitted values", y = "Residuals") + 
    theme(strip.background = element_blank(), strip.text = element_blank(), 
     panel.background = element_rect(color = "black")) + 
    stat_smooth(se = F, span = 1, colour = "black") + geom_point(shape = 1) + 
    facet_grid(Species~.) 

p3 <- ggplot(augment(iris.lm), aes(sample = .resid/.sigma, color = Species)) + 
    theme_classic() + theme(panel.background = element_rect(color = "black")) + 
    labs(x = "Theoretical quantiles", y = "Standardized residuals", title = "Q-Q") + 
    geom_abline(slope = 1, intercept = 0, color = "black") + 
    stat_qq(distribution = qnorm, shape = 1) + 
    facet_grid(Species~.) 

p <- list(p1, p2, p3) %>% purrr::map(~ggplot_gtable(ggplot_build(.))) 

cbind.gtable(p[[1]], p[[2]], p[[3]]) %>% grid.arrange() 

enter image description here

Um zu zeigen, was um die Daten Gerangel sie alle in einer ggplot Aufruf wie folgt aussieht zu tun, hier ist eine andere Riss an sie. Dies ist eine minderwertige Lösung, da Sie geom_blank mit den geänderten Daten aufrufen müssen, um einheitliche Skalen innerhalb des Plottyps zu erhalten, und Sie können die Plots nicht ordnungsgemäß mit ihren Achsen beschriften.

enter image description here

library(dplyr) 
library(broom) 
library(tidyr) 
library(ggplot2) 


iris.lm <- lm(Sepal.Width ~ Sepal.Length*Species, iris) 

data_frame(type = factor(c("Regression", "F vs R", "Q-Q"), 
         levels = c("Regression", "F vs R", "Q-Q"))) %>% 
    group_by(type) %>% 
    do(augment(iris.lm)) %>% 
    group_by(Species) %>% 
    mutate(yval = case_when(
    type == "Regression" ~ Sepal.Width, 
    type == "F vs R" ~ .resid, 
    type == "Q-Q" ~ .resid/.sigma 
         ), 
     xval = case_when(
    type == "Regression" ~ Sepal.Length, 
    type == "F vs R" ~ .fitted, 
    type == "Q-Q" ~ qnorm(ppoints(length(.resid)))[order(order(.resid/.sigma))] 
         ), 
    yval.sm = case_when(
     type == "Regression" ~ .fitted, 
     type == "F vs R" ~ loess(.resid ~ .fitted, span = 1)$fitted, 
     type == "Q-Q" ~ xval 
    )) %>% { 
    ggplot(data = ., aes(xval, yval, color = Species)) + geom_point() + 
    facet_wrap(~interaction(type, Species, sep = ": "), scales = "free") + 
    geom_line(aes(xval, yval.sm), colour = "black") + 
    geom_blank(data = . %>% ungroup() %>% select(-Species) %>% 
       mutate(Species = iris %>% select(Species) %>% distinct()) %>% 
       unnest(), 
      aes(xval, yval)) + 
    labs(x = "Sepal.Length: actual values, fitted values, theoretical quantiles", 
     y = "Sepal.Width: actual values, residuals, standardized residuals")} 
+0

Danke für die Antwort. Das ist wirklich schade, wenn facet_wrap hier nicht funktionieren kann. Meine Idee war, dass ggplot2 stark genug ist, um für jede Gruppe ein zusammengesetztes Diagramm zu erstellen und sie in einem großen Diagramm zusammenzufügen. All dies hinter der Szene von facet_wrap. –

+0

@MatrixNorm 'facet_wrap' macht, was es beabsichtigt ist: produzieren kleine Vielfache für den Vergleich zwischen Gruppen. Deshalb ist jede Spalte der Handlung schön und sauber. Es ist nicht für die Erstellung mehrerer Arten von Plots vorgesehen. Du könntest damit kämpfen und sie alle in einen einzigen "ggplot" -Ruf bringen, aber es wäre nicht der "saubere" Weg, es zu tun. – Brian

+0

@MatrixNorm, ich habe meinen Code aktualisiert, um Ihnen zu zeigen, wie ein All-in-One-Gerät aussehen müsste. 'ggplot' muss gesagt werden, was in welchem ​​Panel zu setzen ist. – Brian

Verwandte Themen