Pokaż % zamiast zliczeń na wykresach zmiennych kategorycznych

Wykreślam zmienną kategoryczną i zamiast pokazywać liczby dla każdej wartości kategorii.

Szukam sposobu, aby ggplot wyświetlić procent wartości w tej kategorii. Oczywiście można utworzyć kolejną zmienną z obliczonym procentem i wykreślić tę, ale muszę to zrobić kilkadziesiąt razy i mam nadzieję, że uda mi się to osiągnąć jednym poleceniem.

Eksperymentowałem z czymś takim

qplot(mydataf) +
  stat_bin(aes(n = nrow(mydataf), y = ..count../n)) +
  scale_y_continuous(formatter = "percent")

Ale muszę go używać niepoprawnie, bo mam błędy.

Aby łatwo odtworzyć konfigurację, oto uproszczony przykład:

mydata <- c ("aa", "bb", NULL, "bb", "cc", "aa", "aa", "aa", "ee", NULL, "cc");
mydataf <- factor(mydata);
qplot (mydataf); #this shows the count, I'm looking to see % displayed.

W prawdziwym przypadku prawdopodobnie użyję ggplot zamiast qplot, ale właściwy sposób użycia stat_bin wciąż mi umyka.

Wypróbowałem również te cztery podejścia:

ggplot(mydataf, aes(y = (..count..)/sum(..count..))) + 
  scale_y_continuous(formatter = 'percent');

ggplot(mydataf, aes(y = (..count..)/sum(..count..))) + 
  scale_y_continuous(formatter = 'percent') + geom_bar();

ggplot(mydataf, aes(x = levels(mydataf), y = (..count..)/sum(..count..))) + 
  scale_y_continuous(formatter = 'percent');

ggplot(mydataf, aes(x = levels(mydataf), y = (..count..)/sum(..count..))) + 
  scale_y_continuous(formatter = 'percent') + geom_bar();

Ale wszystkie 4 dają:

Error: ggplot2 doesn't know how to deal with data of class factor

Ten sam błąd pojawia się dla prostego przypadku

ggplot (data=mydataf, aes(levels(mydataf))) +
  geom_bar()

Więc jest to wyraźnie coś o tym, jak ggplot współdziała z pojedynczym wektor. Drapię się po głowie, googlując za ten błąd daje pojedynczy wynik .

 139
Author: Eric Leung, 2010-09-12

8 answers

Od momentu odpowiedzi na to pytanie nastąpiły znaczące zmiany w składni ggplot. Podsumowując dyskusję w komentarzach powyżej:

 require(ggplot2)
 require(scales)

 p <- ggplot(mydataf, aes(x = foo)) +  
        geom_bar(aes(y = (..count..)/sum(..count..))) + 
        ## version 3.0.0
        scale_y_continuous(labels=percent)

Oto powtarzalny przykład używając mtcars:

 ggplot(mtcars, aes(x = factor(hp))) +  
        geom_bar(aes(y = (..count..)/sum(..count..))) + 
        scale_y_continuous(labels = percent) ## version 3.0.0

Tutaj wpisz opis obrazka

To pytanie jest obecnie hitem # 1 w google dla "ggplot count vs procent histogramu", więc mam nadzieję, że pomoże to destylować wszystkie informacje zawarte obecnie w komentarzach na temat zaakceptowanej odpowiedzi.

Uwaga: Jeśli hp nie jest ustawione jako czynnik, ggplot zwraca:

Tutaj wpisz opis obrazka

 193
Author: Andrew,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-16 07:49:06

Ten zmodyfikowany kod powinien działać

p = ggplot(mydataf, aes(x = foo)) + 
    geom_bar(aes(y = (..count..)/sum(..count..))) + 
    scale_y_continuous(formatter = 'percent')

Jeśli Twoje dane mają NAs i nie chcesz, aby zostały uwzględnione w wykresie, przekaż na.pomiń (mydataf) jako argument do ggplot.

Mam nadzieję, że to pomoże.
 54
Author: Ramnath,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-12 16:23:45

Z ggplot2 w wersji 2.1.0 jest to

+ scale_y_continuous(labels = scales::percent)
 40
Author: Fabian Hertwig,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-26 12:46:17

Według danych z marca 2017 roku, z ggplot2 2.2.1 najlepszym rozwiązaniem jest wyjaśnienie w Hadley Wickham R for data science book:

ggplot(mydataf) + stat_count(mapping = aes(x=foo, y=..prop.., group=1))

stat_count oblicza dwie zmienne: count jest używany domyślnie, ale można wybrać użycie prop, który pokazuje proporcje.

 27
Author: Olivier Ma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-21 08:22:23

Jeśli chcesz procenty na osi y i oznaczone na słupkach:

library(ggplot2)
library(scales)
ggplot(mtcars, aes(x = as.factor(am))) +
  geom_bar(aes(y = (..count..)/sum(..count..))) +
  geom_text(aes(y = ((..count..)/sum(..count..)), label = scales::percent((..count..)/sum(..count..))), stat = "count", vjust = -0.25) +
  scale_y_continuous(labels = percent) +
  labs(title = "Manual vs. Automatic Frequency", y = "Percent", x = "Automatic Transmission")

Tutaj wpisz opis obrazka

Podczas dodawania etykiet słupkowych możesz pominąć oś y dla wykresu czystszego, dodając na końcu:

  theme(
        axis.text.y=element_blank(), axis.ticks=element_blank(),
        axis.title.y=element_blank()
  )

Tutaj wpisz opis obrazka

 17
Author: Sam Firke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-28 16:39:27

Jeśli chcesz procentu etykiet ale rzeczywistego Ns na osi y, spróbuj tego:

    library(scales)
perbar=function(xx){
      q=ggplot(data=data.frame(xx),aes(x=xx))+
      geom_bar(aes(y = (..count..)),fill="orange")
       q=q+    geom_text(aes(y = (..count..),label = scales::percent((..count..)/sum(..count..))), stat="bin",colour="darkgreen") 
      q
    }
    perbar(mtcars$disp)
 6
Author: Steve Powell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-11 21:21:02

Oto obejście dla danych aspektowych. (Zaakceptowana odpowiedź przez @ Andrzej nie działa w tym przypadku.) Chodzi o to, aby obliczyć wartość procentową za pomocą dplyr, a następnie użyć geom_col do utworzenia wykresu.

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

binwidth <- 30

mtcars.stats <- mtcars %>%
  group_by(cyl) %>%
  mutate(bin = cut(hp, breaks=seq(0,400, binwidth), 
               labels= seq(0+binwidth,400, binwidth)-(binwidth/2)),
         n = n()) %>%
  group_by(cyl, bin) %>%
  summarise(p = n()/n[1]) %>%
  ungroup() %>%
  mutate(bin = as.numeric(as.character(bin)))

ggplot(mtcars.stats, aes(x = bin, y= p)) +  
  geom_col() + 
  scale_y_continuous(labels = percent) +
  facet_grid(cyl~.)

Oto Fabuła:

Tutaj wpisz opis obrazka

 6
Author: ACNB,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-26 04:53:41

Dla tych, którzy przyjdą do tego po 2018 roku, zamień " labels = percent_format () "na"scales::percent"

 1
Author: Ghazal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-05 18:28:42