Urutan baris dalam data.table dalam urutan menurun pada kunci string `order (-x, v)` memberikan kesalahan pada data.table 1.9.4 atau sebelumnya

125

Katakanlah saya memiliki berikut data.tabledi R:

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

Saya ingin memesannya dengan dua kolom (katakanlah kolom xdan v). Saya menggunakan ini:

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

Tapi sekarang, saya ingin mengurutkannya x(dalam urutan menurun) dan memiliki kode berikut:

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

Oleh karena itu, menurut saya kesalahan ini disebabkan oleh fakta itu class(DT$x)=character. Bisakah Anda memberi saya saran untuk mengatasi masalah ini?

Saya tahu saya dapat menggunakan DT[order(x,decreasing=TRUE)], tetapi saya ingin mengetahui sintaks untuk mengurutkan berdasarkan beberapa kolom menggunakan kedua cara (beberapa menurun, beberapa meningkat) pada saat yang bersamaan.

Perhatikan bahwa jika Anda menggunakan DT[order(-y,v)]hasilnya ok, tetapi jika Anda menggunakan DT[order(-x,v)]ada kesalahan. Jadi, pertanyaan saya adalah: bagaimana mengatasi kesalahan ini?

nhern121
sumber
6
Pertanyaan yang menarik, tetapi jika Anda bekerja dengan kumpulan data yang besar, Anda mungkin harus menyetel kunci untuk data.tables Anda. Kunci menempatkan data Anda dalam urutan yang memaksimalkan pengindeksan, subset, agregasi-oleh-grup, dll. Itu mungkin bukan format pilihan Anda untuk mencetak data, tetapi seringkali harga yang kecil untuk membayar kecepatan yang akan diperoleh Anda .
Josh O'Brien
Namun, bagi saya itu DT[order(-x)]bukanlah pernyataan yang setara dengan setorder(DT, -x)karena setorder()benar-benar bertindak DTsementara yang lain tidak. Pernyataan yang setara akan menjadi DT <- DT [order (-x)] setorder (DT, -x) Saya sangat baru mengenal R jadi harap perbaiki jika saya salah.
jeromeResearch
@jerome Anda benar. Pankil tidak mengatakan bahwa mereka setara, jadi saya rasa tidak apa-apa.
Frank
1
Saya setuju dengan @smci bahwa pengeditan judul masuk akal di sini, meskipun saya akan mengubahnya untuk menunjukkan bahwa pertanyaan ini tidak lagi relevan, misalnya dengan menambahkan "dalam data.table 1.9.4 atau sebelumnya" ke judul sehingga orang tidak lanjutkan mendarat di sini dari google mengharapkan sesuatu yang lain. Saya melakukan ini dengan salah satu pertanyaan saya stackoverflow.com/questions/30035939/…
Frank
1
Nestorggh, jangan rollback judul baru kecuali Anda dapat memperbaikinya. "sort row in data.table" hampir tidak mengatakan apa-apa, bahwa fungsionalitas dasar ada untuk yonks. Judul perlu menyebutkan masalah Anda yang sebenarnya (beberapa kunci yang salah satunya adalah decr order). Juga penting bahwa ini adalah masalah yang diketahui di 1.9.4 dan sebelumnya dan tidak lagi menjadi masalah.
smci

Jawaban:

144

Memperbarui

data.table v1.9.6 + sekarang mendukung upaya asli OP dan jawaban berikut tidak lagi diperlukan.


Anda bisa menggunakan 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
Matthew Plourde
sumber
1
Seperti yang ditunjukkan oleh @PankilShah di bawah ini, ini telah diperbaiki untuk beberapa waktu dan pendekatan asli OP sekarang berfungsi seperti yang diharapkan. Saya tidak dapat menemukan komit karena telah diperbaiki pada level C dan saya tidak tahu apa yang harus dicari.
MichaelChirico
1
Keren Terimakasih. Tampaknya tidak mungkin ada orang yang akan berakhir di sini ... tetapi di sisi lain saya sendiri berakhir di sini karena mencari sesuatu yang tidak jelas terkait.
MichaelChirico
@MichaelChirico sebenarnya, saya secara rutin mendapatkan suara positif untuk jawaban ini, jadi saya sangat senang Anda menunjukkan hal ini. Saya sebenarnya bukan pengguna data.table dan belum mengikuti perkembangannya.
Matthew Plourde
Ini sangat berguna untuk menyatakan rilis jumlah sebenarnya (1.9.6?), Jadi kita tidak harus pergi berburu di arsip NEWS.md .
smci
23

Anda hanya dapat menggunakan -entri numerik, sehingga Anda dapat menggunakan pengurangan dan penghapusan yang Anda inginkan dalam urutan yang meningkat:

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
James
sumber
3
Saya suka cara ini, kecuali Anda memiliki dua characterkolom dan Anda ingin mengurutkan satu bertambah dan yang lainnya menurun.
Matthew Plourde
1
@mplourde Saya rasa Anda dapat menggabungkan solusi Anda dengan yang satu ini untuk mengatasi masalah yang Anda ajukan. Misalnya, Anda dapat meletakkan: DT[order(x,-rank(w),decreasing=TRUE)]mengingat itu xdan wkeduanya adalah kolom karakter. Terima kasih!
nhern121
17

DT[order(-x)]bekerja seperti yang diharapkan. Saya memiliki data.table versi 1.9.4. Mungkin ini telah diperbaiki dalam versi terbaru.
Juga, saya menyarankan setorder(DT, -x)sintaks sesuai dengan perintah set * seperti setnames,setkey

Pankil Shah
sumber