arrange

Mengurutkan baris berdasarkan satu atau beberapa kolom.

Daftar isi

Topik ini membahas verba arrange() dari dplyr, yaitu verba untuk mengurutkan baris tabel menurut nilai satu atau beberapa kolom. Pembahasan mencakup pengurutan menaik secara bawaan, pembalikan urutan dengan desc(), pengurutan bertingkat dengan beberapa kolom, posisi khusus nilai NA pada hasil pengurutan, perbedaan perilaku kolom teks dan kolom faktor, serta kesalahan yang lazim terjadi. Dataset contoh didefinisikan ulang di awal topik agar seluruh contoh tetap dapat dijalankan ulang secara mandiri.

r
library(tidyverse)
nilai <- tibble::tibble(
  nama = c("Ali", "Budi", "Citra", "Dewi", "Eka", "Fajar", "Gita", "Hana"),
  kelas = c("7A", "7B", "7A", "7B", "7A", "7B", "7A", "7B"),
  nilai = c(88, 74, 92, 65, 81, 79, 95, 70),
  kehadiran = c(0.95, 0.88, 1.00, 0.75, 0.92, 0.85, 0.98, 0.80)
)
text Keluaran
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.2.1     ✔ readr     2.2.0
✔ forcats   1.0.1     ✔ stringr   1.6.0
✔ ggplot2   4.0.3     ✔ tibble    3.3.1
✔ lubridate 1.9.5     ✔ tidyr     1.3.2
✔ purrr     1.2.2     
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors

Pengurutan menaik dengan arrange()#

Verba arrange() mengurutkan seluruh baris tabel menurut kolom yang disebutkan, dan kolomnya ditulis tanpa tanda kutip sebagaimana verba dplyr lainnya. Pengurutan menaik, yaitu dari nilai terkecil ke terbesar, merupakan perilaku bawaannya. Contoh berikut mengurutkan baris menurut kolom kehadiran.

r
nilai |> arrange(kehadiran)
text Keluaran
# A tibble: 8 × 4
  nama  kelas nilai kehadiran
  <chr> <chr> <dbl>     <dbl>
1 Dewi  7B       65      0.75
2 Hana  7B       70      0.8 
3 Fajar 7B       79      0.85
4 Budi  7B       74      0.88
5 Eka   7A       81      0.92
6 Ali   7A       88      0.95
7 Gita  7A       95      0.98
8 Citra 7A       92      1   

Baris Dewi dengan kehadiran terendah kini menempati posisi pertama, dan baris Citra dengan kehadiran penuh menempati posisi terakhir. Isi setiap baris tetap menyatu, sehingga nilai siswa tetap mengikuti namanya, dan yang berubah hanyalah urutan barisnya. Seperti verba dplyr lainnya, arrange() mengembalikan tabel baru tanpa mengubah tabel asalnya. Hasil pengurutan juga sering dipadukan dengan verba lain dalam satu rantai pipe, misalnya difilter terlebih dahulu sebelum diurutkan, atau diurutkan terlebih dahulu sebelum beberapa baris teratasnya diambil dengan head(). Urutan langkah dalam rantai perlu dirancang sesuai hasil yang ingin diperoleh.

Urutan menurun dan beberapa kolom#

Fungsi desc() membalik arah pengurutan kolom yang membungkusnya, sehingga nilai terbesar tampil lebih dahulu. Fungsi ini dipanggil di dalam arrange() pada kolom yang ingin dibalik, sedangkan kolom lain yang tidak dibungkus tetap terurut menaik. desc() juga berlaku pada kolom teks, sehingga urutan alfabetisnya dapat dibalik menjadi urutan terbalik dengan cara yang sama.

r
nilai |> arrange(desc(nilai))
text Keluaran
# A tibble: 8 × 4
  nama  kelas nilai kehadiran
  <chr> <chr> <dbl>     <dbl>
1 Gita  7A       95      0.98
2 Citra 7A       92      1   
3 Ali   7A       88      0.95
4 Eka   7A       81      0.92
5 Fajar 7B       79      0.85
6 Budi  7B       74      0.88
7 Hana  7B       70      0.8 
8 Dewi  7B       65      0.75

Apabila beberapa kolom disebutkan sekaligus, pengurutannya berlaku bertingkat, yaitu kolom pertama menjadi kunci utama, kolom kedua menjadi pemecah seri pada kolom pertama, dan seterusnya. Apabila dua baris memiliki nilai yang sama pada seluruh kolom kuncinya, urutan relatif keduanya mengikuti urutan asal baris pada tabel. Contoh berikut mengurutkan menurut kelas secara menaik, lalu menurut nilai secara menurun di dalam setiap kelasnya.

r
nilai |> arrange(kelas, desc(nilai))
text Keluaran
# A tibble: 8 × 4
  nama  kelas nilai kehadiran
  <chr> <chr> <dbl>     <dbl>
1 Gita  7A       95      0.98
2 Citra 7A       92      1   
3 Ali   7A       88      0.95
4 Eka   7A       81      0.92
5 Fajar 7B       79      0.85
6 Budi  7B       74      0.88
7 Hana  7B       70      0.8 
8 Dewi  7B       65      0.75

Empat baris kelas 7A tampil lebih dahulu dengan urutan nilai dari yang terbesar, disusul empat baris kelas 7B dengan urutan yang sama. Pola bertingkat semacam ini lazim dipakai untuk membuat peringkat di dalam kelompok tanpa mengubah susunan kelompoknya.

Posisi nilai NA pada pengurutan#

Perbandingan dengan nilai NA tidak dapat dipastikan hasilnya, sehingga baris bernilai NA tidak dapat ditempatkan secara logis di antara baris bernilai lain. dplyr menyelesaikan ketidakpastian itu dengan aturan tetap, yaitu baris bernilai NA selalu ditempatkan paling akhir, baik pada pengurutan menaik maupun menurun. Tabel kecil berikut memuat satu skor tugas yang belum tersedia untuk memperlihatkan aturan itu.

r
skor_tugas <- tibble::tibble(
  nama = c("Ali", "Budi", "Citra", "Dewi"),
  skor = c(88, NA, 75, 92)
)
skor_tugas |> arrange(skor)
skor_tugas |> arrange(desc(skor))
text Keluaran
# A tibble: 4 × 2
  nama   skor
  <chr> <dbl>
1 Citra    75
2 Ali      88
3 Dewi     92
4 Budi     NA
# A tibble: 4 × 2
  nama   skor
  <chr> <dbl>
1 Dewi     92
2 Ali      88
3 Citra    75
4 Budi     NA

Pada kedua arah, baris Budi yang skornya NA selalu menempati posisi terakhir. Pemisahan baris semacam ini sekaligus memudahkan pencarian, karena seluruh baris yang belum lengkap terkumpul di satu tempat setelah pengurutan. Apabila baris-baris itu perlu diperiksa lebih lanjut, hasil pengurutan dapat dipadukan dengan filter() dan is.na() untuk mengisolasi baris yang belum lengkap.

Kolom teks dan kolom faktor#

Kolom teks diurutkan menurut urutan alfabetis isinya, sedangkan kolom faktor diurutkan menurut urutan tingkatnya yang sudah ditetapkan saat faktor dibuat. Contoh berikut mengurutkan menurut kelas yang bertipe teks, lalu menurut kehadiran sebagai pemecah serinya.

r
nilai |> arrange(kelas, kehadiran)
text Keluaran
# A tibble: 8 × 4
  nama  kelas nilai kehadiran
  <chr> <chr> <dbl>     <dbl>
1 Eka   7A       81      0.92
2 Ali   7A       88      0.95
3 Gita  7A       95      0.98
4 Citra 7A       92      1   
5 Dewi  7B       65      0.75
6 Hana  7B       70      0.8 
7 Fajar 7B       79      0.85
8 Budi  7B       74      0.88

Nilai teks 7A diperlakukan lebih dahulu daripada 7B karena urutan alfabetisnya, kemudian kehadiran diurutkan menaik di dalam setiap kelasnya. Perilaku ini berbeda pada kolom faktor yang urutannya tidak mengikuti alfabet. Faktor menyimpan sekumpulan tingkat yang urutannya ditetapkan secara eksplisit, dan arrange() menghormati urutan itu.

r
jadwal <- tibble::tibble(
  hari = factor(c("Jumat", "Senin", "Rabu"),
                levels = c("Senin", "Selasa", "Rabu", "Kamis", "Jumat")),
  kegiatan = c("laboratorium", "rapat", "olahraga")
)
jadwal |> arrange(hari)
text Keluaran
# A tibble: 3 × 2
  hari  kegiatan    
  <fct> <chr>       
1 Senin rapat       
2 Rabu  olahraga    
3 Jumat laboratorium

Hasilnya berurutan Senin, Rabu, lalu Jumat sesuai urutan tingkat yang diberikan pada argumen levels, dan bukan urutan alfabetis Jumat, Rabu, Senin. Perbedaan inilah yang membuat faktor tepat untuk kolom yang urutannya bermakna, seperti hari dalam seminggu atau jenjang dengan tingkat yang berurutan, karena urutan alfabetisnya tidak membawa makna tersebut.

Kesalahan umum#

Kesalahan yang khas pada arrange() adalah menuliskan nama kolom dengan tanda kutip. Pemanggilan berikut dimaksudkan untuk mengurutkan menurut kolom nilai, tetapi yang diterima verba adalah sebuah teks.

r
nilai |> arrange("nilai")
text Keluaran
# A tibble: 8 × 4
  nama  kelas nilai kehadiran
  <chr> <chr> <dbl>     <dbl>
1 Ali   7A       88      0.95
2 Budi  7B       74      0.88
3 Citra 7A       92      1   
4 Dewi  7B       65      0.75
5 Eka   7A       81      0.92
6 Fajar 7B       79      0.85
7 Gita  7A       95      0.98
8 Hana  7B       70      0.8 

Pemanggilan itu tidak menghasilkan error dan keluarannya tampak normal, tetapi urutan barisnya tidak berubah sama sekali. Kegagalan senyap semacam ini lebih berbahaya daripada error karena hasilnya bisa langsung dipakai tanpa disadari keliru. Perbaikannya adalah menuliskan nama kolom tanpa tanda kutip, sebagaimana konvensi seluruh verba dplyr, sehingga nama itu dinilai sebagai kolom dan bukan sebagai teks. Pemeriksaan cepat untuk kasus serupa adalah membandingkan urutan hasil dengan tabel asalnya, karena apabila keduanya identik, ada argumen yang tidak dibaca sebagaimana mestinya.

Ringkasan#

  • arrange() mengurutkan baris menurut kolom yang disebutkan dengan arah menaik secara bawaan, dan desc() membalik arahnya.
  • Beberapa kolom diurutkan bertingkat, yaitu kolom pertama menjadi kunci utama dan kolom berikutnya memecah serinya.
  • Baris bernilai NA selalu ditempatkan paling akhir pada arah pengurutan mana pun.
  • Kolom teks diurutkan alfabetis, sedangkan kolom faktor diurutkan menurut urutan tingkatnya.
  • Nama kolom yang diberi tanda kutip tidak dianggap kolom, sehingga pengurutannya gagal senyap tanpa pesan error.

Referensi#