Menu

Matrix di R: matrix(), cbind, rbind, dan perkalian matrix

Cara membuat matrix dengan matrix(), cbind(), dan rbind(), mengakses baris dan kolom, serta membedakan * per elemen dari perkalian matrix sungguhan %*%.

Halaman ini dilengkapi editor yang bisa dijalankan. Edit, jalankan, dan lihat output-nya seketika.

Matrix adalah vector dengan dimensi

Matrix di R adalah persegi panjang berisi nilai (baris dan kolom) yang setiap selnya bertipe sama, biasanya angka. Di baliknya, matrix benar-benar sebuah vector yang ditempeli atribut dim, dan itu menjelaskan sebagian besar perilakunya: satu tipe di seluruh isinya, matematika tervektorisasi di mana-mana.

Kamu membuatnya dengan mengubah bentuk sebuah vector memakai matrix():

Enam nilai, dua baris: R menghitung sendiri bahwa dibutuhkan tiga kolom. dim() melaporkan kedua dimensi sekaligus sebagai 2 3; nrow() dan ncol() memberikannya secara terpisah.

Perhatikan baik-baik matrix yang tercetak: nilainya berjalan 1 2 menurun di kolom pertama, lalu 3 4 menurun di kolom berikutnya. R mengisi matrix kolom demi kolom secara default. Kalau datamu dibaca baris demi baris (cara manusia biasanya menulis), nyatakan dengan byrow = TRUE:

Sekarang baris pertamanya adalah 1 2 3. Lupa menulis byrow = TRUE tidak menimbulkan error; kamu hanya diam-diam mendapat susunan angka yang sama yang tampak seperti hasil transpose, jadi biasakan memeriksa tata letak yang tercetak setiap kali kamu membuat matrix dari nilai mentah.

Pengindeksan: m[row, column]

Pengindeksan matrix menerima dua posisi di dalam satu pasang kurung siku, baris sebelum koma dan kolom sesudahnya, keduanya dihitung mulai dari 1:

Mengosongkan sebuah posisi berarti "semuanya": m[1, ] adalah seluruh baris pertama, m[, 2] seluruh kolom kedua. Perhatikan bahwa keduanya kembali sebagai vector biasa: R membuang dimensi yang menyusut menjadi berukuran 1. Itu praktis saat interaktif tapi menjadi jebakan di kode, karena fungsi yang mengharapkan matrix akan tersedak saat menerima vector. Minta R mempertahankan bentuknya dengan drop = FALSE:

dim() sekarang melaporkan 1 3, jadi masih berupa matrix. Setiap kali kamu mengambil satu baris atau kolom di dalam fungsi, tulis drop = FALSE; bug yang dicegahnya (kode yang berjalan pada data lebar tapi rusak pada data satu kolom) sangat menyiksa untuk dilacak.

Mask logika juga bekerja di sini: m[m > 3] mengembalikan semua sel yang nilainya di atas 3, sebagai vector.

Menyusun dengan cbind() dan rbind()

Alih-alih mengubah bentuk satu vector panjang, kamu bisa menyusun matrix dari potongan-potongan: cbind() menyambung vector sebagai kolom, rbind() sebagai baris. Fungsi yang sama juga bisa memperpanjang matrix yang sudah ada:

Nama-namanya ikut terbawa bersama vector: cbind() otomatis memakai heights dan weights sebagai nama kolom, sehingga matrix yang tercetak tetap mudah dibaca. Kedua fungsi mengharuskan panjangnya sejajar (dengan daur ulang untuk nilai sepanjang 1); menyambung vector sepanjang 3 ke matrix berisi 4 baris akan memunculkan peringatan.

Nama kolom dan baris juga bisa diatur langsung lewat colnames(m) <- ... dan rownames(m) <- ..., setelah itu kamu bisa mengakses berdasarkan nama: people[, "weights"].

* per elemen vs perkalian matrix sungguhan %*%

Inilah perbedaan yang paling penting di seluruh artikel ini. R punya dua operator perkalian untuk matrix, dan keduanya menghitung hal yang sama sekali berbeda:

  • a * a adalah per elemen: setiap sel dikalikan dengan sel yang sesuai. 1 2 3 4 menjadi 1 4 9 16, tersusun dalam bentuk yang sama. Ini hanyalah aritmetika tervektorisasi, * yang sama yang kamu pakai pada vector.
  • a %*% a adalah perkalian matrix dari aljabar linear: setiap sel hasil adalah satu baris matrix pertama dikali satu kolom matrix kedua, lalu dijumlahkan. Input yang sama menghasilkan 7 10 15 22, angka yang sama sekali berbeda.

Jalankan potongan kode itu dan bandingkan kedua output-nya berdampingan; melihat keduanya berbeda pada input yang identik itulah yang membuat perbedaannya melekat. Kalau kamu menulis * padahal perhitungannya butuh %*%, R tidak akan memperingatkanmu (bentuknya sama-sama cocok untuk matrix persegi), kamu hanya mendapat angka yang salah. Di kode statistika (matrix kovarians, aljabar model linear), ini salah satu bug diam-diam yang klasik.

t() melakukan transpose, yaitu menukar baris dan kolom, dan sering muncul di sebelah %*% karena perkalian matrix butuh dimensi bagian dalam yang cocok:

Sebagai pelengkap: solve(m) membalikkan (invers) sebuah matrix, dan %*% dengan vector memperlakukan vector itu sebagai matrix satu kolom. Sedalam itulah yang dibutuhkan kebanyakan pekerjaan data.

Ringkasan baris dan kolom

Menjumlahkan atau merata-ratakan per baris dan per kolom begitu sering dilakukan sampai R menyediakan fungsi khusus yang cepat untuk itu:

rowSums() meringkas setiap baris menjadi satu angka (6 15 di sini), colSums() setiap kolom (5 7 9), dan varian Means merata-ratakan alih-alih menjumlahkan. Utamakan fungsi-fungsi ini daripada loop buatan sendiri atau bahkan apply(m, 1, sum): lebih jelas dan lebih cepat. Untuk ringkasan yang tidak dicakup keempatnya (misalnya nilai maksimum per kolom), keluarga apply adalah alat umumnya: apply(m, 2, max).

Matrix atau data frame?

Keduanya berbentuk persegi panjang, jadi mana yang dipilih?

  • Matrix: setiap sel bertipe sama, dan perhitungannya penting. Komputasi numerik, aljabar linear, perhitungan jarak, kisi seperti gambar. Matrix lebih ramping dan operasinya lebih cepat justru karena jaminan satu tipe itu.
  • Data frame: kolom-kolom dengan tipe yang berbeda, nama di sebelah umur di sebelah penanda logika. Inilah data tabel dunia nyata, dan inilah yang diharapkan hampir semua fungsi analisis data.

Aturan yang bagus: kalau kamu secara alami akan membukanya di spreadsheet dengan kolom-kolom bernama dan bercampur, itu data frame. Kalau itu kisi berisi angka yang ingin kamu olah dengan aljabar, itu matrix. Mengonversi di antara keduanya mudah (as.matrix(), as.data.frame()), tapi as.matrix() pada data frame yang punya kolom teks apa pun akan memaksa semuanya menjadi character, jadi konversi hanya kolom-kolom numeriknya.

Yang kamu bawa pulang

  • Matrix adalah vector dengan dimensi: satu tipe di seluruh isinya, dibuat dengan matrix(data, nrow, ncol), dan diisi kolom demi kolom kecuali kamu memberikan byrow = TRUE.
  • Akses dengan m[row, col]; posisi kosong berarti "semua"; tambahkan drop = FALSE saat mengambil satu baris atau kolom di dalam kode.
  • cbind() dan rbind() menyusun matrix dari vector atau memperpanjang matrix yang sudah ada.
  • * bekerja per elemen, %*% adalah perkalian matrix sungguhan: input sama, jawaban berbeda, tanpa peringatan.
  • rowSums() / colSums() / rowMeans() / colMeans() menangani ringkasan sehari-hari.

Berikutnya: factor, cara R merepresentasikan data kategorik, dan jebakan yang menyertainya.

Pertanyaan yang sering diajukan

Bagaimana cara membuat matrix di R?

matrix(1:6, nrow = 2) mengubah bentuk sebuah vector menjadi 2 baris dan 3 kolom, diisi kolom demi kolom. Tambahkan byrow = TRUE untuk mengisinya baris demi baris. Kamu juga bisa menyusun matrix dari beberapa vector: cbind() menyambungnya sebagai kolom, rbind() sebagai baris.

Apa perbedaan * dan %*% di R?

* mengalikan elemen demi elemen: setiap sel dikalikan dengan sel yang sesuai, dan bentuknya harus sejajar. %*% adalah perkalian matrix sungguhan dari aljabar linear (baris dikali kolom, jadi dimensi bagian dalamnya harus cocok). Keduanya memberi hasil yang sama sekali berbeda pada matrix yang sama, dan memakai * padahal maksudmu %*% adalah bug diam-diam yang klasik.

Bagaimana cara mengambil satu baris atau kolom matrix di R?

Kosongkan posisi lainnya: m[1, ] adalah baris pertama, m[, 2] adalah kolom kedua. Secara default keduanya kembali sebagai vector biasa. Tambahkan drop = FALSE, seperti pada m[1, , drop = FALSE], untuk mempertahankan hasilnya sebagai matrix satu baris atau satu kolom, yang penting saat kode berikutnya mengharapkan dua dimensi.

Ilustrasi bahasa pemrograman di Coddy

Belajar coding dengan Coddy

Mulai