Operasi Vektorisasi

Aritmetika pada seluruh vektor sekaligus tanpa perulangan eksplisit.

Daftar isi

Topik ini membahas operasi vektorisasi (vectorization), yaitu penerapan operasi pada seluruh elemen vektor sekaligus tanpa perulangan eksplisit. Pembahasan mencakup aritmetika antarvektor, perbandingan logika tervektorisasi, aturan recycling ketika panjang kedua vektor tidak sama, fungsi agregasi, serta perbandingan singkat dengan perulangan for. Setelah membacanya, perhitungan atas banyak nilai sekaligus dapat ditulis dalam satu ekspresi ringkas tanpa langkah yang ditulis berulang-ulang.

Aritmetika pada seluruh elemen#

Contoh berikut menggunakan catatan suhu sensor yang dibaca dua kali sehari selama empat hari. Vektor suhu_pagi menyimpan suhu pagi, dan vektor suhu_sore menyimpan suhu sore pada hari-hari yang sama. Selisihnya dihitung dengan satu pengurangan:

r
suhu_pagi <- c(24.1, 23.8, 25.0, 24.6)
suhu_sore <- c(31.2, 30.5, 32.0, 31.8)
suhu_sore - suhu_pagi
text Keluaran
[1] 7.1 6.7 7.0 7.2

Operator pengurangan bekerja elemen per elemen (element-wise): angka pertama suhu_sore dikurangi angka pertama suhu_pagi, lalu angka kedua dengan angka kedua, dan seterusnya. Tidak ada satu pun langkah yang ditulis berulang. Semua operator aritmetika berperilaku sama, termasuk +, *, dan /. Operasi antara vektor dan angka tunggal mengikuti pola ini juga, misalnya konversi suhu pagi dari Celsius ke Fahrenheit:

r
suhu_pagi * 9 / 5 + 32
text Keluaran
[1] 75.38 74.84 77.00 76.28

Angka tunggal sesungguhnya vektor berpanjang satu, sehingga operasi vektor dengan angka tunggal bukan pengecualian, melainkan kasus khusus dari operasi antarvektor. Satu rumus yang sama diterapkan pada keempat nilai tanpa penyesuaian apa pun. Perhatikan pula format keluarannya: angka 77 tampil sebagai 77.00 karena seluruh elemen satu vektor ditampilkan dengan banyak desimal yang sama.

Perbandingan logika tervektorisasi#

Operator perbandingan juga tervektorisasi. Satu pernyataan menilai seluruh elemen sekaligus dan menghasilkan vektor logical, yaitu vektor berisi TRUE dan FALSE:

r
suhu_sore > 31
text Keluaran
[1]  TRUE FALSE  TRUE  TRUE

Keluaran tersebut terbaca: suhu sore melebihi 31 derajat pada hari pertama, tidak pada hari kedua, lalu kembali melebihi pada hari ketiga dan keempat. Dengan satu baris, empat pertanyaan terjawab sekaligus, dan vektor hasilnya sama panjang dengan vektor yang dibandingkan sehingga setiap elemen memperoleh jawabannya masing-masing. Operator lain seperti <, >=, ==, dan != bekerja dengan pola yang sama. Vektor logical hasil perbandingan ini bukan sekadar keluaran, tetapi bahan mentah untuk penghitungan pada bagian agregasi di bawah.

Perbandingan dapat dirangkai dengan operator logika & dan |, yang juga tervektorisasi. Dua vektor perbandingan ditempel berdampingan dan dievaluasi posisi demi posisi:

r
suhu_pagi > 24 & suhu_sore > 31
text Keluaran
[1]  TRUE FALSE  TRUE  TRUE

Hasil TRUE hanya muncul pada hari yang memenuhi kedua syarat sekaligus. Kehati-hatian diperlukan pada bentuk operatornya. Bentuk tunggal & dan | bekerja elemen per elemen pada vektor, sedangkan bentuk ganda && dan || menuntut masukan berpanjang satu dan melaporkan error apabila diberi vektor. Bentuk ganda memang ditujukan untuk percabangan dan pengendalian alur, bukan untuk vektor data.

Aturan recycling#

Apabila kedua vektor tidak sama panjangnya, R mendaur ulang vektor yang lebih pendek, dan mekanisme ini disebut recycling. Elemen vektor pendek diulang dari awal sampai panjangnya menyamai vektor terpanjang. Kasus yang paling sering terjadi adalah vektor berpanjang satu, sebagaimana angka tunggal pada bagian sebelumnya:

r
c(10, 20, 30, 40) + 1
text Keluaran
[1] 11 21 31 41

Angka 1 diulang empat kali sehingga setiap elemen bertambah satu. Masalah muncul apabila panjang vektor yang lebih panjang bukan kelipatan panjang vektor yang lebih pendek. Perhitungan tetap dijalankan, tetapi R menampilkan peringatan:

r
c(10, 20, 30) + c(1, 2)
text Keluaran
Warning in c(10, 20, 30) + c(1, 2) :
  longer object length is not a multiple of shorter object length
[1] 11 22 31

Keluaran tetap dihasilkan: elemen ketiga kembali berpasangan dengan elemen pertama vektor pendek, sehingga 30 dijumlahkan dengan 1. Peringatan ini patut diperiksa, karena pembagian pasangan yang tidak rata sering menandakan kesalahan data, bukan niat mendaur ulang secara sengaja.

Agregasi menjadi satu angka#

Hasil perhitungan vektor sering perlu diringkas menjadi satu angka. Fungsi agregasi menerima seluruh vektor sebagai argumen dan mengembalikan satu nilai. Empat fungsi yang paling sering digunakan adalah sum(), mean(), max(), dan min():

r
sum(suhu_sore > 31)
mean(suhu_pagi)
max(suhu_sore)
min(suhu_pagi)
text Keluaran
[1] 3
[1] 24.375
[1] 32
[1] 23.8

Pernyataan pertama menghitung banyaknya hari dengan suhu sore di atas 31. Hasilnya tiga karena dalam penjumlahan, TRUE diperlakukan sebagai 1 dan FALSE sebagai 0. Pernyataan berikutnya menghitung rata-rata suhu pagi, suhu sore tertinggi, dan suhu pagi terendah. Rata-rata dihitung dengan menjumlahkan seluruh elemen lalu membaginya dengan panjang vektor, sehingga angka 24.375 dapat diverifikasi dengan tangan. Keempat fungsi ini mengembalikan vektor berpanjang satu, sehingga keluarannya selalu diawali indeks [1]. Pola operasi tervektorisasi yang dilanjutkan agregasi adalah cara kerja paling umum dalam analisis data dengan R, dan seluruhnya berlangsung tanpa satu pun perulangan yang ditulis tangan.

Perbandingan dengan perulangan eksplisit#

Hasil yang sama dapat dihasilkan dengan perulangan for, dan membandingkan kedua pendekatan tersebut memperlihatkan perbedaan pola pikir. Dengan perulangan, langkah dituliskan satu per satu: wadah disiapkan, indeks diulang, selisih dihitung, lalu hasilnya disimpan.

r
selisih <- numeric(length(suhu_sore))
for (i in seq_along(selisih)) {
  selisih[i] <- suhu_sore[i] - suhu_pagi[i]
}
selisih
text Keluaran
[1] 7.1 6.7 7.0 7.2

Hasilnya identik dengan versi vektorisasi, tetapi kodenya memuat rincian mekanisme yang sebenarnya tidak perlu diperhatikan, yaitu wadah numeric() dan variabel indeks i. Versi vektorisasi hanya menyatakan hubungan antara dua vektor, dan R yang mengurus langkah-langkahnya melalui kode C internal. Untuk data besar, versi vektorisasi biasanya juga berjalan lebih cepat. Perulangan for tetap berguna pada situasi yang memang membutuhkan langkah berurutan, tetapi pada tahap ini kebiasaan memikirkan seluruh vektor sekaligus lebih produktif dan lebih sesuai dengan desain bahasanya. Fungsi seq_along() pada contoh itu menghasilkan deret indeks dari satu sampai panjang vektornya, sehingga wadah dan rentangnya selalu sepadan.

Ringkasan#

  • Operasi aritmetika dan perbandingan bekerja elemen per elemen pada seluruh vektor, tanpa perulangan eksplisit.
  • Vektor pendek didaur ulang melalui aturan recycling, dan panjang yang bukan kelipatan memunculkan peringatan.
  • Fungsi sum(), mean(), max(), dan min() merangkum seluruh vektor menjadi satu angka.
  • Perulangan for dapat menghasilkan keluaran yang sama, tetapi vektorisasi menyatakan maksud dengan lebih ringkas.

Referensi#