I have been struggling with how to make a Pareto Chart in R using the ggplot2 package. In many cases when making a bar chart or histogram we want items sorted by the X axis. In a Pareto Chart we want the items ordered descending by the value in the Y axis. Is there a way to get ggplot to plot items ordered by the value in the Y axis? I tried sorting the data frame first but it seems ggplot reorders them.
Example:
val <- read.csv("http://www.cerebralmastication.com/wp-content/uploads/2009/11/val.txt")
val<-with(val, val[order(-Value), ])
p <- ggplot(val)
p + geom_bar(aes(State, Value, fill=variable), stat = "identity", position="dodge") + scale_fill_brewer(palette = "Set1")
the data frame val is sorted but the output looks like this:
(source: cerebralmastication.com)
Hadley correctly pointed out that this produces a much better graphic for showing actuals vs. predicted:
ggplot(val, aes(State, Value)) + geom_bar(stat = "identity", subset = .(variable == "estimate"), fill = "grey70") + geom_crossbar(aes(ymin = Value, ymax = Value), subset = .(variable == "actual"))
which returns:
(source: cerebralmastication.com)
But it's still not a Pareto Chart. Any tips?
Click Insert > Insert Statistic Chart, and then under Histogram, pick Pareto. You can also use the All Charts tab in Recommended Charts to create a Pareto chart (click Insert > Recommended Charts > All Charts tab.
80/20 Rule – The Pareto Principle. The 80/20 Rule (also known as the Pareto principle or the law of the vital few & trivial many) states that, for many events, roughly 80% of the effects come from 20% of the causes.
Subsetting and sorting your data;
valact <- subset(val, variable=='actual')
valsort <- valact[ order(-valact[,"Value"]),]
From there it's just a standard boxplot()
with a very manual cumulative function on top:
op <- par(mar=c(3,3,3,3))
bp <- barplot(valsort [ , "Value"], ylab="", xlab="", ylim=c(0,1),
names.arg=as.character(valsort[,"State"]), main="How's that?")
lines(bp, cumsum(valsort[,"Value"])/sum(valsort[,"Value"]),
ylim=c(0,1.05), col='red')
axis(4)
box()
par(op)
which should look like this
(source: eddelbuettel.com)
and it doesn't even need the overplotting trick as lines()
happily annotates the initial plot.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With