ทำความเข้าใจกับฟังก์ชัน order ()


89

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

ตัวอย่างเช่น

> a <- c(45,50,10,96)
> order(a)
[1] 3 1 2 4

ฉันคาดหวังว่าสิ่งนี้จะกลับมา c(2, 3, 1, 4)เนื่องจากรายการที่จัดเรียงจะเป็น 10 45 50 96

ใครช่วยฉันเข้าใจค่าส่งคืนของฟังก์ชันนี้ได้ไหม

คำตอบ:


101

สิ่งนี้ดูเหมือนจะอธิบายได้

คำจำกัดความของorderคือที่a[order(a)]เพิ่มขึ้นตามลำดับ สิ่งนี้ใช้ได้กับตัวอย่างของคุณโดยลำดับที่ถูกต้องคือองค์ประกอบที่สี่ที่สองอันดับแรกและสาม

คุณอาจกำลังมองหาrankซึ่งส่งกลับอันดับขององค์ประกอบ
R> a <- c(4.1, 3.2, 6.1, 3.1)
R> order(a)
[1] 4 2 1 3
R> rank(a)
[1] 3 2 4 1
เพื่อrankบอกให้คุณทราบว่าตัวเลขอยู่ในลำดับใด orderบอกให้คุณทราบว่าจะเรียงลำดับจากน้อยไปมากได้อย่างไร

plot(a, rank(a)/length(a))จะให้กราฟของ CDF หากต้องการดูว่าเหตุใดจึง orderมีประโยชน์ให้ลองใช้plot(a, rank(a)/length(a),type="S") สิ่งที่ทำให้ยุ่งเหยิงเนื่องจากข้อมูลไม่ได้อยู่ในลำดับที่เพิ่มขึ้น

หากคุณได้
oo<-order(a)
plot(a[oo],rank(a[oo])/length(a),type="S")
หรือเพียงแค่
oo<-order(a)
plot(a[oo],(1:length(a))/length(a)),type="S")
คุณได้รับกราฟเส้นของ CDF

ฉันจะพนันได้เลยว่าคุณกำลังคิดถึงอันดับ


8
อ่า .. ฉันเห็นแล้ว order () ส่งกลับดัชนีของเวกเตอร์ตามลำดับที่จัดเรียง วิเศษมากขอบคุณมาก
jeffshantz

order(a, decreasing = T)และrank(a)จะส่งคืนคำตอบที่เทียบเท่า
omar

ฉันมีปัญหากับการสั่งซื้อ a<-c(4,2,1,80,13)ถ้าอย่างนั้นก็order(a)ควรจะเป็น3 4 5 1 2แต่แปลกที่ฉันได้รับ3 2 1 5 4
Shoham Debnath

1
@duffymo ความช่วยเหลือเล็กน้อยที่นี่จะได้รับการชื่นชมจริงๆ เมื่อไหร่rankและorderเหมือนกัน?
Shoham Debnath

อันที่จริงorder(order(a))จะกลับมาเช่นเดียวกับrank(a) ถ้าไม่มีความสัมพันธ์ rank(a, ties.method="first")ถ้ามีแล้วมันจะกลับมาเช่นเดียวกับ
jac

33

ในการจัดเรียงเวกเตอร์ 1D หรือข้อมูลคอลัมน์เดียวเพียงแค่เรียกใช้ฟังก์ชันsortและส่งต่อตามลำดับของคุณ

ในทางกลับกันฟังก์ชันลำดับมีความจำเป็นในการจัดเรียงข้อมูลข้อมูลสองมิตินั่นคือข้อมูลหลายคอลัมน์ที่รวบรวมในเมทริกซ์หรือดาต้าเฟรม

Stadium Home Week Qtr Away Off Def Result       Kicker Dist
751     Out  PHI   14   4  NYG PHI NYG   Good      D.Akers   50
491     Out   KC    9   1  OAK OAK  KC   Good S.Janikowski   32
702     Out  OAK   15   4  CLE CLE OAK   Good     P.Dawson   37
571     Out   NE    1   2  OAK OAK  NE Missed S.Janikowski   43
654     Out  NYG   11   2  PHI NYG PHI   Good      J.Feely   26
307     Out  DEN   14   2  BAL DEN BAL   Good       J.Elam   48
492     Out   KC   13   3  DEN  KC DEN   Good      L.Tynes   34
691     Out  NYJ   17   3  BUF NYJ BUF   Good     M.Nugent   25
164     Out  CHI   13   2   GB CHI  GB   Good      R.Gould   25
80      Out  BAL    1   2  IND IND BAL   Good M.Vanderjagt   20

นี่คือข้อมูลที่ตัดตอนมาสำหรับการพยายามยิงประตูในฤดูกาล 2008 NFL ซึ่งเป็นดาต้าเฟรมที่ฉันเรียกว่า 'fg' สมมติว่าจุดข้อมูล 10 จุดนี้แสดงถึงเป้าหมายภาคสนามทั้งหมดที่พยายามในปี 2008 ต่อไปสมมติว่าคุณต้องการทราบระยะห่างของการยิงประตูที่ยาวที่สุดในปีนั้นใครเตะและทำได้ดีหรือไม่ คุณยังต้องการทราบว่ายาวเป็นอันดับสองและยาวเป็นอันดับสาม ฯลฯ ; และในที่สุดคุณก็ต้องการความพยายามในการยิงประตูที่สั้นที่สุด

คุณสามารถทำได้:

sort(fg$Dist, decreasing=T)

ซึ่งผลตอบแทน: 50 48 43 37 34 32 26 25 25 20

นั่นถูกต้อง แต่ไม่มีประโยชน์มากนัก - มันบอกเราถึงระยะทางของการยิงประตูที่ไกลที่สุดระยะที่สองที่ยาวที่สุด ... และสั้นที่สุด แต่นั่นคือทั้งหมดที่เรารู้ - เช่นเราไม่รู้ว่าใครคือนักเตะความพยายามนั้นสำเร็จหรือไม่ ฯลฯ แน่นอนว่าเราต้องการดาต้าเฟรมทั้งหมดที่จัดเรียงในคอลัมน์ "Dist" (พูดอีกอย่างเรา ต้องการจัดเรียงแถวข้อมูลทั้งหมดบนแอตทริบิวต์เดียวDist . ซึ่งจะมีลักษณะดังนี้:

Stadium Home Week Qtr Away Off Def Result       Kicker Dist
751     Out  PHI   14   4  NYG PHI NYG   Good      D.Akers   50
307     Out  DEN   14   2  BAL DEN BAL   Good       J.Elam   48
571     Out   NE    1   2  OAK OAK  NE Missed S.Janikowski   43
702     Out  OAK   15   4  CLE CLE OAK   Good     P.Dawson   37
492     Out   KC   13   3  DEN  KC DEN   Good      L.Tynes   34
491     Out   KC    9   1  OAK OAK  KC   Good S.Janikowski   32
654     Out  NYG   11   2  PHI NYG PHI   Good      J.Feely   26
691     Out  NYJ   17   3  BUF NYJ BUF   Good     M.Nugent   25
164     Out  CHI   13   2   GB CHI  GB   Good      R.Gould   25
80      Out  BAL    1   2  IND IND BAL   Good M.Vanderjagt   20

นี่คือสิ่งที่สั่งทำ มันคือ 'เรียงลำดับ' สำหรับข้อมูลสองมิติ อีกวิธีหนึ่งคือส่งคืนดัชนีจำนวนเต็ม 1D ซึ่งประกอบด้วยหมายเลขแถวซึ่งการจัดเรียงแถวตามเวกเตอร์นั้นจะทำให้คุณมีการจัดเรียงแถวที่ถูกต้องบนคอลัมน์Dist

นี่คือวิธีการทำงาน ข้างต้นเรียงลำดับได้ถูกใช้ในการจัดเรียงคอลัมน์ Dist; ในการจัดเรียง dataframe ทั้งหมดในคอลัมน์ Dist เราใช้ 'order' แบบเดียวกับที่ใช้ 'sort' ด้านบน :

ndx = order(fg$Dist, decreasing=T)

(ฉันมักจะผูกอาร์เรย์ที่ส่งคืนจาก 'order' กับตัวแปร 'ndx' ซึ่งย่อมาจาก 'index' เพราะฉันจะใช้เป็นดัชนีอาร์เรย์เพื่อจัดเรียง)

นั่นคือขั้นตอนที่ 1 นี่คือขั้นตอนที่ 2:

'ndx' สิ่งที่ส่งคืนโดย 'sort' จะถูกใช้เป็นอาร์เรย์ดัชนีเพื่อจัดลำดับดาต้าเฟรมใหม่ 'fg':

fg_sorted = fg[ndx,]

fg_sorted คือ dataframe ที่สั่งซื้อใหม่ทันทีด้านบน

โดยรวมแล้ว 'sort' ใช้เพื่อสร้างดัชนีอาร์เรย์ (ซึ่งระบุลำดับการจัดเรียงของคอลัมน์ที่คุณต้องการจัดเรียง) ซึ่งจะใช้เป็นอาร์เรย์ดัชนีเพื่อจัดลำดับดาต้าเฟรม (หรือเมทริกซ์) ใหม่


2
-1: คำสั่งมีความหมายที่ดีสำหรับเวกเตอร์ คุณสมบัติพื้นฐานของคำสั่ง - ที่ [order (a)] ถูกจัดเรียง - ไม่ได้ระบุไว้อย่างชัดเจน
Jyotirmoy Bhattacharya

3
ไม่ถูกต้อง. คุณต้องดูอีกครั้ง - 'คุณสมบัติพื้นฐาน' นั้นแสดงอย่างชัดเจนในโค้ดสองบรรทัด (พื้นหลังสีเทา) ด้านบน เนื่องจากการเรียงลำดับ w / 'order' เป็นการดำเนินการสองรายการที่แยกจากกันฉันจึงแสดงสิ่งนี้โดยใช้โค้ดสองบรรทัด - บรรทัดแรกสร้างเวกเตอร์ดัชนีและบรรทัดที่สองโดยใช้ดัชนีนั้นในการจัดเรียง OP ขอคำอธิบายไม่ใช่แค่ผลลัพธ์และฉันก็ให้คำอธิบายแก่เขาหนึ่งข้อโดยมีหลักฐานว่าเขาเลือกคำตอบของฉันและเขียนข้อความสั้น ๆ ไว้ด้านบน "Thanks [m] akes perfect sense" ฉันยังผูกผลลัพธ์สุดท้ายไว้กับตัวแปรที่เรียกว่า "fg_sorted"
doug

24

(ฉันคิดว่ามันอาจจะเป็นประโยชน์ในการจัดวางแนวคิดง่ายๆที่นี่เพื่อสรุปเนื้อหาที่ดีที่โพสต์โดย @doug & เชื่อมโยงโดย @duffymo; +1 ต่อแต่ละ btw)

ลำดับจะบอกคุณว่าองค์ประกอบใดของเวกเตอร์ดั้งเดิมที่ต้องใส่ก่อนวินาทีและอื่น ๆ เพื่อจัดเรียงเวกเตอร์ดั้งเดิมในขณะที่อันดับจะบอกคุณว่าองค์ประกอบใดมีค่าต่ำสุดต่ำสุดอันดับสอง ฯลฯ ตัวอย่างเช่น:

> a <- c(45, 50, 10, 96)
> order(a)  
[1] 3 1 2 4  
> rank(a)  
[1] 2 3 1 4  

ดังนั้นจึงorder(a)พูดว่า 'ใส่องค์ประกอบที่สามก่อนเมื่อคุณเรียงลำดับ ... ' ในขณะที่rank(a)พูดว่า 'องค์ประกอบแรกต่ำสุดอันดับสอง ... ' (โปรดทราบว่าทั้งคู่เห็นพ้องกันว่าองค์ประกอบใดต่ำสุด ฯลฯ พวกเขาเพียงแค่นำเสนอข้อมูลที่แตกต่างกัน) ดังนั้นเราจึงเห็นว่าเราสามารถใช้order()จัดเรียงได้ แต่เราไม่สามารถใช้rank()วิธีนั้นได้:

> a[order(a)]  
[1] 10 45 50 96  
> sort(a)  
[1] 10 45 50 96  
> a[rank(a)]  
[1] 50 10 45 96  

โดยทั่วไปorder()จะไม่เท่ากันrank()เว้นแต่ว่าจะเรียงลำดับเวกเตอร์เรียบร้อยแล้ว:

> b <- sort(a)  
> order(b)==rank(b)  
[1] TRUE TRUE TRUE TRUE  

นอกจากนี้เนื่องจากorder()(โดยพื้นฐานแล้ว) ดำเนินการเหนืออันดับของข้อมูลคุณจึงสามารถเขียนข้อมูลเหล่านี้ได้โดยไม่ส่งผลกระทบต่อข้อมูล แต่ในทางกลับกันทำให้เกิดการพูดไม่ชัด

> order(rank(a))==order(a)  
[1] TRUE TRUE TRUE TRUE  
> rank(order(a))==rank(a)  
[1] FALSE FALSE FALSE  TRUE  

1
orderและrankมีการผกผันซึ่งกันและกัน (อย่างน้อยตราบเท่าที่ค่าในaไม่ซ้ำกัน) หากคุณนึกภาพว่าแต่ละชื่อมีชื่อ (/ label) ('1', '2', '3', '4') บนค่าของมันค่าของorder(a)จะบอกคุณว่าตำแหน่งใดในrank(a)แต่ละป้ายกำกับเกิดขึ้น (เช่นค่าที่ 1 order(a)(3) บอกคุณว่า '1' เกิดขึ้นในตำแหน่งที่ 3 ของrank(a)และในทางกลับกัน (เช่นค่าที่ 2 ของrank(a)(3) บอกคุณว่า '2' เกิดขึ้นในตำแหน่งที่ 3 ของorder(a) ) การเรียงสับเปลี่ยนแบบผกผัน: rank(order(a))= order(rank(a))=1 2 3 4
Glen_b

"? order จะบอกให้คุณทราบว่าองค์ประกอบใดของเวกเตอร์ดั้งเดิมที่ต้องใส่ก่อนวินาทีและอื่น ๆ เพื่อจัดเรียงเวกเตอร์ดั้งเดิมในขณะที่อันดับจะบอกคุณว่าองค์ประกอบใดมีค่าต่ำสุดต่ำสุดเป็นอันดับสอง ฯลฯ " ที่นั่น นั่นคือทั้งหมดที่ทุกคนต้องพูด สุดท้าย. ขอขอบคุณ!!
AleksandrH

อธิบายอย่างรวบรัด.. ต้องการอะไร "ลำดับบอกคุณว่าองค์ประกอบใดของเวกเตอร์ดั้งเดิมที่ต้องใส่ก่อนวินาที ฯลฯ เพื่อจัดเรียงเวกเตอร์เดิมในขณะที่อันดับบอกคุณว่าองค์ประกอบใดมีค่าต่ำสุดต่ำสุดเป็นอันดับสอง ฯลฯ ค่า "
sHiBuKaLiDhAsAn

9

การเรียกใช้โค้ดเล็กน้อยนี้ทำให้ฉันเข้าใจฟังก์ชันคำสั่ง

x <- c(3, 22, 5, 1, 77)

cbind(
  index=1:length(x),
  rank=rank(x),
  x, 
  order=order(x), 
  sort=sort(x)
)

     index rank  x order sort
[1,]     1    2  3     4    1
[2,]     2    4 22     1    3
[3,]     3    3  5     3    5
[4,]     4    1  1     2   22
[5,]     5    5 77     5   77

อ้างอิง: http://r.789695.n4.nabble.com/I-don-t-understand-the-order-function-td4664384.html


1
ผลลัพธ์ไม่ตรงกับอินพุต คุณต้องมีการใช้ที่แตกต่างกันในx cbind()
Rich Scriven

แก้ไขเพิ่มเติมเกี่ยวกับความเห็นข้างต้น หวังว่านี่จะช่วยได้ :)
adebesin

2

สิ่งนี้สามารถช่วยคุณได้ในบางจุด

a <- c(45,50,10,96)
a[order(a)]

สิ่งที่คุณจะได้รับคือ

[1] 10 45 50 96

รหัสที่ฉันเขียนระบุว่าคุณต้องการ "a" เป็นส่วนย่อยทั้งหมดของ "a" และคุณต้องการให้เรียงลำดับจากค่าต่ำสุดไปสูงสุด


2

พูดง่ายๆคือorder()ให้ตำแหน่งขององค์ประกอบที่มีขนาดเพิ่มขึ้น

ยกตัวอย่างเช่นorder(c(10,20,30))จะให้1,2,3และ order(c(30,20,10))จะให้3,2,1


0

คล้ายกัน แต่ไม่เหมือนกัน

set.seed(0)
x<-matrix(rnorm(10),1)

# one can compute from the other
rank(x)  == col(x)%*%diag(length(x))[order(x),]
order(x) == col(x)%*%diag(length(x))[rank(x),]
# rank can be used to sort
sort(x) == x%*%diag(length(x))[rank(x),]

อันดับคือการเปลี่ยนลำดับผกผัน: all(x==x[order(x)][rank(x)])เป็นจริงเสมอ การเรียงสับเปลี่ยนบางส่วนเป็นตัวผกผันของตัวเอง แต่ส่วนใหญ่ไม่ใช่ การผกผันเพื่อเรียงลำดับการเปลี่ยนแปลงที่ออกมาจากลำดับ () คืออันดับ () สิ่งนี้อธิบายว่าเหตุใดบางครั้งจึงเหมือนกันและบางครั้งก็ไม่เหมือนกัน
Nick Nassuphis
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.