1

If I have some generic data.

dx <- data.frame(x = c(sample(letters[1:4], 1000, replace=TRUE)),
                 y = c(sample(letters[5:7], 1000, replace=TRUE)),
                 z = c(sample(1:10, 5000, replace=TRUE)))

dx$z <- as.factor(dx$z)

d <- ggplot(dx, aes(z, fill=z)) + 
  geom_bar() +
  facet_grid(y~x)

d

I am wanting to print each z percentages within each grid element (ae, be, af, etc)..

if i try and use geom_text( ... aes(label = paste(round(..count../sum(..count..)*100),"%"))

I get the percentages as a function of total Z

from what i have read it is easier to calculate the percentages prior to plotting.

I have tried using ddply function, as used in this question,
but it changes the length of my data. Where

m = ddply(data.frame(table(df)), .(x, y), mutate, pct = round(Freq/sum(Freq) * 100, 1))

attempting to then plot

    d <- ggplot(dx, 
                aes(z, fill =z)) +
  geom_bar() +
  facet_grid(y ~ x)+
  geom_text(position = "identity", aes(label = paste(round(m$pct), "%")),
            color = "black", y = 40) +
  scale_x_discrete(drop=F)

gives me the error

Error: Aesthetics must either be length one, or the same length as the dataProblems:paste(round(m$pct), "%")

Any help is greatly appreciated, whether it be a command within geom_text or using ddply

Community
  • 1
  • 1
lukeg
  • 1,327
  • 3
  • 10
  • 27
  • 2
    If you can use `dplyr`, you can get the grouped `z` percentages with: `dx %>% group_by(x, y) %>% summarise(pct=n()/sum(z))` – hrbrmstr Sep 12 '14 at 10:24

2 Answers2

3

Taking a lead from the question you linked:

You also need to pass the new dataframe returned by ddply to the geom_text call together with aesthetics.

library(ggplot2)
library(plyr)

# Reduced the dataset 
set.seed(1)
dx <- data.frame(x = sample(letters[1:2], 1000, replace=TRUE),
                 y = sample(letters[5:6], 1000, replace=TRUE),
                 z = factor(sample(1:3, 5000, replace=TRUE)))

# Your ddply call
m <- ddply(data.frame(table(dx)), .(x,y), mutate, 
                                     pct = round(Freq/sum(Freq) * 100, 0)) 

# Plot - with a little extra y-axis space for the label    
d <- ggplot(dx, aes(z, fill=z)) + 
                geom_bar() +
                scale_y_continuous(limits=c(0, 1.1*max(m$Freq))) +
                facet_grid(y~x)


d + geom_text(data=m, aes(x=z, y=Inf, label = paste0(pct, "%")), 
                                                  vjust = 1.5, size = 5) 

enter image description here

(i do think this is a lot of ink just to show N(%), especially if you have lots of facets and levels of z)

user20650
  • 24,654
  • 5
  • 56
  • 91
1

Not quite sure what share of z you meant but this one adds percentages across the grid up to 1.

require(plyr)
helper<-sum(dx$z)
datac <- ddply(dx, c("x","y"), summarise, zshare=sum(z)/helper)

dx$z <- as.factor(dx$z)

d <- ggplot(data=dx)
d <- d + geom_bar(aes(z, fill=z))
d <- d+ facet_grid(y~x) + geom_text(data=datac,aes(x=3,y=60,label=paste(round(zshare,3)*100,"%")))
d

enter image description here

CMichael
  • 1,856
  • 16
  • 20
  • thanks, but I want the percentage of each z value (1:10), in each grid. (ae, be, ce, de, af ...) that being, within each grid the sum of percentages should be 100 – lukeg Sep 12 '14 at 10:56