สั่งสเกล x แบบไม่ต่อเนื่องตามความถี่ / ค่า


138

ฉันกำลังสร้างแผนภูมิแท่งแบบหลบโดยใช้ ggplot ที่มีมาตราส่วน x แบบไม่ต่อเนื่องตอนนี้แกน x ถูกจัดเรียงตามลำดับตัวอักษร แต่ฉันต้องจัดเรียงใหม่เพื่อให้เรียงลำดับตามค่าของแกน y (เช่นแถบที่สูงที่สุดจะ อยู่ทางซ้าย)

ฉันลองเรียงลำดับหรือเรียงลำดับ แต่ผลลัพธ์ในการจัดเรียงแกน x แต่ไม่ใช่แถบตามลำดับ

ฉันทำอะไรผิด?

คำตอบ:


106

ลองตั้งค่าระดับของปัจจัยบนแกน 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()

ggplot ของชุดข้อมูลรถยนต์ที่มีระดับปัจจัยเรียงลำดับใหม่โดยใช้ฟังก์ชันเรียงลำดับใหม่


199

วิธีที่ดีที่สุดสำหรับผมใช้เวกเตอร์ที่มีหมวดหมู่เพื่อที่ฉันจะต้องเป็นพารามิเตอร์limits scale_x_discreteฉันคิดว่ามันเป็นวิธีแก้ปัญหาที่ค่อนข้างง่ายและตรงไปตรงมา

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

ป้อนคำอธิบายภาพที่นี่


1
@HendyIrawan ไม่มีตำนานเว้นแต่คุณจะมีมิติข้อมูลอื่น ๆ (สีเติม) ที่แมปกับตัวแปรเดียวกัน
Gregor Thomas

5
ผมคิดว่านี่คือคำตอบที่ดีที่สุด ควบคุมลำดับของค่าแกน x และไม่แปลงหรือส่งผลกระทบต่อ data-frame การใช้factorและreorderการเปลี่ยนแปลงลักษณะของข้อมูลแม้ว่าจะอยู่ในการggplot()โทรและทำมากกว่าที่จำเป็นสำหรับปัญหาในมือ
mjandrews

2
นี่น่าจะเป็นคำตอบที่ยอมรับ !! เหตุใดจึงทำให้สิ่งต่าง ๆ ซับซ้อนโดยการเขียนโค้ด 2 ถึง 3 บรรทัดสำหรับบางสิ่งที่คุณสามารถทำได้ในโค้ดบรรทัดเดียว (กำหนดไว้ล่วงหน้า)
SilSur

1
สิ่งนี้ได้ผลให้ฉันสั่ง x ด้วยค่า y: scale_x_discrete(limits = DT$x[order(-DT$y)])+
armipunk

39

คุณสามารถใช้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")

ฉันคาดหวังว่าสิ่งนี้จะมีความสูงติดลบ แต่ก็ไม่ได้ผล!


6
ฉันตกใจมากที่คำตอบนี้ไม่มีการโหวตเพิ่มขึ้น 90% ของเวลานี้เป็นวิธีที่เหมาะสมที่จะทำ
Gregor Thomas

1
ฉันคิดว่าทั้งการเรียกตัวประกอบนั้นไม่จำเป็น มีการเรียกโดยนัยให้แยกตัวประกอบสำหรับอาร์กิวเมนต์แรกและอาร์กิวเมนต์ hte ที่สองจะถือว่าเป็นตัวเลข
IRTFM

คำอธิบายที่ช่วยให้ฉันเข้าใจว่าโซลูชันเหล่านี้กำลังทำอะไรอยู่ภายใต้ประทุน: rstudio-pubs-static.s3.amazonaws.com/…
keithpjolley

desc(reorder(.))สามารถให้แถบที่สูงที่สุดทางด้านซ้าย
Jabro

31

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อยู่ท้าย คอลัมน์ใหม่นี้มีระดับจากน้อยไปมากดังนั้น ggplot2 จะลงจุดโดยอัตโนมัติตามลำดับนั้น

สิ่งนี้ค่อนข้าง จำกัด (ใช้ได้เฉพาะกับอักขระหรือตัวประกอบและการผสมตัวเลขของคอลัมน์และเรียงลำดับจากน้อยไปหามาก) แต่ฉันยังพบว่ามีประโยชน์มากสำหรับการวางแผนระหว่างเดินทาง


ฉันเดาว่าฉันไม่เห็นข้อดีของสิ่งนี้เมื่อเทียบกับการใช้reorderโดยตรง ไม่ggplot(df, aes(x = reorder(AXIS_X, COLUMN_Y), y = COLUMN_Y)) + ...ทำสิ่งเดียวกันเกี่ยวกับอย่างรัดกุมและไม่มีฟังก์ชันตัวช่วยใช่หรือไม่?
Gregor Thomas
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.