Kategorik değişkenlerin grafiklerindeki sayımlar yerine% 'yi göster


171

Kategorik bir değişken çiziyorum ve her kategori değeri için sayıları göstermek yerine.

ggplotBu kategorideki değerlerin yüzdesini görüntülemek için bir yol arıyorum . Tabii ki, hesaplanan yüzde ile başka bir değişken oluşturmak ve bunu çizmek mümkündür, ancak bunu birkaç düzine kez yapmak zorundayım ve bunu tek bir komutta başarmayı umuyorum.

Gibi bir şey deniyordum

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

ama hataları aldığım için yanlış kullanmalıyım.

Kurulumu kolayca yeniden oluşturmak için basitleştirilmiş bir örnek:

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.

Gerçek durumda, muhtemelen ggplotbunun yerine kullanacağım qplot, ancak stat_bin'i kullanmanın doğru yolu hala kaçıyor .

Bu dört yaklaşımı da denedim:

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();

ama her ikisi de verir:

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

Aynı hata,

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

bu yüzden açıkça ggplottek bir vektörle nasıl etkileşime girdiğine dair bir şey var . Başımı kaşıyorum, bu hata için googling yapmak tek bir sonuç veriyor .


2
Veriler, çıplak bir faktör değil, bir veri çerçevesi olmalıdır.
hadley

1
hadley'nin yorumuna ekleme, verilerinizi mydataf = data.frame (mydataf) kullanarak bir veri çerçevesine dönüştürme ve bunu names (mydataf) = foo olarak yeniden adlandırma işlemi hile yapar
Ramnath

Yanıtlar:


222

Bu yanıtlandığından beri ggplotsözdiziminde bazı anlamlı değişiklikler olmuştur . Yukarıdaki yorumlardaki tartışmanın özetlenmesi:

 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)

İşte aşağıdakileri kullanarak tekrarlanabilir bir örnek mtcars:

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

resim açıklamasını buraya girin

Bu soru şu anda 'ggplot sayısı vs yüzde histogramı' için Google'da 1. sırada yer alıyor.

Not: Eğer hpbir faktör, ggplot getiriler olarak ayarlı değil:

resim açıklamasını buraya girin


12
Bu cevap için teşekkürler. Sınıfta nasıl yapılacağı hakkında bir fikrin var mı?
WAF

3
@ WAF'ın önerdiği gibi, bu cevap yönlü verilerle çalışmaz. @
Erwan'ın

1
percentYukarıdakilerin işe yaraması için paketin ön ekini yapmanız gerekebilir (yaptım). ggplot(mtcars, aes(x = factor(hp))) + geom_bar(aes(y = (..count..)/sum(..count..))) + scale_y_continuous(labels = scales::percent)
mammykins

Gezmek için faset kullanımı geom_bar(aes(y = (..count..)/tapply(..count..,..PANEL..,sum)[..PANEL..]))kullanın. Her faset% 100 olmalıdır.
JWilliman

Etrafında ".." olan değişkenler stat () - komutuyla değiştirilmedi mi? ggplot2.tidyverse.org/reference/stat.html
Magnus

58

bu değiştirilmiş kod çalışmalıdır

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

verilerinizde NA'lar varsa ve bunların grafiğe dahil edilmesini istemiyorsanız, ggplot argümanı olarak na.omit (mydataf) iletin.

Bu yardımcı olur umarım.


37
Ggplot2 0.9.0 sürümünde formatterbağımsız değişkenin artık çalışmadığını unutmayın. Bunun yerine, böyle bir şey isteyeceksiniz labels = percent_format()).
joran

25
Ve 0.9.0 ile scaleskullanmadan önce kitaplığı yüklemeniz gerekir percent_format(), aksi takdirde çalışmaz. 0.9.0 artık destek paketlerini otomatik olarak yüklemiyor.
Andrew

1
Bkz ? stat_bin. Veri çerçevesine hangi ek sütunların eklendiğini gösterir ggplot2. Tüm ekstra sütunlar formdadır ..variable...
Ramnath

1
aes(y = (..count..)/sum(..count..))Basitçe değiştirmek mantıklı mı aes(y = ..density..)? Görsel olarak çok benzer (ama yine de farklı) resim
veriyor

6
Ggplot 0.9.3.1.0'da, önce scaleskütüphaneyi yüklemek , ardından dokümanlardascale_y_continuous(labels=percent) belirtildiği gibi kullanmak
istersiniz


38

Mart 2017 itibariyle, ggplot22.2.1 ile en iyi çözüm, Hadley Wickham'ın veri bilimi kitabındaki R kitabında açıklanmıştır:

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

stat_countiki değişkeni hesaplar: countvarsayılan olarak kullanılır, ancak proporanları gösteren kullanmayı seçebilirsiniz .


3
Bu, Haziran 2017 itibariyle en iyi cevaptır, grupla doldurma ve yüz oluşturma ile çalışır.
Skumin

1
Bazı nedenlerden dolayı bu, filleşlemeyi kullanmama izin vermiyor (herhangi bir hata oluşmuyor , ancak dolgu rengi eklenmiyor).
Max Candocia

@MaxCandocia group = 1Dolgu eşlemesi almak için kaldırmam gerekti . belki yardımcı olur
Tjebo

1
groupParametreyi kaldırırsam, uygun yüzdeleri göstermez, çünkü her şey her bir benzersiz x değeri için kendi grubuna aittir.
Max Candocia

20

Yüzdeleri y ekseninde ve çubuklarda etiketli yapmak istiyorsanız :

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

resim açıklamasını buraya girin

Çubuk etiketleri eklerken, daha temiz bir grafik için y eksenini sonuna ekleyerek atlamak isteyebilirsiniz:

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

resim açıklamasını buraya girin


6

Yüzde etiketlerini ancak y ekseninde gerçek N'leri istiyorsanız şunu deneyin:

    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

İşte yönlü veriler için bir geçici çözüm. (@Andrew tarafından kabul edilen cevap bu durumda çalışmaz.) Fikir, dplyr kullanarak yüzde değerini hesaplamak ve daha sonra çizimi oluşturmak için geom_col kullanmaktır.

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~.)

Bu konu:

resim açıklamasını buraya girin


4

Değişkeniniz sürekli ise, işlev değişkeni "bins" olarak gruplayacağından geom_histogram () kullanmanız gerektiğini unutmayın.

df <- data.frame(V1 = rnorm(100))

ggplot(df, aes(x = V1)) +  
  geom_histogram(aes(y = (..count..)/sum(..count..))) 

# if you use geom_bar(), with factor(V1), each value of V1 will be treated as a
# different category. In this case this does not make sense, as the variable is 
# really continuous. With the hp variable of the mtcars (see previous answer), it 
# worked well since hp was not really continuous (check unique(mtcars$hp)), and one 
# can want to see each value of this variable, and not to group it in bins.
ggplot(df, aes(x = factor(V1))) +  
  geom_bar(aes(y = (..count..)/sum(..count..))) 
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.