เรียงแถวใน data.table ตามลำดับที่ลดลงบนคีย์สตริง `order (-x, v)` ให้ข้อผิดพลาดบน data.table 1.9.4 หรือก่อนหน้า


125

สมมติว่าฉันมีสิ่งต่อไปนี้data.tableในR:

  library(data.table)
  DT = data.table(x=rep(c("b","a","c"),each=3), y=c(1,3,6), v=1:9)

ฉันต้องการเรียงลำดับตามสองคอลัมน์ (พูดว่าคอลัมน์xและv) ฉันใช้สิ่งนี้:

 DT[order(x,v)] # sorts first by x then by v (both in ascending order)

แต่ตอนนี้ฉันต้องการจัดเรียงตามx(ตามลำดับที่ลดลง) และมีรหัสต่อไปนี้:

  DT[order(-x)] #Error in -x : invalid argument to unary operator

class(DT$x)=characterดังนั้นผมคิดว่าข้อผิดพลาดนี้เกิดจากความจริงที่ว่า คุณช่วยให้ข้อเสนอแนะเพื่อแก้ปัญหานี้ได้ไหม

ฉันรู้ว่าฉันสามารถใช้ได้DT[order(x,decreasing=TRUE)]แต่ฉันต้องการทราบว่าไวยากรณ์เพื่อจัดเรียงตามหลายคอลัมน์โดยใช้ทั้งสองวิธี (ลดลงบ้างเพิ่มขึ้นบ้าง) ในเวลาเดียวกัน

โปรดทราบว่าหากคุณใช้DT[order(-y,v)]ผลลัพธ์ก็โอเค แต่ถ้าคุณใช้DT[order(-x,v)]มีข้อผิดพลาด ดังนั้นคำถามของฉันคือ: จะแก้ไขข้อผิดพลาดนี้ได้อย่างไร?


6
คำถามที่น่าสนใจ แต่ถ้าคุณกำลังทำงานกับชุดข้อมูลขนาดใหญ่คุณควรตั้งค่าคีย์สำหรับ data.tables ของคุณ คีย์จะจัดเรียงข้อมูลของคุณในลำดับที่เพิ่มการจัดทำดัชนีการย่อยการรวมกลุ่มตามลำดับและอื่น ๆ ซึ่งอาจไม่ใช่รูปแบบที่คุณต้องการสำหรับการพิมพ์ข้อมูล แต่มักจะเป็นราคาเพียงเล็กน้อยที่คุณต้องจ่ายเพื่อความเร็วที่จะได้รับ .
Josh O'Brien

อย่างไรก็ตามสำหรับฉันแล้วดูเหมือนว่าDT[order(-x)]ไม่ใช่คำสั่งที่เทียบเท่ากับsetorder(DT, -x)เพราะใช้งานได้setorder()จริงในDTขณะที่อีกฝ่ายไม่ทำ ข้อความเทียบเท่าจะเป็น DT <- DT [order (-x)] setorder (DT, -x) ฉันยังใหม่กับ R มากดังนั้นโปรดแก้ไขหากฉันเข้าใจผิด
jeromeResearch

@jerome คุณถูกต้อง. พันกิลไม่ได้บอกว่าพวกเขาเทียบเท่ากันดังนั้นฉันคิดว่ามันก็ดีเหมือนเดิม
Frank

1
ฉันเห็นด้วยกับ @smci ว่าการแก้ไขชื่อมีความหมายที่นี่แม้ว่าฉันจะเปลี่ยนเพื่อระบุว่าคำถามนี้ไม่เกี่ยวข้องอีกต่อไปเช่นการเพิ่ม "in data.table 1.9.4 หรือก่อนหน้า" ลงในชื่อเพื่อไม่ให้คนอื่น ๆ เชื่อมโยงไปถึงที่นี่จาก Google โดยคาดหวังอย่างอื่น ฉันทำสิ่งนี้ด้วยหนึ่งในคำถามของฉันstackoverflow.com/questions/30035939/…
Frank

1
Nestorggh โปรดอย่าย้อนกลับชื่อใหม่เว้นแต่คุณจะปรับปรุงได้ "เรียงแถวใน data.table" แทบจะไม่พูดอะไรเลยว่าฟังก์ชันพื้นฐานนั้นมีไว้สำหรับ yonks ชื่อเรื่องต้องพูดถึงปัญหาที่แท้จริงของคุณ (คีย์หลายตัวโดยที่คีย์หนึ่งเป็นคำสั่ง decr) สิ่งสำคัญเช่นกันว่านี่เป็นปัญหาที่ทราบแล้วใน 1.9.4 และก่อนหน้านี้และไม่ใช่ปัญหาอีกต่อไป
smci

คำตอบ:


145

ปรับปรุง

data.table v1.9.6 + รองรับความพยายามเดิมของ OP แล้วและคำตอบต่อไปนี้ไม่จำเป็นอีกต่อไป


คุณสามารถใช้DT[order(-rank(x), y)].

   x y v
1: c 1 7
2: c 3 8
3: c 6 9
4: b 1 1
5: b 3 2
6: b 6 3
7: a 1 4
8: a 3 5
9: a 6 6

1
ตามที่ระบุไว้โดย @PankilShah ด้านล่างนี้ได้รับการแก้ไขมาระยะหนึ่งแล้วและแนวทางดั้งเดิมของ OP ได้ผลตามที่คาดไว้ ฉันไม่พบคอมมิตเนื่องจากได้รับการแก้ไขในระดับ C และฉันไม่รู้ว่าจะค้นหาอะไร
MichaelChirico

1
ขอบคุณครับ ดูเหมือนว่าจะไม่น่าจะมีใครมาลงเอยที่นี่ได้ ... แต่ในทางกลับกันฉันเองก็จบลงที่นี่จากการ googling อะไรสักอย่าง
MichaelChirico

@MichaelChirico ที่จริงฉันมักจะได้รับคะแนนโหวตสำหรับคำตอบนี้ดังนั้นฉันดีใจมากที่คุณชี้ให้เห็นสิ่งนี้ ฉันไม่ใช่ผู้ใช้data.tableจริง ๆและไม่ได้ติดตามการพัฒนา
Matthew Plourde

มันมีประโยชน์มากที่จะระบุจำนวนการเปิดตัวจริง (1.9.6?) ดังนั้นเราจึงไม่ต้องไปล่าสัตว์ในจดหมายเหตุของ NEWS.md
smci

23

คุณสามารถใช้ได้เฉพาะ-กับรายการตัวเลขดังนั้นคุณสามารถใช้การลดและลบรายการที่คุณต้องการตามลำดับที่เพิ่มขึ้น:

DT[order(x,-v,decreasing=TRUE),]
      x y v
 [1,] c 1 7
 [2,] c 3 8
 [3,] c 6 9
 [4,] b 1 1
 [5,] b 3 2
 [6,] b 6 3
 [7,] a 1 4
 [8,] a 3 5
 [9,] a 6 6

3
ฉันชอบวิธีนี้เว้นแต่คุณจะมีสองcharacterคอลัมน์และคุณต้องการเรียงลำดับหนึ่งเพิ่มขึ้นและอีกคอลัมน์ลดลง
Matthew Plourde

1
@mplourde ฉันคิดว่าคุณสามารถรวมโซลูชันของคุณกับอันนี้เพื่อจัดการกับปัญหาที่คุณวางไว้ ตัวอย่างเช่นคุณสามารถใส่: DT[order(x,-rank(w),decreasing=TRUE)]กำหนดxและwเป็นคอลัมน์อักขระทั้งสอง ขอบคุณ!
nhern121

17

DT[order(-x)]ทำงานได้ตามที่คาดไว้ ฉันมี data.table เวอร์ชัน 1.9.4 อาจจะได้รับการแก้ไขในเวอร์ชันล่าสุด
นอกจากนี้ผมขอแนะนำsetorder(DT, -x)ไวยากรณ์ในการรักษาด้วยชุด *คำสั่งที่ชอบsetnames,setkey

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.