Superposed xyplot Panels with Grouped Regression Lines

Matthew Lundberg picture Matthew Lundberg · Jan 6, 2013 · Viewed 7.8k times · Source

I want to superpose multiple groups on a single panel in lattice, and want independent regression lines.

It is fairly easy to get multiple panels, each with a regression line by using a conditioning factor:

xyplot(
  Petal.Width  ~ Petal.Length | Species,
  data = iris,
  panel = function(x, y, ...) {
    panel.xyplot(x, y, ...)
    panel.abline(lm(y~x), col='#0080ff')
  },
  grid = TRUE
)

enter image description here

It is also fairly easy to print a single regression for all of the points in a superposed xyplot:

xyplot(
  Petal.Width ~ Petal.Length,
  data = iris,
  groups = Species,
  panel = function(x, y, ...) {
    panel.xyplot(x, y, ...)
    panel.abline(lm(y~x))
  },
  grid = TRUE,
  auto.key = list(title='Species', space='right')
)

enter image description here

But this is not what I need. I will enter an answer to this, but it seems messy. Perhaps that's just the nature of the beast.

I'm looking for something that is easier to understand. Lattice is preferred, but a good ggplot solution may be accepted as well. If it isn't clear, I'm making plots for consumption by Excel users.

Answer

Matthew Lundberg picture Matthew Lundberg · Jan 6, 2013

Here is what I came up with:

xyplot(
  Petal.Width  ~ Petal.Length,
  groups = Species,
  data = iris,
  panel = function(x, y, ...) {
    panel.superpose(x, y, ...,
                    panel.groups = function(x,y, col, col.symbol, ...) {
                      panel.xyplot(x, y, col=col.symbol, ...)
                      panel.abline(lm(y~x), col.line=col.symbol)
                    }
    )
  },
  grid = TRUE,
  auto.key = list(title='Species', space='right')
)

enter image description here