Giorgio
Giorgio

Reputation: 41

Use ggplot to plot partial effects obtained with effects library

I would like to use ggplot to replicate the plots partial effects (with partial residuals), as obtained with the "effect" package. To do this I need to retrieve some information. This is the plot I want to replicate with ggplot.

library(effects)    
mod <- lm(log(prestige) ~ income:type + education, data=Prestige)
eff = effect("education", mod, partial.residuals=T)

plot(eff)

Partial effect plot of Education Term

From the eff object I am able to retrieve the partial residuals, as eff$residuals, but they are not sufficient to replicate the plot. I think that what I need is the both the residuals, AND the marginal predicted effect. However I was not able to retrieve them from my eff object. Otherwise I only have the residuals scores that cannot be plotted against the line of the marginal effect.

Any hint on how to retrieve this information?

Upvotes: 0

Views: 3652

Answers (1)

Roman Luštrik
Roman Luštrik

Reputation: 70633

You have almost all the information available. This would take some more time to generalize, but here's some code that results in a figure approximately like from the effects package. Notice that the smoother is off, but I didn't bother to dig up why.

The code should be self explanatory. I only copied function closest from the package.

mod <- lm(log(prestige) ~ income:type + education, data=Prestige)
eff = effect("education", mod, partial.residuals=T)

library(ggplot2)
library(gridExtra)

closest <- function(x, x0) apply(outer(x, x0, FUN=function(x, x0) abs(x - x0)), 1, which.min)

x.fit <- unlist(eff$x.all)
trans <- I
x <- data.frame(lower = eff$lower, upper = eff$upper, fit = eff$fit, education = eff$x$education)
xy <- data.frame(x = x.fit, y = x$fit[closest(trans(x.fit), x$education)] + eff$residuals)

g <- ggplot(x, aes(x = education, y = fit)) +
  theme_bw() +
  geom_line(size = 1) +
  geom_point(data = xy, aes(x = x, y = y), shape = 1, col = "blue", size = 2) +
  geom_ribbon(aes(ymin = lower, ymax = upper), alpha = 0.5) +
  geom_smooth(data = xy, aes(x = trans(x), y = y), 
              method = "loess", span = 2/3, linetype = "dashed", se = FALSE)

grid.arrange(plot(eff), g, ncol = 2)

enter image description here

Upvotes: 3

Related Questions