2
votes

I am trying to create a ggplot2 graph of fixed effects for prototypic individuals from different groups in a longitudinal dataset (charting the effect of race and years of education on wages growth). Rather than using the dataset itself I am trying to create a line graph based on the coefficients for intercept and slope from a mixed-effects model. Thus I have created a blank frame and added ablines to it. However I would like to add a legend to the plot that explains these lines. Here is the code I have used to create the plot.

df <- data.frame() 
fixef.c <- list(intercept0 = 1.72, slope0 = 0.04, intercept1 = 0.038, slope1 = -0.016) 
ggplot(df) + xlim(0, 12) + ylim(1.6, 2.4) + 
  geom_abline(intercept = fixef.c[[1]], slope = fixef.c[[2]]) +
  geom_abline(intercept = fixef.c[[1]] + fixef.c[[3]]*3, slope = fixef.c[[2]], linetype = 2) +
  geom_abline(intercept = fixef.c[[1]], slope = fixef.c[[2]] + fixef.c[[4]], linetype = 3) +
  geom_abline(intercept = fixef.c[[1]] +  fixef.c[[3]]*3, slope = fixef.c[[4]] + fixef.c[[2]], linetype = 4) +
  xlab("Log Wages") +
  ylab("Years Experience")

I need to know how to add a custom legend to this plot that explains the lines. Ideally I would like the legend placed in the same location and with similar labels to the plot below created using the base graphics package. (Note: I tried adding show.legend = TRUE to each of the abline functions but it did not work.

exper.seq <- seq(0, 12)
x.w9 <- fixef.c[[1]] + fixef.c[[2]]*exper.seq
x.w12 <-  fixef.c[[1]] + fixef.c[[2]]*exper.seq + fixef.c[[3]]*3
x.b9 <- fixef.c[[1]] + fixef.c[[2]]*exper.seq + fixef.c[[4]]*exper.seq
x.b12 <- fixef.c[[1]] + fixef.c[[2]]*exper.seq + fixef.c[[3]]*3 + 
         fixef.c[[4]]*exper.seq
plot(exper.seq, x.w9, ylim=c(1.6, 2.4), ylab="LNW.hat", xlab="EXPER", type="l", lwd=2)
lines(exper.seq, x.w12, lty=3)
lines(exper.seq, x.b9, lty=4, lwd=2)
lines(exper.seq, x.b12, lty=5)
legend(0, 2.4, c("9th grade, White/Latino", "9th grade, Black", 
       "12th grade, White/Latino", "12th grade, Black"), lty=c(1, 4, 3, 5))
1

1 Answers

2
votes

If you can concede to creating an object which holds intercept and slope, along with grouping, this is a fairly straightforward task.

xy <- as.data.frame(
  rbind(line1 = c(intercept = fixef.c[[1]], slope = fixef.c[[2]]),
      line2 = c(intercept = fixef.c[[1]] + fixef.c[[3]]*3, slope = fixef.c[[2]]),
      line3 = c(fixef.c[[1]], slope = fixef.c[[2]] + fixef.c[[4]]),
      line4 = c(fixef.c[[1]] +  fixef.c[[3]]*3, slope = fixef.c[[4]] + fixef.c[[2]]))
)
xy$design <- rownames(xy)

ggplot() + 
  xlim(0, 12) + ylim(1.6, 2.4) +
  geom_abline(data = xy, aes(intercept = intercept, slope = slope, linetype = design))

You can also modify what linetype belong to which level.

scale_linetype_manual(values = c(line1 = "solid", line2 = "dashed", line3 = "dotted", line4 = "dotdash")) +

enter image description here