web-dev-qa-db-ja.com

離散xスケールの順序を変更する

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

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

私は何を間違えましたか?

120
lokheart

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

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

ggplot of the cars dataset with factor levels automatically determined

# 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 of the cars dataset with factor levels reordered manually

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

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

ggplot of the cars dataset with factor levels reordered using the reorder function

96
Richie Cotton

私にとっての最善の方法は、scale_x_discretelimitsパラメーターとして必要な順序でカテゴリを使用してベクターを使用することでした。これは非常にシンプルで簡単なソリューションだと思います。

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

enter image description here

175

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

私はこれも負の高さを持つことを期待していますが、そうではないので動作します!

37
James

Hadleyはforcatsというパッケージを開発しています。このパッケージにより、タスクが非常に簡単になります。因子の頻度によってx軸の順序を変更する場合は、fct_infreq()を利用できます。この投稿の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") 

enter image description here

25
jazzurro

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

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_が付いた別のデータフレームを作成します。この新しい列にはレベルが昇順であるため、ggplot2は自動的にその順序でプロットします。

これはやや制限されています(文字または因子と列の数値の組み合わせで昇順でのみ機能します)が、外出先でのプロットには非常に便利です。

2
eflores89