2013-09-04 16 views
9

棒グラフでカテゴリを(再)順序付ける方法について多くの質問がありました(多くの場合、Order Bars in ggplot2 bar graphにリンクされています)。ファセットに依存するカテゴリの順序を持​​つggplotの棒グラフ

私は何度も触れていますが、私はそれを行う良い方法を見つけませんでした:私は多面的な棒グラフを持っており、私は各ファセットのx軸を独立して(私の場合、その変数はちょうどyの値そのものです。すなわち、棒の長さを各面で増やしたいだけです)。

Order Bars in ggplot2 bar graph:我々は何を得る

df <- data.frame(name=c('foo','bar','foo','bar'),period=c('old','old','recent','recent'),val=c(1.23,2.17,4.15,3.65)) 
p = ggplot(data = df, aes(x = reorder(name, val), y = val)) 
p = p + geom_bar(stat='identity') 
p = p + facet_grid(~period) 
p 

は以下の通りです: enter image description here

私がしたいことはあるのに対し: enter image description here

+4

ああ良さ、私の作成します!あなたは*統計情報*に嘘をつける方法へのフォローアップを書いていますか? – John

+1

これを行う唯一の方法は、別々のプロットを作成し、 'gridExtra'パッケージから' grid.arrange'を使うことです。しかし、私はそれが一般的に非常に良いプロットに終わらないことに同意します。 (ggplotにはたくさんのことがありますが、何かが本当にやるのが難しい場合は、おそらくあなたが何か愚かなことをやろうとしているからです。必ずしもそうではありません...) – joran

+0

はい、ありがとう、超有用ではありませんが、とにかくありがとうございます。私たちがそれを使用している状況では、それは重要なプロットであり、カテゴリの順序は非常に慎重です。ここで私はこれを最小限の例で煮詰めましたが、私たちのアプリケーションでは、それらの実現された相加性の関数で十数個の信号を並べ替え、ある小面のどこかにバーを置くことは容認できません。 –

答えて

18

オクラホマので、すべてここで、脇philosophizing、及び場合に誰が興味がありますそれを行う醜いハック。アイデアは、別のラベルを使用することです(私は0スペース、1スペースなどにピリオドを入れ替えて表示しないようにしてください)paste(period, name)と考えてください。私はこのプロットを必要と私は一般的な伝説を共有したい場合がありますので、私は、grobsなどをアレンジしたくない、など

先に与えられた原子の例は次のようになります。

df <- data.frame(name=c('foo','bar','foo','bar'), 
    period=c('old','old','recent','recent'), 
    val=c(1.23,2.17,4.15,3.65), 
    stringsAsFactors=F) 
df$n = as.numeric(factor(df$period)) 
df = ddply(df,.(period,name),transform, x=paste(c(rep(' ',n-1), name), collapse='')) 
df$x = factor(df$x, levels=df[order(df$val), 'x']) 
p = ggplot(data = df, aes(x = x, y = val)) 
p = p + geom_bar(stat='identity') 
p = p + facet_grid(~period, scale='free_x') 
p 

enter image description here 別例では、まだ少し愚かな私の実際のユースケースに近い、次のようになります。

df <- ddply(mpg, .(year, manufacturer), summarize, mixmpg = mean(cty+hwy)) 
df$manufacturer = as.character(df$manufacturer) 
df$n = as.numeric(factor(df$year)) 
df = ddply(df, .(year,manufacturer), transform, 
    x=paste(c(rep(' ',n-1), manufacturer), collapse='')) 
df$x = factor(df$x, levels=df[order(df$mixmpg), 'x']) 
p = ggplot(data = df, aes(x = x, y = mixmpg)) 
p = p + geom_bar(stat='identity') 
p = p + facet_grid(~year, scale='free_x') 
p = p + theme(axis.text.x=element_text(angle=90,hjust=1,vjust=.5,colour='gray50')) 
p 

enter image description here 、目を閉じて帝国を考え、そして楽しむためにしてみてください。

+0

私はそれが 'grid.arrange'なしで実行できることは素晴らしいと思うので答えを出しましたが、これはまた、面取りされたグラフに対する私たちの期待は、カテゴリが同じ方法で配置されるという点で非常に扱いにくいと信じていますファセット。これは先天的または歴史的な期待であるかもしれませんが、その期待はあまりありませんし、誤解を招く可能性があります。 –

+0

私は両方のカウントで@TylerRinkerに同意し、それに応じて投票しました。 (IMHO)があまり混乱させないようにするもう1つの選択肢は、軸のラベルを完全に抑制し、塗りつぶしの美しさだけを使用するか(バーがわずかである場合)、または各バーの上のプロットの内側にラベルを付けます。 – joran

+0

ありがとうございます。基本的にはxをランク(一貫した数値)とし、ラベルの代わりに各バーの内側にカテゴリのテキストをプロットします。これは、いくつかのカテゴリではバーが小さい場合には問題になるかもしれませんが、私は常に多様な意見に触れています。おそらくあなたは例を挙げることができます。 'mpg'データを使って、どのように見えるかを確認することができます。とにかく私の最初の選択ではないでしょうが、それはタイラーが "歴史的期待"(この場合、私の会社のもの)と呼ぶものに合っています... –

1

これは古い質問ですが、それはだまされやすい人のターゲットとして使用されています(ただ、警告を無視)

df <-data.frame(name = c('foo', 'bar', 'foo', 'bar'), 
       period = c('old', 'old', 'recent', 'recent'), 
       val = c(1.23, 2.17, 4.15, 3.65)) 

d1 <- df[order(df$period, df$val), ] 
sn <- factor(x = 1:4, labels = d1$name) 
d1$sn <- sn 
p <- ggplot(data = d1, aes(x = sn, y = val)) 
p <- p + geom_bar(stat = 'identity') 
p <- p + facet_wrap(~ period, scale = 'free_x') 
p 
+0

完全性のために:警告読まれるべきではありません: '因子の重複したレベルは廃止されました'。 – Uwe

4

それは本当に簡単です、これを試してみてください。したがって、ggplot2パッケージの最新の拡張機能、つまりlabelsのパラメータをscale_x_discrete()に利用するソリューションを提案することは価値があります。これにより、use duplicate levelsが廃止されるか、またはmanipulate factor labels by prepending a varying number of spacesになりません。

mpgデータセットはthis answerとの比較を持っているために使用され、データここで

を準備します。データ操作のためにここでは data.tableパッケージが使用されていますが、この目的のために好きなパッケージを自由に使用してください。

library(data.table) # version 1.10.4 
library(ggplot2)  # version 2.2.1 
# aggregate data 
df <- as.data.table(mpg)[, .(mixmpg = mean(cty + hwy)), by = .(year, manufacturer)] 
# create dummy var which reflects order when sorted alphabetically 
df[, ord := sprintf("%02i", frank(df, mixmpg, ties.method = "first"))] 

プロット

# `ord` is plotted on x-axis instead of `manufacturer` 
ggplot(df, aes(x = ord, y = mixmpg)) + 
    # geom_col() is replacement for geom_bar(stat = "identity") 
    geom_col() + 
    # independent x-axis scale in each facet, 
    # drop absent factor levels (actually not required here) 
    facet_wrap(~ year, scales = "free_x", drop = TRUE) + 
    # use named character vector to replace x-axis labels 
    scale_x_discrete(labels = df[, setNames(as.character(manufacturer), ord)]) + 
    # replace x-axis title 
    xlab(NULL) + 
    # rotate x-axis labels 
    theme(axis.text.x = element_text(angle = 90, hjust=1, vjust=.5)) 

enter image description here

関連する問題