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
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)
(i do think this is a lot of ink just to show N(%), especially if you have lots of facets and levels of z)