Tiptop
Tiptop

Reputation: 623

Facet-wrap in ggplot with function

@Allan Cameron helped me with a code that automatically places the R2 and p value (from an LM) in the upper left corner of a graph when I'm plotting two variables.

I cannot however make it work with facet_wrap. For an example, in the mtcars dataset, if I want to plot wt against disp I can do that, but if I want to use facet_wrap to make a plot for each cylinder group (e.g. 4, 6, 8) then I receive the following error message

At least one layer must contain all faceting variables: `cyl`.
* Plot is missing `cyl`
* Layer 1 is missing `cyl`
* Layer 2 is missing `cyl`
* Layer 3 is missing `cyl`
* Layer 4 is missing `cyl`

Here is the code

ggplotRegression <- function (fit, title) {
  
  require(ggplot2)
  lab <- grid::textGrob(label = paste0(
    as.character(as.expression(fit$call$formula)), "\n",
    "Adj R\u00b2 = ",
    signif(summary(fit)$adj.r.squared, 1),
    ",  p = ", signif(summary(fit)$coef[2,4], 1)),
     x = unit(0.05, "npc"), 
     y = unit(0.9, "npc"), just = "left",
     gp = grid::gpar(size = 14, fontface = "bold"))
  ggplot(fit$model, aes_string(x = names(fit$model)[2], 
                               y = names(fit$model)[1])) + 
    ggtitle(title) +
    geom_point() +
    stat_smooth(method = "lm", col = "red") +
    annotation_custom(lab)
}


ggplotRegression(lm(disp ~ wt, data = mtcars), "My Title") +
  geom_point(size = 3.74, colour = "#0c4c8a") +
  theme_bw()+
  facet_wrap(vars(cyl), scales = "free")

Also, I don't really understand what the code does?

Upvotes: 0

Views: 504

Answers (1)

StupidWolf
StupidWolf

Reputation: 46978

You run into the error because the function relies on fit$model, and if you feed in lm(disp ~ wt, data = mtcars) into the data, you can see that cyl is no longer in the ggplot object:

fit = lm(disp ~ wt, data = mtcars)
head(fit$model)

                  disp    wt
Mazda RX4          160 2.620
Mazda RX4 Wag      160 2.875
Datsun 710         108 2.320
Hornet 4 Drive     258 3.215
Hornet Sportabout  360 3.440
Valiant            225 3.460

What @Allan provided for you basically edits 1 plot and inserts in the text. If you want to fit three linear models on different subsets of data, it would be this:

library(ggpmisc)
library(ggplot2)

formula = y~x

ggplot(mtcars, aes(wt, disp)) +
geom_point() +
geom_smooth(method = "lm",formula=formula) +
facet_wrap(~cyl, scales = "free")+
stat_poly_eq(
aes(label = paste(stat(adj.rr.label), stat(p.value.label),sep = "*\", \"*")),
formula = formula, parse = TRUE,size=3)

enter image description here

Upvotes: 2

Related Questions