Estoy haciendo una serie de gráficos de barras donde el valor porcentual se coloca encima de cada barra. Me gustaría redondear esto a 0 lugares decimales, pero el valor predeterminado es 1 lugar decimal. Aquí tienes un ejemplo con mtcars.

library(ggplot2)
library(scales)

d <- mtcars

g <- ggplot(d, aes(gear)) +
geom_bar(aes(y = (..count..)/sum(..count..), fill=factor(..x..)), stat= "count")+
geom_text(aes(label = scales::percent((..count..)/sum(..count..)),
            y= ((..count..)/sum(..count..))), stat="count",
        vjust = -.25)

Esto le da: ingrese la descripción de la imagen aquí

¿Hay alguna manera de redondearlos al número entero más cercano, de modo que las barras estén etiquetadas como 47%, 38% y 16%?

Las soluciones podrían incluir anotar las etiquetas manualmente o generar un marco de datos resumido desde el cual extraer las etiquetas. Sin embargo, dado que estoy generando numerosas tablas, preferiría incluir todo mi código dentro del comando ggplot.

17
John J. 14 dic. 2016 a las 20:29

2 respuestas

La mejor respuesta

Aquí está el cambio mínimo en su código actual que hará lo que quiera:

library(ggplot2)
library(scales)

d <- mtcars

g <- ggplot(d, aes(gear)) +
geom_bar(aes(y = (..count..)/sum(..count..), fill=factor(..x..)), stat= "count")+
geom_text(aes(label = scales::percent(round((..count..)/sum(..count..),2)),
            y= ((..count..)/sum(..count..))), stat="count",
        vjust = -.25)

Agregué una llamada a round(...,2) en su división que redondeará la proporción antes de pasarla a percent.


Personalmente, haría esto fuera de ggplot para mayor claridad del código.

library(ggplot2)
library(scales)
library(dplyr)

d <- mtcars %>%
  group_by(gear) %>%
  summarise(Count = n()) %>%
  mutate( gear = factor(gear),
    Ratio = Count / sum(Count),
         label = percent(Ratio %>% round(2)))

g <- ggplot(d, aes(x=gear,y=Ratio,label=label,fill=gear)) +
  geom_bar(stat='identity') +
  geom_text(vjust=0)
g

Cuando tenga que volver atrás y mirar eso en 6 meses, será mucho más fácil averiguar qué hice.

15
Bishops_Guest 14 dic. 2016 a las 17:48

Me ocupé del mismo problema y lo resolví agregando accuracy = 1L en scales::percent() y funcionó perfectamente:

label = scales::percent(round((..count..)/tapply(..count..,..PANEL..,sum)[..PANEL..], 
                              2), 
                        accuracy = 1L))
4
Benjamin Telkamp 25 jun. 2019 a las 12:26