{count, plural, one {Kursus} other {Kursus}}
Catatan tentang Keluarga Apply di R
Keluarga Apply di R adalah sekumpulan fungsi di R yang memungkinkan pengguna menerapkan sebuah fungsi pada elemen vektor, list, atau matriks. Namun, ini dianggap sebagai fungsionalitas lama dan sebaiknya tidak digunakan untuk kode baru. Sebagai gantinya, direkomendasikan untuk menggunakan paket purrr untuk semua proses looping di R. Paket purrr menyediakan sintaks yang konsisten untuk bekerja dengan fungsi yang menerima banyak masukan dan keluaran, sehingga memudahkan penulisan dan pembacaan kode. Selain itu, purrr menyediakan serangkaian fungsi yang dioptimalkan untuk lingkungan komputasi modern, sehingga lebih cepat dan efisien dibanding Keluarga Apply. Secara keseluruhan, meskipun Keluarga Apply di R mungkin masih berfungsi untuk beberapa aplikasi, disarankan untuk menggunakan paket purrr untuk semua proyek R yang baru.
Fungsi Apply sebagai Alternatif Loop
Post ini akan menunjukkan cara menggunakan fungsi R apply(), variannya seperti mapply() dan beberapa kerabat apply(), yang diterapkan pada berbagai struktur data. Tentu tidak semua varian dapat dibahas, tetapi jika memungkinkan, Anda akan diperkenalkan pada penggunaan fungsi-fungsi ini secara bersama, melalui beberapa contoh yang sedikit lebih berat.
Selain itu, Anda mungkin akan merasa berguna untuk melihat kursus pengantar R ini untuk lebih memahami list, vektor, array, dan dataframe, meskipun Anda tidak harus menuntaskan tutorial tersebut untuk mengikuti post ini!
Keluarga apply()
Keluarga apply() termasuk dalam paket dasar R dan berisi fungsi-fungsi untuk memanipulasi potongan data dari matriks, array, list, dan dataframe secara berulang. Fungsi-fungsi ini memungkinkan menelusuri data dengan berbagai cara dan menghindari penggunaan eksplisit konstruksi loop. Fungsi-fungsi tersebut bekerja pada input berupa list, matriks, atau array dan menerapkan fungsi tertentu dengan satu atau beberapa argumen opsional.
Fungsi yang dipanggil bisa berupa:
- Fungsi agregasi, seperti misalnya mean atau sum (yang mengembalikan angka atau skalar);
- Fungsi transformasi atau subsetting lainnya; dan
- Fungsi tervektorisasi lainnya, yang menghasilkan struktur yang lebih kompleks seperti list, vektor, matriks, dan array.
Fungsi-fungsi apply() menjadi dasar kombinasi yang lebih kompleks dan membantu melakukan operasi hanya dengan sedikit baris kode. Secara khusus, keluarga ini terdiri dari fungsi apply(), lapply(), sapply(), vapply(), mapply(), rapply(), dan tapply().
Lalu bagaimana dan kapan sebaiknya kita menggunakan ini?
Ini bergantung pada struktur data yang ingin Anda operasikan dan format keluaran yang Anda perlukan.
Cara Menggunakan apply() di R
Mulailah dengan kepala keluarga, apply(), yang beroperasi pada array. Demi kesederhanaan, tutorial ini membatasi diri pada array 2D, yang juga dikenal sebagai matriks.
Manual dasar R menjelaskan bahwa fungsinya dipanggil sebagai berikut: apply(X, MARGIN, FUN, ...)
di mana:
Xadalah array atau matriks jika dimensi array adalah 2;MARGINadalah variabel yang menentukan bagaimana fungsi diterapkan: ketikaMARGIN=1, fungsi diterapkan pada baris, sedangkan denganMARGIN=2, fungsi bekerja pada kolom. Perhatikan bahwa ketika Anda menggunakan konstruksiMARGIN=c(1,2), fungsi diterapkan pada baris dan kolom; danFUN, yaitu fungsi yang ingin Anda terapkan ke data. Dapat berupa fungsi R apa pun, termasuk User Defined Function (UDF).
Pemula mungkin kesulitan membayangkan apa yang terjadi, jadi gambar dan sedikit kode akan membantu Anda memahaminya.
Misalkan kita membuat matriks 5 x 6 dan bayangkan Anda ingin menjumlahkan nilai setiap kolom.
Anda dapat menulis seperti ini:
# Construct a 5 x 6 matrix
my_matrix <- matrix(1:30, nrow = 5, ncol = 6)
# Calculate the sum of each column
col_sums <- apply(my_matrix, 2, sum)
# Print the result
print(col_sums)
Fungsi matrix() membuat matriks 5 x 6 dengan nilai dari 1 hingga 30. Kemudian kita menggunakan fungsi apply() untuk menerapkan fungsi sum() ke setiap kolom matriks (2 menentukan bahwa kita ingin menerapkan fungsi pada kolom). Vektor hasil penjumlahan kolom disimpan dalam variabel col_sums dan dicetak ke konsol.
Ingat bahwa di R, sebuah matriks dapat dipandang sebagai kumpulan vektor baris ketika Anda menelusuri matriks dari atas ke bawah (sepanjang garis vertikal 1, yang menentukan dimensi atau margin 1), atau sebagai daftar vektor kolom, membentang dari kiri ke kanan sepanjang dimensi atau margin 2.
Artinya instruksi yang baru saja Anda masukkan, seperti pada gambar 1, diterjemahkan menjadi: “terapkan fungsi ‘sum’ pada matriks X sepanjang margin 2 (per kolom), menjumlahkan nilai setiap kolom.”
Perhatikan bahwa, untuk menghindari kerumitan gambar, hanya satu kolom yang disorot.
Anda akan mendapatkan vektor baris yang berisi jumlah nilai setiap kolom.
Keluaran dari kode di atas, yaitu vektor baris, juga akan diberikan jika Anda menjumlahkan sepanjang baris matriks. Begitulah cara R menampilkan hasil.
Catatan untuk berikutnya: dalam banyak kasus, R dapat mengembalikan nilai meskipun nilai tersebut tidak ditentukan, atau lebih tepatnya nilai kembalian fungsi tidak ditetapkan ke variabel. R cukup mengembalikan objek terakhir yang dievaluasi. Namun dalam praktiknya, ketika Anda ingin memeriksa nilai kembalian dan ketika Anda perlu melakukan operasi lebih lanjut terhadap nilai-nilai tersebut, sebaiknya hasil suatu fungsi secara eksplisit ditetapkan ke variabel.
Fungsi lapply()
Anda ingin menerapkan suatu fungsi pada setiap elemen list dan memperoleh list sebagai hasil. Ketika Anda mengeksekusi ?lapply, Anda melihat bahwa sintaksnya mirip dengan fungsi apply().
Perbedaannya adalah bahwa:
- Dapat digunakan untuk objek lain seperti dataframe, list, atau vektor; dan
- Keluaran yang dikembalikan adalah list (yang menjelaskan huruf “l” dalam nama fungsi), yang memiliki jumlah elemen yang sama dengan objek yang diberikan.
Untuk melihat cara kerjanya, buat beberapa matriks dan ekstrak sebuah kolom tertentu dari masing-masingnya.
Ini adalah operasi yang cukup umum dilakukan pada data nyata saat melakukan perbandingan atau agregasi dari berbagai dataframe.
Contoh sederhana kita, seperti pada gambar 2, dapat ditulis sebagai:

Operasi tersebut ditunjukkan pada bagian kiri gambar 2.
Sekali lagi, Anda mulai dengan menentukan objek yang diminati, yaitu list Mylist. Anda menggunakan operator seleksi standar R [ lalu mengosongkan parameter pertama (yang berarti “apa saja”, itulah mengapa Anda melihat dua koma).
Selanjutnya, Anda menentukan parameter kedua, yaitu 2: margin kita adalah ‘kolom’. Jadi Anda mengekstrak kolom kedua dari semua matriks dalam list.
Beberapa catatan untuk kode di atas:
- Notasi
[adalah operator seleksi. Ingat, misalnya, untuk mengekstrak semua elemen baris ketiga dari B memerlukan:B[3,]; - Notasi
[[ ]]menyatakan bahwa kita berurusan dengan list: [[2]] berarti elemen kedua dari list. Ini juga terlihat pada keluaran yang diberikan oleh R; - Keluaran adalah list dengan jumlah elemen sebanyak elemen dalam input; dan
- Perhatikan bahwa Anda juga bisa mengekstrak satu elemen untuk setiap matriks, seperti ini:
lapply(MyList,"[", 1, 2)
Pada sisi kanan gambar 2, Anda dapat melihat ekstraksi alternatif: kali ini Anda mengosongkan parameter pertama, dan mendapatkan baris pertama dari masing-masing matriks.
Coba sendiri! Pilih kolom kedua dari setiap matriks dalam list:
Fungsi sapply()
Fungsi sapply() bekerja seperti lapply(), tetapi berusaha menyederhanakan keluaran ke struktur data yang paling elementer. Dan memang, sapply() adalah fungsi ‘pembungkus’ untuk lapply().
Contoh dapat membantu memahaminya: misalkan Anda ingin mengulangi operasi ekstraksi satu elemen seperti pada contoh terakhir, tetapi sekarang ambil elemen pertama dari baris kedua (indeks 2 dan 1) untuk setiap matriks.
Menerapkan fungsi lapply() akan memberi kita list kecuali Anda memberikan simplify=FALSE sebagai parameter ke sapply(). Maka list akan dikembalikan. Lihat cara kerjanya pada potongan kode di bawah ini:
Sebaliknya, fungsi seperti unlist() dapat memberi tahu lappy() untuk memberikan vektor!
Bagaimanapun, untuk menghindari kebingungan, sebaiknya gunakan fungsi-fungsi ini dalam ‘format aslinya’ dan hindari konversi kecuali benar-benar diperlukan.
Fungsi rep()
Sesuatu yang sering digunakan bersama fungsi apply() adalah rep(). Ketika Anda menerapkannya pada vektor atau faktor x, fungsi ini mereplikasi nilainya sebanyak jumlah yang ditentukan.
Mari gunakan salah satu vektor yang Anda hasilkan di atas dengan lapply() ke dalam MyList.
Kali ini, Anda hanya memilih elemen baris pertama dan kolom pertama dari setiap elemen dalam list MyList (dan Anda menggunakan sapply() untuk mendapatkan vektor):
Anda melihat bahwa kode di atas mereplikasi nilai Z beberapa kali sebagaimana ditetapkan oleh c(3,1,2): tiga kali yang pertama, satu kali yang kedua, dan dua kali yang ketiga:
Praktis, bukan?
Fungsi mapply()
Fungsi mapply() adalah singkatan dari ‘multivariat’ apply. Tujuannya adalah mampu memvektorisasi argumen ke suatu fungsi yang biasanya tidak menerima vektor sebagai argumen.
Singkatnya, mapply() menerapkan sebuah Fungsi ke Beberapa Argumen List atau beberapa Argumen Vektor.
Mari lihat contoh mapply() di mana Anda membuat matriks 4 x 4 dengan pemanggilan fungsi rep() secara berulang:
Tetapi Anda melihat bahwa ada cara yang lebih efisien untuk menggabungkan hasil fungsi rep() ketimbang dengan c(): saat Anda memanggil mapply(), Anda memvektorisasi aksi fungsi rep().
Fungsi yang Terkait dengan apply()
Fungsi-fungsi yang tersusun serupa sesekali digunakan bersama elemen dari keluarga apply(): tutorial ini hanya akan memberikan gambaran beberapa di antaranya.
Fungsi Sweep()
Fungsi sweep() mungkin yang paling dekat dengan keluarga apply(). Anda menggunakannya ketika ingin mereplikasi berbagai aksi pada elemen MARGIN yang Anda pilih (dibatasi pada kasus matriks di sini).
Skenario khas terjadi pada clustering, di mana Anda mungkin perlu berulang kali menghasilkan data yang dinormalisasi dan dicenter atau “distandardisasi”.
Apa artinya ini?
Asumsikan Anda memiliki sejumlah titik data dalam sekelompok data. Anda terlebih dahulu mencari pusat data (“center of mass”) dan melihat seberapa menyebar data ini terhadap pusat tersebut. Dua besaran dasar akan memberi Anda informasi ini: mean dan standar deviasi.
Misalkan titik data Anda adalah vektor kolom dalam sebuah matriks data Anda dan mari gunakan matriks B yang dibuat di awal post ini, tetapi sekarang Anda menamainya dataPoints.
Pertama, Anda mencari mean per kolom dan penyebaran atau standar deviasi dengan bantuan salah satu fungsi apply(). Lalu Anda menggeser semua titik terhadap pusatnya. Ini berarti mean yang Anda temukan terlebih dahulu akan digunakan untuk menormalkan data terhadap standar deviasinya:
Anda menghasilkan titik-titik yang sudah dicenter hanya dengan satu pemanggilan sweep(). Fungsi ini mengharapkan elemen-elemen berikut:
- array input, yang dalam kasus ini adalah matriks;
- MARGIN,
2untuk menunjukkan kolom; - statistik ringkasan (di sini
mean); dan - fungsi yang akan diterapkan. Anda menggunakan operator aritmetika
“-”untuk pengurangan.
Ini berarti: “ambil elemen-elemen kolom dari dataset MyPoints, dan kurangkan mean, dataPoints_means, dari masing-masingnya”.
Sekarang, Anda memanggil sweep() lagi untuk membagi semua nilai yang baru saja Anda peroleh dengan standar deviasinya masing-masing. Langkah ini disebut “normalisasi”. Lagi-lagi, Anda memilih MARGIN=2, lalu memberikan vektor standar deviasi, dataPoints_sdev sebagai operand. Selanjutnya, Anda meneruskan operator ‘bagi’, “/”.
Yang Anda minta dari R adalah sebagai berikut: “ambil elemen-elemen kolom dari objek baru yang baru saja Anda buat, dataPoints_Trans1, dan bagi nilai-nilai ini (“/”) dengan standar deviasi masing-masing dataPoints_sdev.”
Tentu, Anda bisa memperoleh hasil yang sama dengan lebih cepat dan ringkas (seperti sering terjadi di R!) dan tanpa menggunakan nama berbeda, dengan satu baris kode yang memuat pemanggilan bersarang ke sweep():
Secara statistik, Anda baru saja membuat matriks korelasi, dan data yang distandardisasi menjadi dasar dari beberapa prosedur lanjutan pada data (seperti reduksi dimensi melalui PCA, analisis sinyal, dan lainnya).
Fungsi aggregate()
Fungsi ini terdapat dalam paket stats, dan Anda menggunakannya seperti ini: aggregate(x, by, FUN, ..., simplify = TRUE).
Dengan kata lain, cara kerjanya mirip dengan fungsi apply(): Anda menentukan objeknya, fungsinya, dan menyatakan apakah Anda ingin menyederhanakan hasilnya, seperti pada fungsi sapply(). Perbedaan krusial adalah penggunaan klausa by, yang menetapkan variabel atau field dataframe yang menjadi dasar kita melakukan agregasi.
Bagian berikut akan menunjukkan cara kerjanya.
Contoh aggregate()
Pertimbangkan dataset sederhana bernama Mydf, yang berisi data penjualan suatu produk dan di mana beberapa nilai pada kolom variabel DepPC berulang.
Variabel ini mengklasifikasikan data berdasarkan lokasi geografis, seperti bagian dari kode pos (di sini angkanya sesuai dengan departemen di Île de France, wilayah yang mencakup Paris).
Anda ingin melakukan beberapa statistik pada kolom penjualan. Kolom tersebut adalah DProgr, nomor progresif dalam urutan waktu meningkat, dan penjualan produk (kuantitas Qty), ditambah variabel logis, Delivered, yang bersifat logis, memberi tahu apakah produk telah dikirim (T) atau belum (F).
Pertama, Anda dapat melakukan sejumlah hal sederhana untuk mengenal dataset, selain menampilkan seluruhnya dengan mengetikkan namanya (di sini kita hanya memiliki 120 record, tetapi bayangkan melakukan ini untuk berkas nyata dengan ribuan baris!).
Mari kita eksplorasi datanya:
Catatan bahwa jika Anda ingin melihat jumlah baris dan kolom yang dimiliki dataframe, Anda juga bisa memanggil nrow(Mydf) dan ncol(Mydf).
Banyak pertanyaan lain terhadap data dimungkinkan.
Di sini, Anda tertarik untuk mengetahui di departemen mana produk terjual paling baik, misalnya. Itulah mengapa Anda harus mengelompokkan data berdasarkan departemen, menjumlahkan penjualan, Qty, untuk setiap departemen DepPC dengan bantuan fungsi aggregate():
Jadi, aggregate() memberi tahu R bahwa Anda ingin menjumlahkan semua Qty yang termasuk dalam departemen yang sama.
Perhatikan bahwa R menetapkan jumlah tersebut ke variabel ‘x’ karena Anda tidak menyatakannya secara lain.
Keluaran sudah cukup mudah dibaca, namun untuk jumlah departemen yang lebih besar, ini mungkin kurang mudah dibaca. Dalam kasus seperti ini, Anda dapat menggunakan keluaran grafis: Anda memplot hasil dengan menggunakan salah satu sistem keluaran grafis R bersama fungsi aggregate():
Ini memberikan penjualan untuk setiap departemen.
Anda mungkin menanyakan pertanyaan yang sama, tetapi hanya untuk barang yang dikirim. Untuk melakukan ini, pertama-tama Anda melakukan subset data untuk yang delivered bernilai true (T) menggunakan operator subsetting "[" yang kini sudah familier.
Catatan bahwa di sini Anda menetapkan hasilnya ke variabel baru Y, yang merupakan dataframe baru yang mewarisi nama kolom yang sama dari dataframe induk Mydf. Anda melakukan ini untuk menghindari pengulangan instruksi aggregate di dalam pemanggilan plotting demi keterbacaan:
Jadi Anda dapat mengajukan berbagai pertanyaan pada data secara tervektorisasi seperti dengan aggregate(), dan ini sering dilakukan bersamaan dengan sistem plotting yang nyaman seperti ggplot2, jadi Anda paham maksudnya.
Perhatikan bahwa untuk mendapatkan ini, Anda hanya memerlukan sangat sedikit baris kode.
Vektorisasi sebagai Alternatif terhadap Loop dan Fungsi Apply?
Anda telah melihat beberapa variasi pada tema yang sama, yaitu “bertindak pada sekumpulan data terstruktur secara berulang”. Dalam pengertian ini, fungsi-fungsi ini dapat dilihat tidak hanya sebagai alternatif loop tetapi juga sebagai bentuk tervektorisasi dalam melakukan sesuatu.
“Tervektorisasi” di sini dalam arti longgar, kita tidak akan memasuki perdebatan apakah – dan mana dari – fungsi apply() yang benar-benar tervektorisasi atau tidak (lihat misalnya diskusi di sini).
Dalam praktiknya, untuk memilih fungsi apply() mana yang akan digunakan, Anda perlu mempertimbangkan hal-hal berikut:
- Jenis data dari input: ini adalah objek yang akan Anda operasikan (vektor, matriks, array…, list, data frame, atau mungkin kombinasinya)
- Apa yang ingin Anda lakukan: fungsi
FUNyang ingin Anda teruskan - Subset dari data tersebut: baris, kolom, atau mungkin semua?
- Jenis data apa yang ingin Anda dapatkan dari fungsi? Karena Anda mungkin ingin melakukan operasi lebih lanjut atasnya (dan apakah Anda ingin objek baru, atau ingin langsung mentransformasi objek input?)
Ini adalah pertanyaan yang cukup umum yang dapat Anda ajukan untuk fungsi terkait, yang di antaranya telah kita bahas aggregate(), by(), sweep(), dll.
Tetapi masih banyak lagi! Jangan berhenti mengeksplorasi sekarang! Lihat tutorial DataCamp Arrays in R.
Sebagai tindak lanjut tutorial ini, pertimbangkan untuk mengikuti kursus DataCamp Introduction to R atau Intermediate R.

