2011-01-18 20 views
29

haciendo facetas en ggplot A menudo me gustaría usar el porcentaje en lugar de conteos.porcentaje en y lab en un diagrama de barras ggplot facetado?

p. Ej.

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) 

Esto es muy fácil, pero si N es diferente en comparación con las facetas Una faceta B, sería mejor, creo, para comparar porcentajes, de tal manera que las sumas cada faceta a 100%.

¿cómo lograrías esto?

Espero que mi pregunta tenga sentido.

Atentamente.

Respuesta

20

Prueba esto:

# 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

también puede añadir + scale_y_continuous(formatter = "percent") a la parcela para ggplot2 vers ion 0.8.9 o + scale_y_continuous(labels = percent_format()) para la versión 0.9.0.

+0

Esta es una solución mucho mejor. +1 – Chase

+0

Eso es realmente agradable, ¡muchas gracias! :-D – Andreas

+0

@Chase y @Andreas: ¡gracias! Acabo de publicar un método más simple (y creo que más bonito) basado en esta pregunta: http://stackoverflow.com/q/3695497/564164 – daroczig

1

Aquí hay una solución que debería hacerlo avanzar en la dirección correcta. Tengo curiosidad por ver si hay formas más eficientes de hacer esto, ya que esto parece un poco hacky y complicado. Podemos usar el argumento construido en ..density.. para el y aesthetic, pero los factores no funcionan allí. Entonces también necesitamos usar scale_x_discrete para etiquetar apropiadamente el eje una vez que convertimos test2 en un objeto numérico.

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") 

Pero denle un giro y háganme saber lo que piensan.

Además, se puede acortar la creación de datos de prueba como tal, que evite los objetos adicionales en su entorno y tener que cbind juntos:

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

sí un poco complicado - pero aún así, gracias - mejor que lo que tenía :-) No sé si esto debería ser una característica de ggplot. Podría imaginar muchas situaciones en las que sería mejor que contar. Por otro lado, podría ser mejor mantener los datos mungering af graphing separados :-) – Andreas

+0

La densidad no es lo mismo que el porcentaje. – russellpierce

6

Una forma muy sencilla:

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

lo tanto, sólo cambia el parámetro de geom_bar a aes(y = (..count..)/sum(..count..)). Después de ajustar ylab a NULL y especificando el formateador, se puede obtener:

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

actualización Nótese que si bien formatter = "percent") obras para ggplot2 versión 0.8.9, 0.9.0 en que te gustaría algo así como scale_y_continuous(labels = percent_format()). alt text

+0

ghezus - De hecho creo que alguien en SO me respondió esto antes. Embarrising para mí - espero que esto surja en la búsqueda a partir de ahora. Gracias de nuevo. – Andreas

+4

en realidad es scale_y_continuous (labels = percent) (usando el paquete de balanzas) – dickoa

+0

alguien me puede ayudar a entender el significado de .. en la declaración anterior (..count ..)/sum (.. count ..) ?? – Abhi

0

Trato situaciones similares con bastante frecuencia, pero adopto un enfoque muy diferente que utiliza dos de los otros paquetes de Hadley, a saber, la remodelación y plyr. Principalmente porque prefiero ver las cosas como barras 100% apiladas (cuando suman 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

Aquí hay un plazo de ggplot método, utilizando ..count.. y ..PANEL..:

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

Como esto se calcula sobre la marcha, debe ser robusto a cambios para trazar parámetros.

+0

Este es un gran enfoque. ¿Crees que es posible agregar etiquetas porcentuales a cada barra que se sumen al 100% en cada faceta? – marbel

+0

@ MartínBel Parece que 'geom_text' no funciona con las variables calculadas. Es posible que desee publicar como una pregunta separada. – James

+2

Claro. Aquí está la [pregunta] (http://stackoverflow.com/questions/20600900/r-faceted-bar-chart-with-percentages-labels-independent-for-each-plot) Lo dejo aquí para referencia futura. – marbel

0

Gracias por compartir el "consejo" del PANEL en el método ggplot.

Para información: se puede producir porcentajes en y lab, en el mismo gráfico de barras, mediante el uso de count y group en el ggplot método:

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

Mientras que otros pueden pensar que esto podría ser más adecuado como un comentario y no como una respuesta, le di a esta respuesta un +1 porque me ayudó a resolver un problema que tenía y quería agradecer a Lilly por publicar esto. – paleo13

Cuestiones relacionadas