2011-01-18 8 views
29

fare facet in ggplot Mi piacerebbe molto spesso la percentuale da utilizzare al posto dei conteggi.percentuale su y lab in un diagramma a barre sfaccettato ggplot?

ad es.

test1 <- sample(letters[1:2], 100, replace=T) 
test2 <- sample(letters[3:8], 100, replace=T) 
test <- data.frame(cbind(test1,test2)) 
ggplot(test, aes(test2))+geom_bar()+facet_grid(~test1) 

Questo è molto facile, ma se N è diverso in sfaccettatura A rispetto alla faccetta B, sarebbe meglio Credo di confrontare le percentuali, in modo tale che le somme ogni sfaccettatura a 100%.

come faresti a raggiungere questo?

Spero che la mia domanda abbia un senso.

Cordiali saluti.

risposta

20

Prova questa:

# first make a dataframe with frequencies 
df <- as.data.frame(with(test, table(test1,test2))) 
# or with count() from plyr package as Hadley suggested 
df <- count(test, vars=c('test1', 'test2')) 
# next: compute percentages per group 
df <- ddply(df, .(test1), transform, p = Freq/sum(Freq)) 
# and plot 
ggplot(df, aes(test2, p))+geom_bar()+facet_grid(~test1) 

alt text

È inoltre possibile aggiungere + scale_y_continuous(formatter = "percent") alla trama per ggplot2 vers ion 0.8.9 o + scale_y_continuous(labels = percent_format()) per la versione 0.9.0.

+0

Questa è una soluzione molto migliore. +1 – Chase

+0

Questo è davvero bello - grazie mille! :-D – Andreas

+0

@Chase e @Andreas: grazie! Ho appena pubblicato un metodo più semplice (e penso: più bello) basato su questa domanda: http://stackoverflow.com/q/3695497/564164 – daroczig

1

Ecco una soluzione che dovrebbe farti muovere nella giusta direzione. Sono curioso di vedere se ci sono modi più efficienti per fare questo, perché questo sembra un po 'hacky e contorto. Possiamo utilizzare l'argomento integrato ..density.. per il y aesthetic, ma i fattori non funzionano lì. Quindi abbiamo anche bisogno di usare scale_x_discrete per etichettare in modo appropriato l'asse una volta convertito test2 in un oggetto numerico.

ggplot(data = test, aes(x = as.numeric(test2)))+ 
geom_bar(aes(y = ..density..), binwidth = .5)+ 
scale_x_discrete(limits = sort(unique(test$test2))) + 
facet_grid(~test1) + xlab("Test 2") + ylab("Density") 

Ma date un vortice e fatemi sapere cosa ne pensate.

Inoltre, è possibile accorciare la creazione dei dati di test in questo modo, che evita gli oggetti in più nel proprio ambiente e di dover cbind insieme:

test <- data.frame(
    test1 = sample(letters[1:2], 100, replace = TRUE), 
    test2 = sample(letters[3:8], 100, replace = TRUE) 
) 
+1

sì un po 'contorto - ma ancora grazie - meglio quindi quello che avevo :-) Non so se questa dovrebbe essere una caratteristica di ggplot. Potrei immaginare molte situazioni in cui sarebbe meglio quindi contare i conteggi. D'altra parte - potrebbe essere meglio mantenere i dati in un grafico separato :-) – Andreas

+0

La densità non è la stessa percentuale. – russellpierce

6

Un modo molto semplice:

ggplot(test, aes(test2)) + 
    geom_bar(aes(y = (..count..)/sum(..count..))) + 
    facet_grid(~test1) 

Così ho cambiato solo il parametro di geom_bar a aes(y = (..count..)/sum(..count..)). Dopo aver impostato ylab a NULL e specificando il formattatore, si potrebbe ottenere:

ggplot(test, aes(test2)) + 
    geom_bar(aes(y = (..count..)/sum(..count..))) + 
    facet_grid(~test1) + 
    scale_y_continuous('', formatter="percent") 

Aggiornamento Nota che mentre formatter = "percent") lavori per ggplot2 versione 0.8.9, in 0.9.0 che ci si vuole qualcosa di simile scale_y_continuous(labels = percent_format()). alt text

+0

ghezus - In realtà penso che qualcuno su SO abbia risposto per me prima. Mi sono messo in imbarazzo per me, spero che questo avvenga da ora in poi. Grazie ancora. – Andreas

+4

in realtà è scale_y_continuous (labels = percent) (utilizzando il pacchetto scale) – dickoa

+0

qualcuno può aiutarmi a capire il significato di .. nella dichiarazione di cui sopra (..count ..)/sum (.. count ..) ?? – Abhi

0

Mi occupo di situazioni simili con una certa frequenza, ma ho un approccio molto diverso che utilizza due degli altri pacchetti di Hadley, ovvero rimodella e plyr. Principalmente perché preferisco considerare le cose come barre impilate al 100% (quando sono totali al 100%).

test <- data.frame(sample(letters[1:2], 100, replace=T), sample(letters[3:8], 100, replace=T)) 
colnames(test) <- c("variable","value") 
test <- cast(test, variable + value ~ .) 
colnames(test)[3] <- "frequ" 

test <- ddply(test,"variable", function(x) { 
    x <- x[order(x$value),] 
    x$cfreq <- cumsum(x$frequ)/sum(x$frequ) 
    x$pos <- (c(0,x$cfreq[-nrow(x)])+x$cfreq)/2 
    x$freq <- (x$frequ)/sum(x$frequ) 
    x 
}) 

plot.tmp <- ggplot(test, aes(variable,frequ, fill=value)) + geom_bar(stat="identity", position="fill") + coord_flip() + scale_y_continuous("", formatter="percent") 
43

Ecco una all'interno ggplot metodo, utilizzando ..count.. e ..PANEL..:

ggplot(test, aes(test2)) + 
    geom_bar(aes(y = (..count..)/tapply(..count..,..PANEL..,sum)[..PANEL..])) + 
    facet_grid(~test1) 

Dato che questo viene calcolata al volo, dovrebbe essere robusto per le modifiche per tracciare i parametri.

+0

Questo è un ottimo approccio. Pensi che sia possibile aggiungere etichette percentuali a ogni barra che si aggiungono al 100% in ogni sfaccettatura? – marbel

+0

@ MartínBel Sembra che 'geom_text' non funzioni con le variabili calcolate. Potresti postare come una domanda separata. – James

+2

Sicuro. Ecco la [domanda] (http://stackoverflow.com/questions/20600900/r-faceted-bar-chart-with-percentages-labels-independent-for-each-plot) La lascio qui per riferimenti futuri. – marbel

0

Grazie per aver condiviso il "suggerimento" PANEL sul metodo ggplot.

Per informazioni: è possibile produrre le percentuali in y lab, sullo stesso grafico a barre, utilizzando count e group nel metodo ggplot:

ggplot(test, aes(test2,fill=test1)) 
    + geom_bar(aes(y = (..count..)/tapply(..count..,..group..,sum)[..group..]), position="dodge") 
    + scale_y_continuous(labels = percent) 
+0

Mentre altri potrebbero pensare che questo sarebbe forse più adatto come commento e non come risposta, ho dato questa risposta +1 perché mi ha aiutato a risolvere un problema che stavo avendo e volevo ringraziare Lilly per aver postato questo. – paleo13