34

Using ggplot2 generate a plot which shows the following data.

df=data.frame(score=c(4,2,3,5,7,6,5,6,4,2,3,5,4,8),
              age=c(18,18,23,50,19,39,19,23,22,22,40,35,22,16))
str(df)
df

Instead of doing a frequency plot of the variables (see below code), I want to generate a plot of the average values for each x value. So I want to plot the average score at each age level. At age 18 on the x axis, we might have a 3 on the y axis for score. At age 23, we might have an average score of 4.5, and so forth (Edit: average values corrected). This would ideally be represented with a barplot.

ggplot(df, aes(x=factor(age), y=factor(score))) + geom_bar()

Error: stat_count() must not be used with a y aesthetic.

Just not sure how to do this in R with ggplot2 and can't seem to find anything on such plots. Statistically, I don't know if the plot I desire to plot is even the right thing to do, but that's a different store.

4
  • Did you want average values, because from your dataset average values at 18 age is 3 (not 3.5), and at 23 age - 4.5 (not 6.2)?
    – DrDom
    Commented Aug 8, 2012 at 5:27
  • Yeah, I want averages. In that example, I just made up some numbers w/o thinking about it.
    – ATMathew
    Commented Aug 8, 2012 at 5:37
  • 1
    @ATMathew, but since you're going making the effort of providing some sample data, you should also make sure that your sample output is accurate for the provided data. Otherwise, it leads to unnecessary confusion.... Commented Aug 8, 2012 at 5:54
  • Just as a comment, in case that you have different groups, like gender, and you want a plot with the group mean on it, aes(x=factor(age), y=score, group = gender, color = gender)), group separate the sample color just give them different colors and a legend
    – Jia Gao
    Commented Jan 18, 2018 at 0:20

4 Answers 4

73

You can use summary functions in ggplot. Here are two ways of achieving the same result:

# Option 1
ggplot(df, aes(x = factor(age), y = score)) + 
  geom_bar(stat = "summary", fun = "mean")

# Option 2
ggplot(df, aes(x = factor(age), y = score)) + 
  stat_summary(fun = "mean", geom = "bar")

enter image description here

Older versions of ggplot use fun.y instead of fun:

ggplot(df, aes(x = factor(age), y = score)) + 
  stat_summary(fun.y = "mean", geom = "bar")
4
  • Add a note about how the OP probably didn't want to convert the scores to a factor and you'll have my answer exactly.
    – joran
    Commented Aug 8, 2012 at 5:17
  • @DrDom, the answer is so obvious now that you've posted it! (+1) Commented Aug 8, 2012 at 5:21
  • @joran, yes, I've considered that in my answer. Since mean of factors will be meaningless value in this case. :)
    – DrDom
    Commented Aug 8, 2012 at 5:22
  • Hello, how can you add the mean as labels for each bar?
    – Bustergun
    Commented Mar 1, 2021 at 14:14
8

If I understood you right, you could try something like this:

library(plyr)
library(ggplot2)
ggplot(ddply(df, .(age), mean), aes(x=factor(age), y=factor(score))) + geom_bar()
1
  • 1
    what does the ".(age)" mean/do? Is that a base R thing or ggplot (/tidyverse?) specific?
    – Niki Herl
    Commented Jun 4, 2019 at 16:29
7

You can also use aggregate() in base R instead of loading another package.

temp = aggregate(list(score = df$score), list(age = factor(df$age)), mean)
ggplot(temp, aes(x = age, y = score)) + geom_bar()
0

Another option is doing a group_by of the x-values and summarise the "mean_score" per "age" using dplyr to do it in one pipe. Also you can use geom_col instead of geom_bar. Here is a reproducible example:

df=data.frame(score=c(4,2,3,5,7,6,5,6,4,2,3,5,4,8),
              age=c(18,18,23,50,19,39,19,23,22,22,40,35,22,16))
library(dplyr)
library(ggplot2)
df %>%
  group_by(age) %>%
  summarise(mean_score = mean(score)) %>%
  ggplot(aes(x = factor(age), y = mean_score)) +
  geom_col() +
  labs(x = "Age", y = "Mean score")

Created on 2022-08-26 with reprex v2.0.2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.