Build Your Own Tools: Pemrograman Fungsi & OOP di R
Author
Muhammad Yusran
Published
September 23, 2025
Saatnya Membuat Fungsi dan Objek Sendiri!
Dalam dunia analisis data, kita sering mengandalkan fungsi-fungsi bawaan R untuk memproses, menganalisis, atau memvisualisasikan data. Namun, bagaimana jika kamu ingin membuat fungsi sendiri yang disesuaikan dengan kebutuhan unik? Atau bahkan, bagaimana jika kamu ingin mendefinisikan struktur objek baru yang bisa menyimpan data dan berperilaku seperti objek di dunia nyata?
Praktikum ini akan membawamu melampaui penggunaan fungsi standar menuju dunia pemrograman fungsional dan berorientasi objek (OOP) di R. Kamu akan belajar bagaimana:
Menulis fungsi custom sesuai kebutuhanmu sendiri,
Mengelola class dan objek S3 dengan fleksibilitas tinggi,
Mendesain class S4 dengan struktur formal dan validasi ketat,
Mengembangkan method khusus,
Mewariskan class dan membangun hierarki objek.
Di luar kemampuan eksplorasi data, kemampuan membuat fungsi dan objek sendiri akan membantumu membangun pustaka kode reusable, scalable, dan elegan. Baik untuk penelitian, proyek besar, atau bahkan mengembangkan package R sendiri
Fungsi
Fungsi adalah kumpulan pernyataan yang diatur secara bersama untuk melakukan suatu pekerjaan yang spesifik, seperti perhitungan matematis, pembacaan data, analisis statistik, visualisasi, dan berbagai operasi lainnya.
Dalam bahasa pemrograman R, terdapat dua macam fungsi utama:
Fungsi built-in (fungsi bawaan) – yaitu fungsi yang sudah disediakan dan terintegrasi langsung dalam R.
Fungsi user-defined (fungsi buatan) – yaitu fungsi yang dapat didefinisikan atau dibuat sendiri oleh pemrogram untuk kebutuhan tertentu.
Penggunaan fungsi sangat penting karena memungkinkan kita untuk:
Menulis kode yang modular dan efisien,
Menghindari pengulangan perintah yang sama,
Meningkatkan keterbacaan dan fleksibilitas program,
Membuat alur analisis menjadi lebih terstruktur dan mudah dipelihara.
Built-in Function
Fungsi built-in adalah fungsi yang telah disediakan oleh R dan siap digunakan tanpa perlu didefinisikan ulang. Fungsi-fungsi ini mencakup berbagai keperluan umum mulai dari perhitungan statistik, transformasi data, hingga visualisasi.
Berikut beberapa fungsi built-in yang umum digunakan dalam analisis data menggunakan R:
Fungsi
Deskripsi
Contoh Penggunaan
mean()
Menghitung nilai rata-rata
mean(c(1, 2, 3, 4, 5))
sd()
Menghitung simpangan baku
sd(c(10, 12, 15))
sum()
Menjumlahkan seluruh elemen dalam vektor
sum(1:10)
length()
Menghitung jumlah elemen
length(c(4, 5, 6))
min()
Nilai terkecil dari vektor
min(c(5, 3, 9))
max()
Nilai terbesar dari vektor
max(c(5, 3, 9))
summary()
Ringkasan statistik deskriptif
summary(mtcars$mpg)
range()
Rentang (min & max) dari data
range(c(7, 2, 9, 4))
plot()
Membuat grafik dasar
plot(1:10)
hist()
Membuat histogram
hist(mtcars$mpg)
Berikut beberapa contoh penggunaan langsung fungsi bawaan R:
# Vektor datadata <-c(10, 12, 15, 14, 11)# Rata-rata dan simpangan bakumean(data)
[1] 12.4
sd(data)
[1] 2.073644
# Jumlah elemen dan total nilailength(data)
[1] 5
sum(data)
[1] 62
# Nilai minimum dan maksimummin(data)
[1] 10
max(data)
[1] 15
# Ringkasan statistiksummary(data)
Min. 1st Qu. Median Mean 3rd Qu. Max.
10.0 11.0 12.0 12.4 14.0 15.0
range(data)
[1] 10 15
# Visualisasi sederhanax <-1:10y <- x^2# Plot garisplot(x, y, type ="l", col ="blue", main ="Plot Kuadrat")
# Histogram distribusi mpg di dataset mtcarshist(mtcars$mpg, col ="lightblue", main ="Histogram MPG Mobil")
Catatan Penting
Hampir semua fungsi built-in di R memiliki dokumentasi lengkap.
Gunakan ?nama_fungsi atau help(nama_fungsi) di console untuk membaca petunjuk penggunaannya.
Contoh:
?meanhelp(summary)
Salah satu fasilitas yang menarik dalam penggunaan fungsi built-in di R adalah bahwa argumen fungsi dapat berupa fungsi lain. Dengan kata lain, kamu bisa menjalankan fungsi di dalam fungsi, sehingga sangat fleksibel dan powerful. Contohnya banyak digunakan dalam fungsi apply(), lapply(), dan sejenisnya.
Konsep ini disebut juga sebagai higher-order function — yaitu fungsi yang dapat menerima fungsi lain sebagai input, atau menghasilkan fungsi sebagai output.
User-Defined Function
Tidak semua fungsi yang dibutuhkan ada di dalam R. Jika fungsi bawaan belum dapat memenuhi kebutuhan analisis yang spesifik, maka kita bisa membuat fungsi buatan sendiri, yang disebut juga user-defined function.
Fungsi ini memungkinkan kita untuk: - Menyusun kode agar lebih modular dan reusable, - Menyimpan blok instruksi yang bisa dipanggil berulang kali, - Menyesuaikan proses dengan kebutuhan analisis yang lebih kompleks.
Untuk membuat fungsi sendiri di R, terdapat beberapa komponen penting yang perlu diperhatikan, yaitu:
Nama fungsi – penamaan fungsi sesuai kebutuhan (hindari nama yang sudah digunakan di R),
Argumen fungsi – input yang diterima fungsi untuk diproses,
Tubuh fungsi (body) – berisi instruksi atau blok kode yang dijalankan,
Nilai kembali (return value) – hasil akhir yang dikembalikan oleh fungsi.
Bentuk umum ketika membuat fungsi sendiri adalah
nama_fungsi <-function(arg1, arg2, ...) {# baris kode# ... hasil}
Atau bisa juga secara eksplisit menggunakan return() untuk mengembalikan hasil:
nama_fungsi <-function(arg1, arg2, ...) {# baris kode# ...return(hasil)}
Berikut beberapa contoh fungsi buatan (user-defined function) untuk memahami variasi cara mendefinisikan fungsi di R:
# Fungsi 1: Mengembalikan satu output numerik (z)transform_power <-function(n, power) { x <-runif(n) y <-runif(n) z <- (x + y)^powerreturn(z)}# Contoh penggunaantransform_power(10, 2)
# Fungsi 2: Mengembalikan list berisi x, y, dan hasil zgenerate_components <-function(n, power) { x <-runif(n) y <-runif(n) z <- (x + y)^powerreturn(list(x = x, y = y, result = z))}generate_components(10, 2)
# Fungsi 3: Diberi nilai default untuk argumen n dan powergenerate_default <-function(n =1, power =2) { x <-runif(n) y <-runif(n) z <- (x + y)^powerreturn(z)}generate_default() # menggunakan default
# Fungsi 4: Tidak memiliki argumen, gunakan variabel global (kurang disarankan)generate_global <-function() { x <-runif(n) y <-runif(n) z <- (x + y)^powerreturn(z)}# Harus tetapkan n dan power terlebih dahulun <-5; power <-3generate_global()
# Fungsi 5: Gunakan ... untuk fleksibilitas parameter runifgenerate_flexible <-function(n, power, ...) { x <-runif(n, ...) y <-runif(n, ...) z <- (x + y)^powerreturn(z)}generate_flexible(10, 2, min =2, max =5)
Fungsi generate_flexible() memungkinkan pengguna mengatur argumen tambahan seperti batas bawah (min) dan atas (max) langsung melalui parameter ..., yang sangat berguna saat bekerja dengan fungsi internal seperti runif(), rnorm(), atau paste().
Anonymous Function
Selain membuat fungsi dengan nama tertentu, kita juga bisa membuat fungsi langsung di tempat tanpa nama. Fungsi seperti ini disebut anonymous function. Biasanya, fungsi ini kita gunakan saat ingin melakukan operasi cepat—tanpa perlu menyimpan fungsi tersebut untuk digunakan ulang.
Fungsi jenis ini sering muncul saat kita memakai fungsi lain seperti apply(), lapply(), atau sapply(), dan kita hanya butuh proses satu langkah sederhana.
Bentuk umumnya:
function(argumen) ekspresi
Berikut beberapa contoh anonymous function:
# Mengkuadratkan setiap elemen vektor menggunakan sapply() + anonymous functionbilangan <-1:5sapply(bilangan, function(x) x^2)
[1] 1 4 9 16 25
# Menambahkan 100 ke setiap elemen matriks kolom demi kolommat <-matrix(1:9, nrow =3)apply(mat, 2, function(x) x +100)
# Fungsi lebih dari satu baris dalam anonymous functionsapply(1:5, function(x) { y <- x^2 y +10})
[1] 11 14 19 26 35
Kita bisa memakai fungsi tanpa nama ini ketika:
Kita hanya butuh fungsi sekali pakai,
Ingin menulis kode secara ringkas langsung di tempatnya,
Tidak ingin menambah terlalu banyak nama fungsi ke environment kita.
Namun, kalau kode kita mulai rumit atau fungsinya akan dipakai berulang kali, sebaiknya kita definisikan dulu sebagai fungsi biasa (user-defined) agar lebih rapi dan mudah dirawat.
Error Handling and Debugging
Dalam pemrograman, kita tidak bisa selalu menghindari kesalahan. Namun, kita bisa mengantisipasi dan menangani error agar program tetap berjalan dengan baik dan mudah dilacak. Pada bagian ini, kita akan membahas:
Bagaimana menangani error dengan elegan,
Cara memberikan peringatan atau informasi kepada pengguna,
Strategi menelusuri dan memperbaiki error (debugging).
Tujuannya adalah agar fungsi yang kita buat lebih tangguh, tidak mudah crash, dan mudah diperbaiki saat ada masalah.
Jika proses eksekusi program berjalan terlalu lama atau menyebabkan kesalahan (error), kita bisa menghentikannya secara manual. Di RStudio, tersedia tombol merah Stop (🟥) di pojok kanan atas konsol yang dapat kita klik untuk menginterupsi proses yang sedang berjalan.
Selain itu, kita juga bisa menggunakan shortcut keyboard seperti ESC (di Windows/Mac) atau CTRL + C (di terminal atau R biasa) untuk menghentikan eksekusi secara paksa. Ini sangat penting saat fungsi masuk ke infinite loop atau error yang membuat R “hang”.
Menangani Error: stop(), warning(), dan message()
R menyediakan tiga fungsi utama untuk komunikasi saat error atau kondisi khusus:
Fungsi
Tujuan
stop()
Menghentikan eksekusi program dan menampilkan pesan error
warning()
Menampilkan peringatan tapi program tetap dilanjutkan
message()
Memberikan informasi tanpa menghentikan atau mengganggu eksekusi
Terjadi error: non-numeric argument to mathematical function
[1] NA
Debugging: Menelusuri dan Memperbaiki Error
Saat fungsi tidak berjalan sebagaimana mestinya, kita bisa:
browser(): masuk ke mode interaktif dalam fungsi,
traceback(): melihat jejak error terakhir,
debug() dan undebug(): menelusuri eksekusi fungsi baris per baris,
print() atau cat(): mencetak nilai.
debug(cek_positif)cek_positif(-2) # akan masuk mode debuggingundebug(cek_positif)
Error handling dan debugging adalah keterampilan penting yang akan menghemat waktu dan stres saat proyek menjadi lebih kompleks. Jadi, jangan takut error – kita latih kemampuan untuk “berdialog” dengan error tersebut.
Object-Oriented Programming
Pemrograman Berorientasi Objek (Object-Oriented Programming, OOP) adalah paradigma pemrograman yang berfokus pada objek — entitas yang memiliki data (properti) dan fungsi (method) — serta bagaimana objek tersebut berinteraksi satu sama lain.
Dalam dunia analisis data dan pengembangan perangkat lunak, OOP membantu kita untuk:
Mengorganisasi kode menjadi struktur yang modular dan reusable,
Menyusun program yang lebih natural dan intuitif,
Meningkatkan pemeliharaan (maintainability) dan skalabilitas kode.
Prinsip-prinsip dari OOP adalah:
Konsep
Penjelasan Singkat
Abstraksi
Menyembunyikan detail implementasi dan hanya menampilkan fitur penting.
Enkapsulasi
Mengemas data dan method dalam satu unit (objek), membatasi akses langsung.
Pewarisan (Inheritance)
Objek dapat mewarisi properti dan method dari objek lain.
Polimorfisme
Fungsi yang sama bisa memiliki perilaku berbeda tergantung class objek yang digunakan.
Class dan Object
Dalam OOP, class adalah cetak biru (blueprint) atau template untuk membuat objek. Class mendefinisikan atribut (disebut properti) dan fungsi (disebut method) yang dimiliki oleh objek.
Sedangkan object adalah instansiasi dari class — yaitu wujud konkret yang dibuat berdasarkan class. Satu class bisa digunakan untuk membuat banyak object yang berbeda.
Contoh analogi:
class Mobil: memiliki properti warna, kecepatan; dan method jalan(), berhenti().
object mobilA: adalah mobil merah yang bisa berjalan dan berhenti.
object mobilB: adalah mobil biru dengan kecepatan lebih tinggi.
OOP di Bahasa R
Walaupun R adalah bahasa pemrograman yang secara default bersifat fungsional, R mendukung paradigma berorientasi objek. Hal ini diwujudkan melalui dua sistem utama class:
Class System S3: sistem class yang sederhana dan fleksibel, banyak digunakan dalam paket-paket dasar R.
Class System S4: sistem class yang lebih ketat dan formal, cocok untuk pengembangan perangkat lunak dan package skala besar.
Keduanya memungkinkan pengguna untuk:
Mendefinisikan struktur objek (class definition),
Membuat objek baru (instantiation),
Mengembangkan fungsi khusus (method) sesuai dengan class-nya,
Mewariskan properti dan method ke class turunan (inheritance).
Berikut perbandingan antara kedua sistem class
Fitur
S3
S4 # S3 (tanpa deklarasi class formal)
Pendefinisian Class
Tidak formal (langsung lewat class<-)
Formal (dengan setClass())
Validasi Struktur
Tidak ada
Ada validasi tipe dan panjang data
Pewarisan
Bisa
Bisa (lebih eksplisit dan kuat)
Method
function.classname()
setMethod() untuk generic
Cocok untuk
Proyek kecil-menengah
Proyek besar / pembuatan package
Contoh sederhananya seperti berikut:
# S3 (tanpa deklarasi class formal)obj <-list(x =1:5, y =6:10)class(obj) <-"coords"
# S4 (dengan deklarasi formal)setClass("coords", representation(x ="numeric", y ="numeric"))obj <-new("coords", x =1:5, y =6:10)
obj
An object of class "coords"
Slot "x":
[1] 1 2 3 4 5
Slot "y":
[1] 6 7 8 9 10
class(obj)
[1] "coords"
attr(,"package")
[1] ".GlobalEnv"
Kapan Menggunakan S3 dan S4?
Gunakan S3 jika proyek kita cepat, eksploratif, atau berskala kecil.
Gunakan S4 jika kita mengembangkan package atau sistem dengan banyak validasi formal.
Class System S3 di R
Sistem class S3 adalah sistem pemrograman berorientasi objek yang paling sederhana dan fleksibel di R. Tidak ada deklarasi class formal — cukup dengan menetapkan atribut class pada objek menggunakan class(obj) <- "nama_class".
Class S3 memungkinkan kita untuk:
Membuat class sendiri untuk objek buatan,
Mengembangkan fungsi yang berlaku khusus untuk class tertentu (method),
Melakukan pewarisan sederhana antar class.
Constructor: Membuat Objek Class Baru
S3 tidak memiliki mekanisme formal untuk constructor seperti bahasa lain, tetapi kita bisa membuat fungsi constructor agar input divalidasi dan objek dibuat dengan struktur konsisten.
Contoh: Membuat class coords untuk menyimpan titik koordinat (x, y).
coords <-function(x, y) {if (!is.numeric(x) ||!is.numeric(y)) stop("Koordinat harus numerik")if (!all(is.finite(x)) ||!all(is.finite(y))) stop("Koordinat harus valid (bukan NA, NaN, Inf)")if (length(x) !=length(y)) stop("Panjang x dan y harus sama") pts <-list(x = x, y = y)class(pts) <-"coords"return(pts)}
Walaupun objek coords adalah list, akses langsung seperti obj$x tidak disarankan. Gunakan fungsi accessor agar lebih terkontrol dan mendukung perubahan struktur di masa depan.
Untuk menggunakan fungsi accessornya, cukup memanggil seperti fungsi biasanya
xcoords(pts)
[1] 1.2 3.4 5.6
ycoords(pts)
[1] 7.8 9.0 2.3
Method Generik dan Khusus
Fungsi seperti print(), length(), dan plot() adalah fungsi generik. Kita bisa membuat method khusus untuk class coords dengan menulis fungsi print.coords(), length.coords(), dll.
Semisal kita ingin membuat fungsi generik baru bernama bbox untuk menghitung bounding box (rentang nilai x dan y), kita bisa mendefinisikannya sebagai berikut:
Output berupa matriks 2x2 dengan kolom x dan y, serta baris min dan max.
Fungsi plot() adalah fungsi generik yang bisa dibuat versi khususnya untuk class coords. Kita bisa menambahkan opsi bbox = TRUE untuk menampilkan bounding box di sekitar titik-titik.
plot(pts) # Plot titikplot(pts, bbox =TRUE) # Plot dengan bounding box merah
Pewarisan Class: Membuat Subclass vcoords
Dalam OOP, class bisa mewarisi properti dan method dari class lain. Di S3, pewarisan dilakukan dengan menambahkan class baru ke dalam vektor class objek.
class(obj) <-c("anak", "induk")
Warning in class(obj) <- c("anak", "induk"): Setting class(x) to multiple
strings ("anak", "induk", ...); result will no longer be an S4 object
Misalnya, kita ingin membuat class vcoords — turunan dari coords — yang memiliki nilai tambahan v (misalnya suhu atau intensitas) untuk setiap titik:
vcoords <-function(x, y, v) {if (!is.numeric(x) ||!is.numeric(y) ||!is.numeric(v)) stop("Semua komponen harus numerik")if (length(x) !=length(y) ||length(x) !=length(v)) stop("Panjang x, y, v harus sama") obj <-list(x = x, y = y, v = v)class(obj) <-c("vcoords", "coords")return(obj)}
Fungsi accessor tambahan:
nilai <-function(obj) obj$v
Overriding Method
Objek vcoords otomatis akan menggunakan semua method coords (seperti xcoords(), ycoords(), bbox(), plot()) kecuali jika ada method vcoords yang secara eksplisit dituliskan untuk menimpanya (overriding).
Agar method print() untuk vcoords juga menampilkan nilai v, kita bisa menuliskan ulang fungsi print.vcoords():
Secara default, operator subset [ ] pada objek class S3 akan memanggil method [.list, karena objek coords atau vcoords berbentuk list. Namun, agar objek vcoords dapat di-subset dengan hasil tetap berupa objek vcoords (bukan list biasa), kita perlu mendefinisikan method [.vcoords.
Jika obj[i] dikembalikan dalam bentuk list biasa, maka fungsi generik seperti plot() atau bbox() tidak dapat digunakan.
Dengan method ini, kita menjaga konsistensi struktur objek saat subset dilakukan.
Pemeriksaan Class Objek
Untuk memeriksa apakah suatu objek merupakan class tertentu (misalnya untuk keperluan debugging atau validasi internal), kita bisa menggunakan fungsi inherits().
Membuat method generik baru dan ingin memastikan class input cocok.
Melakukan pengujian kondisi sebelum eksekusi method tertentu.
Membuat fungsi stop() atau warning() agar hanya berlaku untuk class tertentu.
Contoh validasi dalam fungsi:
print_koordinat <-function(obj) {if (!inherits(obj, "coords")) stop("Objek harus class 'coords'")cat("Jumlah titik koordinat:", length(obj$x), "\n")}
Dengan inherits(), kita mencegah pengguna memasukkan objek sembarangan yang bisa menyebabkan error saat dieksekusi.
Contoh: Class S3 player untuk Data Pemain Sepak Bola
Bayangkan kita ingin menyimpan informasi seorang pemain sepak bola yang terdiri atas: nama, tim, posisi, dan jumlah gol yang telah dicetak sepanjang kariernya.
Konstruktor dan Method
player <-function(nama, tim, posisi, gol, main) {if (!is.character(nama) ||!is.character(tim) ||!is.character(posisi)) {stop("Nama, tim, dan posisi harus karakter") }if (!is.numeric(gol) ||!is.numeric(main) ||length(gol) !=1||length(main) !=1) {stop("Gol dan pertandingan harus berupa angka tunggal") } obj <-list(nama = nama, tim = tim, posisi = posisi, gol = gol, main = main)class(obj) <-"player"return(obj)}
Perbandingan Gol:
Kylian Mbappé : 51 gol
Lamine Yamal : 27 gol
Kylian Mbappé unggul 24 gol dari Lamine Yamal
Tambahkan compareGoals.default()
compareGoals.default <-function(p1, p2) {stop("compareGoals hanya tersedia untuk objek class 'player'")}
Dengan begini, compareGoals() kini adalah fungsi S3 yang formal dan fleksibel.
Update Method compareGoals.player() dengan Argumen ratio = TRUE
Semisal, kita ingin memperbarui method compareGoals() agar bisa membandingkan rasio gol per pertandingan, bukan hanya jumlah gol total. Kita cukup menambahkan argumen ratio = TRUE.
compareGoals <-function(p1, p2, ...) {UseMethod("compareGoals")}compareGoals.player <-function(p1, p2, ratio =FALSE) {if (!inherits(p2, "player")) {stop("Argumen kedua harus class 'player'") }if (!is.logical(ratio) ||length(ratio) !=1) {stop("Parameter 'ratio' harus TRUE atau FALSE") }if (ratio) { r1 <-goalRatio(p1) r2 <-goalRatio(p2)cat("Perbandingan Rasio Gol per Pertandingan:\n")cat(p1$nama, ":", round(r1, 3), "gol/match\n")cat(p2$nama, ":", round(r2, 3), "gol/match\n") selisih <- r1 - r2if (selisih >0) {cat(p1$nama, "unggul", round(selisih, 3), "gol/match dari", p2$nama, "\n") } elseif (selisih <0) {cat(p2$nama, "unggul", round(abs(selisih), 3), "gol/match dari", p1$nama, "\n") } else {cat("Keduanya memiliki rasio gol per pertandingan yang sama\n") } } else {cat("Perbandingan Jumlah Gol:\n")cat(p1$nama, ":", p1$gol, "gol\n")cat(p2$nama, ":", p2$gol, "gol\n") selisih <- p1$gol - p2$golif (selisih >0) {cat(p1$nama, "unggul", selisih, "gol dari", p2$nama, "\n") } elseif (selisih <0) {cat(p2$nama, "unggul", abs(selisih), "gol dari", p1$nama, "\n") } else {cat("Keduanya memiliki jumlah gol yang sama\n") } }}
compareGoals(mbappe, yamal) # default: perbandingan jumlah gol
Perbandingan Jumlah Gol:
Kylian Mbappé : 51 gol
Lamine Yamal : 27 gol
Kylian Mbappé unggul 24 gol dari Lamine Yamal
compareGoals(mbappe, yamal, ratio =TRUE) # perbandingan rasio gol per match
Perbandingan Rasio Gol per Pertandingan:
Kylian Mbappé : 0.785 gol/match
Lamine Yamal : 0.248 gol/match
Kylian Mbappé unggul 0.537 gol/match dari Lamine Yamal
Catatan Kritis tentang S3
Sistem class S3 di R sangat populer karena kemudahannya dan menawarkan fleksibilitas tinggi, namun dengan beberapa risiko jika tidak digunakan secara hati-hati. Tabel berikut merangkum kelebihan, kekurangan, serta kesalahan umum penggunaannya.
Aspek
Keterangan
Kelebihan
Sederhana
Tidak perlu deklarasi class formal — cukup set class(obj) <- "nama"
Ringan
Cocok untuk eksplorasi dan prototipe cepat
Kompatibel
Didukung luas oleh fungsi bawaan R seperti print(), summary(), plot()
Kekurangan
Tidak validasi
Tidak ada pengecekan struktur internal objek
Sulit dilacak
Sulit dipelihara dalam proyek besar tanpa dokumentasi yang baik
Rentan error
Mudah salah assign class ke objek yang tidak sesuai
Contoh Kesalahan Umum
Kasus
Contoh Kode
Penjelasan
Menetapkan class yang salah
class(x) <- "lm"
x bukan model regresi, tapi dipaksa jadi class "lm"
Fungsi tidak sesuai class
summary(x) setelah itu
Bisa menghasilkan error atau output tidak relevan
Tidak pakai constructor
Buat list lalu langsung set class
Bisa membuat objek tidak lengkap/valid
Class System S4 di R
Class System S4 adalah sistem OOP (Object-Oriented Programming) di R yang lebih formal dan ketat dibanding S3. Sistem ini dirancang untuk mengatasi kekurangan S3 seperti tidak adanya validasi struktur, dan lebih cocok untuk proyek besar atau pengembangan package.
Beberapa karakteristik utama S4:
Definisi class dilakukan dengan setClass(),
Objek dibuat menggunakan new() atau constructor custom,
Slot digunakan untuk mendefinisikan struktur data secara eksplisit,
Method ditetapkan dengan setMethod() dan generic function didefinisikan lewat setGeneric(),
Validasi tipe data otomatis dilakukan.
Pendefinisian Class dengan setClass()
Contoh: mendefinisikan class coords dengan dua slot numerik x dan y:
coords <-function(x, y){if (length(x) !=length(y)) stop("Panjang x dan y harus sama")if (!is.numeric(x) ||!is.numeric(y)) stop("x dan y harus numerik")new("coords", x =as.vector(x), y =as.vector(y))}pts <-coords(c(1.2, 3.4), c(4.5, 6.7))
pts
An object of class "coords"
Slot "x":
[1] 1.2 3.4
Slot "y":
[1] 4.5 6.7
Kita ingin menambahkan slot nilai ke class coords. Dengan S4, cukup gunakan contains.
setClass("vcoords",representation(nilai ="numeric"),contains ="coords")vcoords <-function(x, y, nilai) {if (!is.numeric(x) ||!is.numeric(y) ||!is.numeric(nilai)) stop("Semua slot harus numerik")if (!(length(x) ==length(y) &&length(y) ==length(nilai))) stop("Panjang harus sama")new("vcoords", x =as.vector(x), y =as.vector(y), nilai =as.vector(nilai))}
Contoh: Class S4 player untuk Data Pemain Sepak Bola
Salah satu keunggulan sistem S4 adalah kemampuannya untuk mendefinisikan perilaku khusus saat objek digunakan dalam operasi aritmetika. Berikut ini kita definisikan class player untuk merepresentasikan data seorang pemain sepak bola, lalu menambahkan method aritmetika +.
player <-function(nama, tim, posisi, gol, main) {if (!is.character(nama) ||!is.character(tim) ||!is.character(posisi)) {stop("Nama, tim, dan posisi harus karakter") }if (!is.numeric(gol) ||!is.numeric(main) ||length(gol) !=1||length(main) !=1) {stop("Gol dan pertandingan harus berupa angka tunggal") }new("player", nama = nama, tim = tim, posisi = posisi, gol = gol, main = main)}