周波数/値で離散xスケールを並べ替え


137

離散xスケールのggplotを使用して覆い焼き棒グラフを作成しています。x軸はアルファベット順に配置されていますが、y軸の値で並べられるように再配置する必要があります(つまり、最も高い棒が左側に配置されます)。

並べ替えまたは並べ替えを試みましたが、結果としてX軸は並べ替えられましたが、棒は並べ替えられませんでした。

何が悪いのでしょうか?

回答:


105

X軸の係数のレベルを手動で設定してみてください。例えば:

library(ggplot2)
# Automatic levels
ggplot(mtcars, aes(factor(cyl))) + geom_bar()    

因子レベルが自動的に決定される自動車データセットのggplot

# Manual levels
cyl_table <- table(mtcars$cyl)
cyl_levels <- names(cyl_table)[order(cyl_table)]
mtcars$cyl2 <- factor(mtcars$cyl, levels = cyl_levels)
# Just to be clear, the above line is no different than:
# mtcars$cyl2 <- factor(mtcars$cyl, levels = c("6","4","8"))
# You can manually set the levels in whatever order you please. 
ggplot(mtcars, aes(cyl2)) + geom_bar()

因子レベルが手動で並べ替えられた車のデータセットのggplot

ジェームズが彼の答えで指摘したreorderように、因子レベルを並べ替える慣用的な方法です。

mtcars$cyl3 <- with(mtcars, reorder(cyl, cyl, function(x) -length(x)))
ggplot(mtcars, aes(cyl3)) + geom_bar()

reorder関数を使用して並べ替えられた因子レベルを含むcarsデータセットのggplot


197

私にとっての最良の方法は、のlimitsパラメーターとして必要な順序で、カテゴリーを持つベクトルを使用することscale_x_discreteでした。私はそれはかなりシンプルで簡単な解決策だと思います。

ggplot(mtcars, aes(factor(cyl))) + 
  geom_bar() + 
  scale_x_discrete(limits=c(8,4,6))

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


1
@HendyIrawan同じ変数にマッピングされている他のディメンション(色、塗りつぶし)がない限り、凡例はありません。
グレゴールトーマス

5
これが最良の答えだと思います。これは、x軸の値の順序を制御し、データフレームを変換したり、データフレームに影響を与えたりしません。呼び出し内ではありますが、データの特性の使用factorreorder変更は、当面ggplot()の問題に対して必要以上のことを行います。
mjandrews

2
これは受け入れられる答えになるはずです!! エレガントな(定義済みの)単一のコード行で実行できることを2〜3行のコードで記述することによって、なぜ物事を複雑にするのですか?
SilSur

1
これはまた、yの値によって順番xに私の仕事: scale_x_discrete(limits = DT$x[order(-DT$y)])+
armipunk

38

使用できますreorder

qplot(reorder(factor(cyl),factor(cyl),length),data=mtcars,geom="bar")

編集:

一番高いバーを左側に配置するには、少しクラッジを使用する必要があります。

qplot(reorder(factor(cyl),factor(cyl),function(x) length(x)*-1),
   data=mtcars,geom="bar")

これは負の高さもあると思いますが、そうではないので機能します!


5
この回答には賛成投票が多くないことに驚いています。90%の確率でこれが適切な方法です。
Gregor Thomas、

1
両方の因子呼び出しは不必要だと思います。最初の引数にはfactorへの暗黙の呼び出しがあり、2番目の引数は数値であると見なされます。
IRTFM 2017

私はこれらのソリューションは、ボンネットの下に何をしていたかを把握する助け説明:rstudio-pubs-static.s3.amazonaws.com/...
keithpjolley

30

Hadleyはと呼ばれるパッケージを開発していますforcats。このパッケージにより、タスクが非常に簡単になります。fct_infreq()因子の頻度によってx軸の順序を変更したい場合に活用できます。mtcarsこの投稿の例の場合cyl、各レベルの頻度でレベルを並べ替える必要があります。最も頻繁に現れるレベルは左側にあります。必要なのはfct_infreq()です。

library(ggplot2)
library(forcats)

ggplot(mtcars, aes(fct_infreq(factor(cyl)))) +
geom_bar() +
labs(x = "cyl")

逆にしたい場合は、とfct_rev()一緒に使用できますfct_infreq()

ggplot(mtcars, aes(fct_rev(fct_infreq(factor(cyl))))) +
geom_bar() +
labs(x = "cyl") 

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


2

私はこれが古いことを理解していますが、おそらく私が作成したこの関数はそこにいる誰かにとって有用です:

order_axis<-function(data, axis, column)
{
  # for interactivity with ggplot2
  arguments <- as.list(match.call())
  col <- eval(arguments$column, data)
  ax <- eval(arguments$axis, data)

  # evaluated factors
  a<-reorder(with(data, ax), 
             with(data, col))

  #new_data
  df<-cbind.data.frame(data)
  # define new var
  within(df, 
         do.call("<-",list(paste0(as.character(arguments$axis),"_o"), a)))
}

この関数を使用すると、次のようにggplot2で対話的にプロットできます。

ggplot(order_axis(df, AXIS_X, COLUMN_Y), 
       aes(x = AXIS_X_o, y = COLUMN_Y)) +
        geom_bar(stat = "identity")

order_axisご覧のように、この関数は、同じ名前が付いて_oいるが最後にaがある新しい列を持つ別のデータフレームを作成します。この新しい列には昇順のレベルがあるため、ggplot2は自動的にその順序でプロットします。

これは多少制限されます(文字または係数と列の数値の組み合わせに対してのみ機能し、昇順で機能します)。


reorder直接使用するだけの場合と比べて、この利点はわかりません。しないggplot(df, aes(x = reorder(AXIS_X, COLUMN_Y), y = COLUMN_Y)) + ...程度の簡潔、同じことを行うと、ヘルパー関数なし?
グレゴールトーマス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.