looking for elegant solution to add respective regression lines in a facetted ggplot scatter

599 views
Skip to first unread message

Jon Hill

unread,
Nov 13, 2013, 7:11:17 PM11/13/13
to ggp...@googlegroups.com
I'm trying to add the unique unique linear regression line and its corresponding rsquare and equation to each plot of a faceted scatterplot.

I'm able to get the scatter to facet correctly, but the line that is printed is for the one I indexed. How do I control each facet?

require(ggplot2)

bin1<-subset(intelli, intelli$BIN=="BIN1") #subset data by BIN
bin2<-subset(intelli, intelli$BIN=="BIN2") #
bin3<-subset(intelli, intelli$BIN=="BIN3") #


intelli <- read.csv("data/intellidata.csv")

lin1 <- lm(INTELLI ~ MANUAL, data = bin1)
lin2 <- lm(INTELLI ~ MANUAL, data = bin2)
lin3 <- lm(INTELLI ~ MANUAL, data = bin3)

coef1 <- lin1$coefficients
coef2 <- lin2$coefficients
coef3 <- lin3$coefficients



ggplot(data=intelli, aes(x=MANUAL,y=INTELLI)) +
  geom_point(pch=19,size=3.5,color="blue") +
  xlab("Manual Count") +
  ylab("IntelliHat Count") +
  ggtitle("IntelliHat Count vs Manual Count") +
  facet_grid(~BIN) +
  xlim(0,500) +
  ylim(0,500) +
  geom_abline(lty=2,size=1.2) +
  geom_abline(slope=coef1[2], intercept=coef1[1], size=1.3, col="red") +
  geom_text(data = NULL, x = 250, y = 480, label="", col="red")


Dennis Murphy

unread,
Nov 14, 2013, 8:10:57 AM11/14/13
to Jon Hill, ggplot2
Hi:

This is just a Q & D reproducible example to give you an idea how the
game works. There are many ways in which the details could be
modified. There are also several past examples of how to do this in
the group archives.

# Generate some fake data
x <- seq(10)
DF <- data.frame(x = x, y1 = 0.5 + 0.8 * x + rnorm(10),
y2 = 0.7 - 0.2 * x + rnorm(10))

# Fit a linear model to each of y1 and y2
m1 <- lm(y1 ~ x, data = DF)
m2 <- lm(y2 ~ x, data = DF)

# Load some packages
library(ggplot2)
library(reshape2)
library(plyr)

# Create a vector of the R^2 values from each model
r2 <- c(summary(m1)[["r.squared"]], summary(m2)[["r.squared"]])

# Melt the original data to stack the two y-variables - this will allow
# you to facet them in the ggplot
DFm <- melt(DF, id = "x")

# Create a data frame for the labels, which has several pieces:
# * a variable for the levels of the faceting variable, so ggplot2 knows
# that different labels go in different panels
# * a vector of (x, y) positions for the labels
# * text string representations of plotmath calls for each of the fitted
# models and R^2s. The parse = TRUE argument in geom_text()
# will convert them into expressions and render them in the plot
#
# I renamed the intercept and slope terms to simplify the text string
# creation and rounded off the input values from the models up front
# to avoid complicating the text string code.

DFeq <- data.frame(variable = c("y1", "y2"),
x = 2.5, y0 = 9.0, y1 = 8.5,
rbind(round(coef(m1), 3), round(coef(m2), 3)),
rsq = round(r2, 3))
names(DFeq)[5:6] <- c("b0", "b1")
DFeq[["modeq"]] <- with(DFeq, paste0("hat(y) == ", b0, " + ", b1, "~X"))
DFeq[["rsquare"]] <- with(DFeq, paste0("R^2 == ", rsq))

# Now generate the plot. Note the use of DFeq as the input
# data frame for geom_text() and the use of parse = TRUE to convert
# the text strings into plotmath expressions. Use geom_smooth() to
# plot the fitted least squares line in each panel with method = "lm".

ggplot(data = DFm, aes(x = x, y = value)) +
geom_point() +
geom_smooth(method = "lm", size = 1, se = FALSE) +
geom_text(data = DFeq, aes(x = x, y = y0, label = modeq),
parse = TRUE, hjust = 0) +
geom_text(data = DFeq, aes(x = x, y = y1, label = rsquare),
parse = TRUE, hjust = 0) +
facet_wrap(~ variable)

The formula for the model with the negative slope is ugly and could be
easily fixed with an if statement to generate the + or - sign that
could then be passed to paste0, but I'll leave that as an exercise.

Dennis
> --
> --
> You received this message because you are subscribed to the ggplot2 mailing
> list.
> Please provide a reproducible example:
> https://github.com/hadley/devtools/wiki/Reproducibility
>
> To post: email ggp...@googlegroups.com
> To unsubscribe: email ggplot2+u...@googlegroups.com
> More options: http://groups.google.com/group/ggplot2
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ggplot2" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to ggplot2+u...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
Reply all
Reply to author
Forward
0 new messages