Faceting implies you want a separate bar chart of fac1 for each level
of fac2 (or vice versa). Since it's not at all clear to me what you
want, let's try a few options and hopefully your expected graph is
somewhere in the mix.
When dealing with conditional relative frequencies, you want to
compute them outside of ggplot2 because stat_bin() doesn't behave
properly.
## --------- begin code chunk 1
set.seed(13)
fac1 <- factor(sample(letters[1:5], 500, replace = TRUE))
fac2 <- factor(sample(LETTERS[1:3], 500, replace = TRUE))
sex <- factor(sample(c("Male", "Female"), 500, replace = TRUE))
DF <- data.frame(fac1, fac2, sex)
rm(fac1, fac2, sex)
library(ggplot2)
# Start with the initial data frame
# Stacked bar charts of fac1 by levels of fac2
ggplot(DF, aes(x = fac2, fill = fac1)) +
theme_bw() +
geom_bar(position = "fill") +
ylab("Proportion")
# Separate bar charts of fac1 by levels of fac2
# Doesn't work because sum(..count..) from stat_bin() is
# the overall sum 500, not the conditional sums
ggplot(DF, aes(x = fac1)) +
geom_bar(aes(y = ..count../sum(..count..)), fill = "blue") +
facet_wrap(~ fac2)
## --------- end code chunk 1
Instead, generate a data frame of conditional relative frequencies and
pass that into ggplot(). This isn't too difficult to do in plyr,
although you could use dplyr, too. You could also convert your
prop.table() into a suitable data frame if you wish.
##------- begin code chunk 2
library(plyr)
# Use the count() function to generate a 3-way table of frequencies
# in data frame form in case you want to do something with gender later
T0 <- count(DF, c("fac1", "fac2", "sex"))
# Sum the frequencies over sex for each fac1/fac2 combination
T1 <- ddply(T0, .(fac1, fac2), summarise, freq = sum(freq))
## Equivalent to
## T1 <- count(DF, c("fac1", "fac2"))
# Compute the conditional proportions of fac1 within levels of fac2
T2 <- ddply(T1, "fac2", mutate, prop = freq/sum(freq))
# Separate facet for each level of fac2
# T2 is a data frame
ggplot(T2, aes(x = fac1, y = prop)) +
geom_bar(stat = "identity", fill = "blue") +
facet_wrap(~ fac2)
# Dodge fac1 by level of fac2
ggplot(T2, aes(x = fac2, y = prop, fill = fac1)) +
geom_bar(stat = "identity", position = "dodge")
# Stack fac2 by levels of fac1
# position = "fill" will look exactly the same with this input
ggplot(T2, aes(x = fac2, y = prop, fill = fac1)) +
geom_bar(stat = "identity", position = "stack")
## ------- end code chunk 2
Dennis