2

I know that this question has been asked very often, but I tried all the method I found and none of them seems to work..

This is my current data.

df <- data.frame(ID = c(1,2,3,4), Type = c("A","B","A","B"), Score1 = c(10,20,30,40), Score2 = c(20,40,60,80))
ID   Type    Score1       Score2
1       A        10           20
2       B        20           40
3       A        30           60
4       B        40           80

and now I want to make a graph that looks like this Edit: I placed the wrong graph > It should look like this

enter image description here

I am able to achieve the bar graph using the reshape and ggplot

rawscore <- df[, c("Type","Score1", "Score2")]
rawscore <- melt(rawscore, id = c("Type"))
ggplot(rawscore, aes(type, value, fill=variable))+
geom_bar(stat="summary", fun.y="mean", position="dodge")

However, I struggles to add the number of observation on the graph I know that I should use geom_text to put the label on the graph, so I tried creating the new vector from this post

nlabels <- table(Type)

but I got an error saying

Error: Aesthetics must be either length 1 or the same as the data

Any suggestions?

Maru
  • 163
  • 1
  • 2
  • 10

2 Answers2

2
df <- data.frame(ID = c(1,2,3,4), Type = c("A","B","A","B"), Score1 = c(10,20,30,40), Score2 = c(20,40,60,80))


rawscore <- df[, c("Type","Score1", "Score2")]
rawscore <- melt(rawscore, id = c("Type"))

Try to construct another data.frame (EDIT)

library(dplyr)

dfmean <- rawscore %>% 
  group_by(interaction(variable, Type)) %>% 
  summarise(m = mean(value), count = n())
names(dfmean)[1] <- "Inter"

ggplot(rawscore, aes(x = interaction(variable, Type), y = value)) + 
  geom_bar(aes(fill = variable), stat="summary", fun.y="mean", position="dodge") +
  geom_text(data = dfmean, aes(x = Inter, y = m + 1, label = count))

enter image description here

abichat
  • 2,317
  • 2
  • 21
  • 39
  • My apologies I just updated my graph and command, but I will try your method as well. However, I'm looking for placing the number of observations on the bar not the average, but I will see if I can play around with your command – Maru Jul 19 '17 at 13:09
  • Yes, I see it. So try `dfmean <- rawscore %>% group_by(interaction(variable, Type)) %>% summarise(count = n())` – abichat Jul 19 '17 at 13:14
  • I tried your command above and it works perfectly!. However, I spent a lot of time trying to apply this to my actual data, but I still got `Error: Aesthetics must be either length 1 or the same as the data (4)` Any ideas what is the cause? I ran `length` for the variable and it is the same as the data... The answer below works, but I want to apply this method for some of the graph that does not require `reshape` the data such that I can just refer to the variable count for all of these graph without reshaping the data again and again. (if that makes sense?) – Maru Jul 20 '17 at 23:17
  • I don't know precisely what you mean... Reshape your data (with `reshape2` or `dplyr`) is necessary because `ggplot2` works with tidy data. – abichat Jul 21 '17 at 06:29
2

A small change in the answer by @Florian.

library(dplyr)
rawscore <- df[, c("Type","Score1", "Score2")]
rawscore <- melt(rawscore, id = c("Type")) %>%
    group_by(variable) %>% summarize(value=mean(value), count = n())

ggplot(rawscore, aes(variable, value, fill=variable))+
    geom_bar(stat="identity") +
    geom_text(aes(label=count), vjust=0)

This works perfectly

enter image description here

Koundy
  • 5,265
  • 3
  • 24
  • 37