1

I'm working with a really big data setcontaining one dummy variable and a factor variable with 14 levels- a sample of which I have posted here. I'm trying to make a stacked proportional bar graph using the following code:

ggplot(data,aes(factor(data$factor),fill=data$dummy))+
geom_bar(position="fill")+
ylab("Proportion")+
theme(axis.title.y=element_text(angle=0))

It works great and its almost the plot I need. I just want to add small text labels reporting the number of observations of each factor level. My intuition tells me that something like this should work

Labels<-c("n=1853" , "n=392",  "n=181" ,  "n=80",   "n=69",   "n=32" ,  "n=10",    "n=6",    "n=4",    "n=5",    "n=3",    "n=3",    "n=2",    "n=1" ) 
ggplot(data,aes(factor(data$factor),fill=data$dummy))+
geom_bar(position="fill")+
geom_text(aes(label=Labels,y=.5))+
ylab("Proportion")+
theme(axis.title.y=element_text(angle=0))

But it spits out a blank graph and the error Aesthetics must either be length one, or the same length as the dataProblems:Labels

this really doesn't make sense to me because I know for a fact that the length of my factor levels is the same length as the number of labels I muscled in. I've been trying to figure out how I can get it to just print what I need without creating a vector of values for the number of observations like this example, but no matter what I try I always get the same Aesthetics error.

Community
  • 1
  • 1
slap-a-da-bias
  • 376
  • 1
  • 6
  • 25
  • 1
    Don't use `$` inside `aes()`, it's asking for trouble if your plot get's more complicated (e.g., facets). eipi's answer corrects this nicely. – Gregor Thomas Jul 02 '15 at 15:21

1 Answers1

3

How about this:

library(dplyr)

# Create a separate data frame of counts for the count labels
counts = data %>% group_by(factor) %>%
  summarise(n=n()) %>%
  mutate(dummy=NA)

counts$factor = factor(counts$factor, levels=0:10)

ggplot(data, aes(factor(factor), fill=factor(dummy))) +
  geom_bar(position="fill") +
  geom_text(data=counts, aes(label=n, x=factor, y=-0.03), size=4) +
  ylab("Proportion")+
  theme(axis.title.y=element_text(angle=0))

Your method is the right idea, but Labels needs to be a data frame, rather than a vector. geom_text needs to be given the name of the data frame using the data argument. Then, the label argument inside aes tells geom_text which column to use for the labels. Also, even though geom_text doesn't use the dummy column, it has to be in the data frame or you'll get an error.

eipi10
  • 91,525
  • 24
  • 209
  • 285