カテゴリー変数のグラフにカウントではなく%を表示


170

カテゴリー変数をプロットし、各カテゴリー値のカウントを表示する代わりに。

ggplotそのカテゴリの値の割合を表示する方法を探しています。もちろん、計算されたパーセンテージで別の変数を作成してそれをプロットすることは可能ですが、私はそれを数十回行わなければならず、1つのコマンドでそれを達成したいと思っています。

私は次のようなものを試していました

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

エラーが発生したので、間違って使用している必要があります。

セットアップを簡単に再現するために、以下に簡単な例を示します。

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.

実際の場合、私はおそらくのggplot代わりに使用しますqplotが、stat_binを使用する正しい方法はまだ私にはわかりません。

次の4つの方法も試しました。

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

4つすべてが与える:

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

同じエラーが単純な場合に表示されます

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

したがって、それは明らかにggplot単一のベクトルとどのように相互作用するかについての何かです。私は頭をかいて、そのエラーをググるだけで単一の結果が得られます。


2
データはデータフレームであり、ベアファクターではありません。
ハドレー

1
ハドリーのコメントに追加し、mydataf = data.frame(mydataf)を使用してデータをデータフレームに変換し、names(mydataf)= fooに名前を変更すると、トリックが実行されます
Ramnath

回答:


221

これが回答されてから、ggplot構文にいくつかの意味のある変更がありました。上記のコメントでの議論を要約すると:

 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)

以下は、を使用した再現可能な例mtcarsです。

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

ここに画像の説明を入力してください

この質問は現在「グップロット数とパーセンテージヒストグラム」のグーグルでの1番目のヒットなので、うまくいけば、受け入れられた回答のコメントに現在格納されているすべての情報を抽出できます。

備考:もしhpが因子として設定されていない、ggplotは次を返します:

ここに画像の説明を入力してください


12
この回答をありがとう。クラスごとにそれを行う方法についてのアイデアはありますか?
WAF 2015

3
。@ WAFが示唆しているように、この回答はファセットデータでは機能しません。stackoverflow.com/questions/22181132/の
@Erwan

1
percent上記を機能させるには、パッケージのプレフィックスを付ける必要があるかもしれません(私はそうしました)。 ggplot(mtcars, aes(x = factor(hp))) + geom_bar(aes(y = (..count..)/sum(..count..))) + scale_y_continuous(labels = scales::percent)
mammykins

ファセットの使用を回避するには、geom_bar(aes(y = (..count..)/tapply(..count..,..PANEL..,sum)[..PANEL..]))代わりにを使用します。各ファセットの合計は100%になるはずです。
JWilliman

".."で囲まれた変数がstat()コマンドに置き換えられていませんか?ggplot2.tidyverse.org/reference/stat.html
Magnus

58

この変更されたコードは動作するはずです

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

データにNAがあり、それらをプロットに含めたくない場合は、na.omit(mydataf)をggplotの引数として渡します。

お役に立てれば。


37
ggplot2バージョン0.9.0では、formatter引数が機能しなくなることに注意してください。代わりに、のようなものが必要になりますlabels = percent_format())
joran

25
また、0.9.0 では、scalesを使用する前にライブラリをロードする必要がありますpercent_format()。そうしないと機能しません。0.9.0は​​サポートパッケージを自動的にロードしなくなりました。
Andrew

1
を参照してください? stat_bin。これは、によってデータフレームに追加される列を示しますggplot2。追加の列はすべての形式..variable..です。
Ramnath 2014年

1
aes(y = (..count..)/sum(..count..))単純に置き換えることは理にかなっていaes(y = ..density..)ますか?視覚的には非常によく似た(ただしまだ異なる)画像が表示されます
Alexander Kosenkov

6
ggplot 0.9.3.1.0では、最初にscalesライブラリをロードしてから、ドキュメントにscale_y_continuous(labels=percent)記載されて
adilapapaya


37

2017年3月の時点で、ggplot22.2.1を使用して、データサイエンスブックに関するHadley WickhamのRで最良のソリューションが説明されていると思います。

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

stat_count2つの変数を計算します。countデフォルトで使用されますが、prop比率を示すものを使用するように選択できます。


3
これは2017年6月の時点での最良の回答であり、グループごとの充填とファセットで機能します。
Skumin 2017年

1
何らかの理由で、これを使用してfillマッピングを使用することはできません(エラーはスローされませんが、塗りつぶしの色は追加されません)。
Max Candocia 2018

@MaxCandocia group = 1フィルマッピングを取得するために削除する必要がありました。多分それは役立つ
Tjebo

1
groupただし、パラメーターを削除すると、すべてが固有のx値ごとに独自のグループに属しているため、適切なパーセンテージが表示されません。
Max Candocia

20

あなたは、y軸上のパーセンテージをしたい場合、バーの上にラベル:

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

ここに画像の説明を入力してください

棒のラベルを追加するとき、最後に追加することにより、すっきりしたグラフのy軸を省略できます。

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

ここに画像の説明を入力してください


6

パーセンテージのラベルが必要だが、y軸に実際のNが必要な場合は、次を試してください。

    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

ファセットデータの回避策を次に示します。(この場合、@ Andrewが受け入れた回答は機能しません。)アイデアは、dplyrを使用してパーセンテージ値を計算してから、geom_colを使用してプロットを作成することです。

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

これはプロットです:

ここに画像の説明を入力してください


3

変数が連続的である場合、関数は変数を「ビン」でグループ化するため、geom_histogram()を使用する必要があることに注意してください。

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..))) 
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.