2017-08-22 58 views
-1

我想使用ggplot2和facet來製作圖片中的情節。一如既往,有分組數據,每個組都映射到方面。棘手的部分是我想要單個方面由三個獨立的圖(不是圖層)組成:迴歸線,殘差,QQ圖。ggplot2:每個方面的幾個圖

link to picture

放鬆一下downvote戰。這裏是代碼

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

所得的情節:enter image description here

正如你可以看到曲線是重疊的每個方面。傷心!同時我想要「複雜」的方面,每個方面包含三個獨立的情節。

+1

請出示重複的例子,和你有什麼嘗試過這麼遠。並請閱讀此:https://stackoverflow.com/tour –

回答

1

由於每個圖表中的信息類型如此不同,因此您需要製作三張圖並將它們綁定在一起。

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

爲了證明什麼爭論圍繞着數據做這一切在一個ggplot通話的樣子,這裏是它的另一種裂紋。這是一個劣質的解決方案,因爲您必須使用修改的數據調用geom_blank才能在繪圖類型中獲得均勻的刻度,並且無法正確標記繪圖的座標軸。

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

感謝您的迴應。如果facet_wrap無法在這裏工作,這真的很不幸。我的想法是,ggplot2足夠強大,可以爲每個組創建複合情節,並將它們粘在一起。所有這些都在facet_wrap的背景之後。 –

+0

@MatrixNorm'facet_wrap'完成它打算做的事:產生小倍數以便在組之間進行比較。這就是爲什麼劇情的每一欄都很乾淨整潔。它不適用於生成多種類型的地塊。你可以與它戰鬥,並最終把它們全部放到一個單一的'ggplot'調用中,但它不會是「乾淨」的方式來做到這一點。 – Brian

+0

@MatrixNorm,我更新了我的代碼,向您展示了多功能一體機的外觀。必須告訴「ggplot」在哪個面板上放置什麼。 – Brian