Frekans / değere göre ayrık x ölçeği sipariş etme


137

Ayrık x ölçeğine sahip ggplot kullanarak kaçık bir çubuk grafik yapıyorum, x ekseni şimdi alfabetik olarak düzenlenmiştir, ancak y ekseninin değeriyle (yani en uzun çubuk sola yerleştirilmelidir).

Siparişi veya sıralamayı denedim, ancak sırasıyla x eksenini sıraladım, ancak sırasıyla çubukları değil.

Neyi yanlış yaptım?

Yanıtlar:


105

Faktörün seviyelerini x ekseni üzerinde manuel olarak ayarlamayı deneyin. Örneğin:

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

otomatik olarak belirlenen faktör seviyeleri ile araç veri kümesinin ggplotu

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

manuel olarak yeniden sıralanan faktör seviyeleri ile araç veri kümesinin ggplotu

James'in cevabında işaret ettiği gibi, reorderfaktör seviyelerini yeniden sıralamanın deyimsel yoludur.

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

Yeniden sıralama işlevi kullanılarak yeniden sıralanan faktör düzeylerine sahip araç veri kümesinin ggplotu


197

Benim için en iyi yol, limitsparametre olarak ihtiyacım olması için kategorilerle vektör kullanmaktı scale_x_discrete. Bence oldukça basit ve anlaşılır bir çözüm.

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

resim açıklamasını buraya girin


1
@HendyIrawan, aynı değişkenle eşleştirilen başka boyutlarınız (renk, dolgu) yoksa efsane yoktur.
Gregor Thomas

5
Bence bu en iyi cevap. X ekseni değerlerinin sırasını kontrol eder ve veri çerçevesini dönüştürmez veya etkilemez. Arama içinde de olsa verilerin kullanımı factorve reorderözelliklerini değiştirir ggplot()ve bu da eldeki sorun için gerekenden fazlasını yapar.
mjandrews

2
Bu kabul edilen cevap olmalı !! Tek bir zarif (önceden tanımlanmış) kod satırında yapabileceğiniz bir şey için 2 ila 3 satır kod yazarak neden işleri karmaşıklaştırabilirsiniz?
SilSur

1
Bu da benim için y değerini x olarak sipariş scale_x_discrete(limits = DT$x[order(-DT$y)])+
etmemde işe yaradı

38

Şunları kullanabilirsiniz reorder:

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

Düzenle:

Solda en uzun çubuğa sahip olmak için biraz çamur kullanmanız gerekir:

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

Bunun da negatif yükseklikleri olmasını beklerdim, ama öyle değil, bu yüzden işe yarıyor!


5
Bu cevabın daha fazla oyu olmadığı için şok oldum, zamanın% 90'ı bunu yapmanın uygun yoludur.
Gregor Thomas

1
Her iki faktör çağrısının da gereksiz olduğunu düşünüyorum. Birinci bağımsız değişken için örtülü bir çarpan çağrısı vardır ve ikinci bağımsız değişken sayısal olarak kabul edilir.
IRTFM

Bu çözümlerin kaputun altında neler yaptığını anlamama
keithpjolley

30

Hadley adlı bir paket geliştiriyor forcats. Bu paket görevi çok daha kolay hale getirir. fct_infreq()X ekseni sırasını bir faktörün frekansına göre değiştirmek istediğinizde yararlanabilirsiniz . Bu yazıda mtcarsörnek olması durumunda, seviyelerini cylher bir seviyenin sıklığına göre yeniden sıralamak istersiniz . En sık görünen seviye sol tarafta kalır. Tek ihtiyacınız olan şey fct_infreq().

library(ggplot2)
library(forcats)

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

Eğer tersini yapmak istiyorsan, fct_rev()birlikte kullanabilirsin fct_infreq().

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

resim açıklamasını buraya girin


2

Bunun eski olduğunu anlıyorum, ama oluşturduğum bu fonksiyon orada birisi için yararlı olabilir:

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

Şimdi, bu işlevle ggplot2 ile etkileşimli olarak çizim yapabilirsiniz:

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

Görülebileceği gibi, order_axisişlev aynı adlı ancak _osonunda a ile yeni bir sütun içeren başka bir veri çerçevesi oluşturur . Bu yeni sütun artan sırada düzeylere sahiptir, bu nedenle ggplot2 otomatik olarak bu sırayla çizilir.

Bu biraz sınırlı (sadece karakter veya faktör ve sütunların sayısal kombinasyonları ve artan sırada çalışır) ama yine de hareket halindeyken çizmek için çok yararlı buluyorum.


Sanırım bu avantajı sadece reorderdoğrudan kullanmaya kıyasla görmüyorum . ggplot(df, aes(x = reorder(AXIS_X, COLUMN_Y), y = COLUMN_Y)) + ...Aynı şeyi, kısaca ve yardımcı işlevi olmadan yapmıyor mu ?
Gregor Thomas
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.