2010-07-15 32 views
84

Tôi đang tạo biểu đồ thanh được né tránh bằng ggplot với thang x rời rạc, trục x được sắp xếp theo thứ tự bảng chữ cái, nhưng tôi cần sắp xếp lại để nó được sắp xếp theo giá trị của trục y (tức là thanh cao nhất sẽ được đặt ở bên trái).Thay đổi thứ tự của một biểu đồ x rời rạc

Tôi đã cố gắng sắp xếp hoặc sắp xếp, nhưng dẫn đến sắp xếp trục x chứ không phải thanh tương ứng.

Tôi đã làm gì sai?

Trả lời

77

Thử đặt mức độ của yếu tố trên trục x theo cách thủ công. Ví dụ:

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

Như James chỉ ra trong câu trả lời của mình, reorder là cách thành ngữ sắp xếp lại mức yếu tố.

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

25

Bạn có thể sử dụng reorder:

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

Edit:

Để có thanh cao nhất ở bên trái, bạn phải sử dụng một chút của một kludge :

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

Tôi mong đợi điều này cũng có độ cao tiêu cực, nhưng không, vì vậy nó hoạt động!

+5

Tôi bị sốc câu trả lời này không có nhiều upvotes, 90% thời gian này là cách thích hợp để làm điều đó. – Gregor

+0

Tôi nghĩ cả hai cuộc gọi yếu tố đều không cần thiết. Có một cuộc gọi ngầm định đến yếu tố cho đối số đầu tiên và đối số thứ hai của hte được giả định là số. –

134

Cách tốt nhất cho tôi là sử dụng véc-tơ với các danh mục theo thứ tự tôi cần như tham số limits thành scale_x_discrete. Tôi nghĩ rằng đó là giải pháp khá đơn giản và dễ hiểu.

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

enter image description here

+1

Điều này "làm việc" .... nhưng truyền thuyết vẫn cho thấy các đơn đặt hàng lộn xộn ... –

+0

@ HendyIrawan không có huyền thoại trừ khi bạn đã có kích thước khác (màu, điền) cũng ánh xạ tới cùng một biến. – Gregor

2

Tôi nhận ra điều này là cũ, nhưng có lẽ chức năng này, tôi tạo ra rất hữu ích với ai đó ngoài kia:

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

Bây giờ, với chức năng này bạn tương tác có thể vẽ với ggplot2, như thế này:

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

Có thể thấy,Hàmtạo một khung dữ liệu khác với một cột mới có tên giống nhau nhưng với một số _o ở cuối. Cột mới này có các cấp theo thứ tự tăng dần, vì vậy ggplot2 tự động vẽ theo thứ tự đó.

Điều này hơi bị hạn chế (chỉ hoạt động đối với kết hợp ký tự hoặc yếu tố và số cột và theo thứ tự tăng dần) nhưng tôi vẫn thấy nó rất hữu ích khi vẽ trên đường đi.

13

Hadley đã phát triển một gói được gọi là forcats. Gói này làm nhiệm vụ dễ dàng hơn nhiều.Bạn có thể khai thác fct_infreq() khi bạn muốn thay đổi thứ tự của trục x theo tần suất của một yếu tố. Trong trường hợp của ví dụ mtcars trong bài đăng này, bạn muốn sắp xếp lại các cấp độ cyl theo tần suất của mỗi cấp. Mức xuất hiện thường xuyên nhất ở bên trái. Tất cả những gì bạn cần là fct_infreq().

library(ggplot2) 
library(forcats) 

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

Nếu bạn muốn đi theo con đường khác xung quanh, bạn có thể sử dụng cùng với fct_rev()fct_infreq().

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

enter image description here

Các vấn đề liên quan