Erstellen eines Pareto-Diagramm mit ggplot2 und R
Frage
Ich habe zu kämpfen mit, wie ein Pareto-Diagramm in R zu machen, das ggplot2 Paket mit . In vielen Fällen, wenn sie ein Balkendiagramm oder Histogramm wir Einzelteile durch die X-Achse sortiert werden sollen. In einem Pareto-Diagramm wollen wir die Einzelteile durch den Wert in der Y-Achse bestellt absteigend. Gibt es eine Möglichkeit ggplot auf Grundstück bestellten Artikel durch den Wert in der Y-Achse zu bekommen? Ich habe versucht, den Datenrahmen erste Sortieranlage, aber es scheint ggplot Nachbestellungen sie.
Beispiel:
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")
der Datenrahmen val sortiert wird, aber die Ausgabe sieht wie folgt aus:
(Quelle: cerebralmastication.com )
Hadley zu Recht darauf hin, dass dies eine viel bessere Grafik erzeugt für die Ansicht Istdaten gegen vorhergesagt:
ggplot(val, aes(State, Value)) + geom_bar(stat = "identity", subset = .(variable == "estimate"), fill = "grey70") + geom_crossbar(aes(ymin = Value, ymax = Value), subset = .(variable == "actual"))
die Rückgabe:
(Quelle: cerebralmastication.com )
Aber es ist noch kein Pareto-Diagramm. Irgendwelche Tipps?
Lösung
Die Balken in ggplot2 werden durch die Anordnung des Spiegels im Faktor bestellt.
val$State <- with(val, factor(val$State, levels=val[order(-Value), ]$State))
Andere Tipps
Untereinstellung und Ihre Daten Sortieren;
valact <- subset(val, variable=='actual')
valsort <- valact[ order(-valact[,"Value"]),]
Von dort ist es nur ein Standard-boxplot()
mit einer sehr manuellen kumulativen Funktion auf:
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)
, die wie dieser
aussehen sollte
(Quelle: eddelbuettel.com )
und es nicht einmal braucht den overplotting Trick als lines()
glücklich die ursprüngliche Handlung annotiert.
Ein traditionelles Pareto-Diagramm in ggplot2 .......
Entwickelt nach dem Lesen Cano, E. L., Moguerza, J. M., & Redchuk, A. (2012). Six Sigma mit R. (G. Robert K. Hornik & G. Parmigiani, Hrsg.) Springer.
library(ggplot2);library(grid)
counts <- c(80, 27, 66, 94, 33)
defects <- c("price code", "schedule date", "supplier code", "contact num.", "part num.")
dat <- data.frame(count = counts, defect = defects, stringsAsFactors=FALSE )
dat <- dat[order(dat$count, decreasing=TRUE),]
dat$defect <- factor(dat$defect, levels=dat$defect)
dat$cum <- cumsum(dat$count)
count.sum<-sum(dat$count)
dat$cum_perc<-100*dat$cum/count.sum
p1<-ggplot(dat, aes(x=defect, y=cum_perc, group=1))
p1<-p1 + geom_point(aes(colour=defect), size=4) + geom_path()
p1<-p1+ ggtitle('Pareto Chart')+ theme(axis.ticks.x = element_blank(), axis.title.x = element_blank(),axis.text.x = element_blank())
p1<-p1+theme(legend.position="none")
p2<-ggplot(dat, aes(x=defect, y=count,colour=defect, fill=defect))
p2<- p2 + geom_bar()
p2<-p2+theme(legend.position="none")
plot.new()
grid.newpage()
pushViewport(viewport(layout = grid.layout(2, 1)))
print(p1, vp = viewport(layout.pos.row = 1,layout.pos.col = 1))
print(p2, vp = viewport(layout.pos.row = 2,layout.pos.col = 1))
Mit einem einfachen Beispiel:
> data
PC1 PC2 PC3 PC4 PC5 PC6 PC7 PC8 PC9 PC10
0.29056 0.23833 0.11003 0.05549 0.04678 0.03788 0.02770 0.02323 0.02211 0.01925
barplot(data)
tut Dinge richtig
das ggplot Äquivalent "sollte": qplot(x=names(data), y=data, geom='bar')
Aber das falsch Nachbestellungen / sortiert die Bars alphabetisch ... weil das ist, wie levels(factor(names(data)))
bestellt werden würde.
Lösung: qplot(x=factor(names(data), levels=names(data)), y=data, geom='bar')
Puh!
Auch finden Sie im Paket qcc , die eine Funktion pareto.chart()
hat. Sieht aus wie es zu Basis Grafiken verwendet, so dass Ihre Prämie für eine ggplot2-Lösung starten: -)
Dinge vereinfachen, wollen wir betrachten gerade nur die Schätzungen.
estimates <- subset(val, variable == "estimate")
Zuerst neu ordnen wir die Faktorstufen, so dass State
s in absteigender Reihenfolge der Value
aufgetragen sind.
estimates$State <- with(estimates, reorder(State, -Value))
In ähnlicher Weise neu ordnen wir den Datensatz und einen kumulativen Wert berechnen.
estimates <- estimates[order(estimates$Value, decreasing = TRUE),]
estimates$cumulative <- cumsum(estimates$Value)
Jetzt sind wir bereit, das Grundstück zu ziehen. Der Trick, um eine Linie und eine Bar auf den gleichen Achsen zu erhalten, ist die Zustandsgröße (Faktor) numerisch sein zu konvertieren.
p <- ggplot(estimates, aes(State, Value)) +
geom_bar() +
geom_line(aes(as.numeric(State), cumulative))
p
erwähnt Wie in der Frage, die versuchen, zwei Pareto Plots von zwei variablen Gruppen zu ziehen direkt neben einander nicht ganz einfach ist. Sie würden wahrscheinlich besser dran mit Facettieren, wenn Sie mehr Pareto Diagramme wollen.
freqplot = function(x, by = NULL, right = FALSE)
{
if(is.null(by)) stop('Valor de "by" precisa ser especificado.')
breaks = seq(min(x), max(x), by = by )
ecd = ecdf(x)
den = ecd(breaks)
table = table(cut(x, breaks = breaks, right = right))
table = table/sum(table)
intervs = factor(names(table), levels = names(table))
freq = as.numeric(table/sum(table))
acum = as.numeric(cumsum(table))
normalize.vec = function(x){
(x - min(x))/(max(x) - min(x))
}
dados = data.frame(classe = intervs, freq = freq, acum = acum, acum_norm = normalize.vec(acum))
p = ggplot(dados) +
geom_bar(aes(classe, freq, fill = classe), stat = 'identity') +
geom_point(aes(classe, acum_norm, group = '1'), shape = I(1), size = I(3), colour = 'gray20') +
geom_line(aes(classe, acum_norm, group = '1'), colour = I('gray20'))
p
}