# How to compare two datasets with Q-Q plot using ggplot2?

As both a stats and R novice, I have been having a really difficult time trying to generate qqplots with an aspect ratio of 1:1. ggplot2 seems to offer far more control over plotting than the default R plotting packages, but I can't see how to do a qqplot in ggplot2 to compare two datasets.

So my question, what is the ggplot2 equivalent of something like:

qqplot(datset1,dataset2)


The easiest thing to do is just look at how qqplot works. So in R type:

R> qqplot
function (x, y, plot.it = TRUE, xlab = deparse(substitute(x)),
ylab = deparse(substitute(y)), ...)
{
sx <- sort(x)
sy <- sort(y)
lenx <- length(sx)
leny <- length(sy)
if (leny < lenx)
sx <- approx(1L:lenx, sx, n = leny)$y if (leny > lenx) sy <- approx(1L:leny, sy, n = lenx)$y
if (plot.it)
plot(sx, sy, xlab = xlab, ylab = ylab, ...)
invisible(list(x = sx, y = sy))
}
<environment: namespace:stats>


So to generate the plot we just have to get sx and sy, i.e:

x <- rnorm(10);y <- rnorm(20)

sx <- sort(x); sy <- sort(y)
lenx <- length(sx)
leny <- length(sy)
if (leny < lenx)sx <- approx(1L:lenx, sx, n = leny)$y if (leny > lenx)sy <- approx(1L:leny, sy, n = lenx)$y

require(ggplot2)
g = ggplot() + geom_point(aes(x=sx, y=sy))
g


• ggplot2 does have a stat_qq(), is there some way to use that? It seems to be designed to compare one vector to a theoretical distribution, I couldn't see how to use it to compare two different vectors. – Ken Williams Apr 20 '12 at 15:37
• You can actually get qqplot() to do all the sort/length/approx calculations for you: d <- as.data.frame(qqplot(x, y, plot.it=FALSE)); ggplot(d) + geom_point(aes(x=x, y=y)) – Ken Williams Apr 20 '12 at 16:04

I use this when I also want a normal line.

ggplot(data, aes(sample = data$column1)) + stat_qq(color="firebrick2", alpha=1) + geom_abline(intercept = mean(data$column1), slope = sd(data\$column1))

If your original need is just to control the aspect ratio, here's one way to do that:

x <- rnorm(1000)
y <- rnorm(1500, 2)

myqq <- function(x, y, ...) {
rg <- range(x, y, na.rm=T)
qqplot(x, y, xlim=rg, ylim=rg, ...)
}

myqq(x, y)