I want to create a ggplot
with dual Y axis. On the left Y axis I want to show the average duration, while on the right Y axis - the average absolute frequency per weekday (i.e. the average number of occurances of each weekday over different dates).
df = data.frame(c("18/10/2016","18/10/2016","14/10/2016","20/10/2016","11/10/2016"),
c("tuesday","tuesday","friday","thursday","tuesday"),
c("20","12","23","24","21"))
colnames(df) = c("date","day","duration")
This is what I tried so far (this code works, but please see the list of issues below):
library("gtable")
library("grid")
library("ggplot2")
#two plots
p1 <- ggplot(df, aes(day, duration)) +
geom_line(colour="#000099", position = "dodge",
stat = "summary", fun.y = "mean") +
geom_point(size=3, colour="#CC0000") +
ylab("Average duration") +
theme_bw()
p2 <- ggplot(df) +
geom_bar(aes(x=day), fill="#FF9999", colour="black",
position = "dodge", stat = "summary", fun.y = "mean") +
ylab("Absolute frequency") +
theme_bw()
# extract gtable
g1 <- ggplot_gtable(ggplot_build(p1))
g2 <- ggplot_gtable(ggplot_build(p2))
# overlap the panel of 2nd plot on that of 1st plot
pp <- c(subset(g1$layout, name == "panel", se = t:r))
g <- gtable_add_grob(g1, g2$grobs[[which(g2$layout$name == "panel")]], pp$t,
pp$l, pp$b, pp$l)
# axis tweaks
ia <- which(g2$layout$name == "axis-l")
ga <- g2$grobs[[ia]]
ax <- ga$children[[2]]
ax$widths <- rev(ax$widths)
ax$grobs <- rev(ax$grobs)
## DO NOT UNDERSTAND THIS LINE
ax$grobs[[1]]$x <- ax$grobs[[1]]$x - unit(1, "npc") + unit(0.15, "cm")
g <- gtable_add_cols(g, g2$widths[g2$layout[ia, ]$l], length(g$widths) - 1)
g <- gtable_add_grob(g, ax, pp$t, length(g$widths) - 1, pp$b)
# draw it
grid.draw(g)
There are the following problems with this code:
1) I can only see bars (p2
), but I don't see p1
- a blue line with red dots.
2) The label of the right Y axis (p2
) does not appear
3) And the MOST important: It looks like p2
counts total number of occurences of weekdays, e.g. 4 tuesdays. However I want to group them by dates. For example, there are 2 occurances of tuesdays, 18/10/2016, AND there is 1 occurance of tuesday, 11/10/2016. So, ON AVERAGE (2+1)/2 => 1.5.