Membuat Fungsi Baru dalam R
Fungsi yang masih belum tersedia dalam R dapat kita buat sendiri sesuai dengan kebutuhan. Template nya adalah :
namafungsi <- function (argumen) { isifungsi return(value)}
- Argumen
Karakteristik :
1. Bisa berisi satu atau lebih dan bisa tidak ada argumen
2. Argumen bisa juga diberikan suatu nilai default, misal function (x=10)
3. Didefinisikan berulang atau tidak dengan menggunakan “…”. Contoh : function(x=10,...)
4. Argumen dapat menerima fungsi R lain. misal : apply(x,1,mean)
- Isi Fungsi
Karakteristik :
1. Isi fungsi merupakan satu objek data.
2. Jika membutuhkan beberapa baris, dapat dikelompokkan dengan {} dan diakhiri dengan satu objek data
3. Komentar dituliskan dengan awalan # dan tidak akan dieksekusi
- Output
Karakteristik :
Fungsi harus memiliki output yang dikembalikan
Output merupakan suatu objek
Dapat langsung dituliskan objeknya atau menggunakan return
Jika memiliki mode berbeda, digunakan
object list. Contoh:fungsi1 <- function (x) { … list (hasil1 , hasil2 ) } fungsi2 <- function (x) { … return ( list (hasil1 , hasil2 )) }
Untuk menggunakan fungsi yang telah dibuat dengan cara :
namafungsi (arg1, arg2,…)
Contoh Pembuatan dan Penggunaan Fungsi Baru
#membuat fungsi baru
angka_acak1=function(n,pw) {
x=runif(n)
y=runif(n)
z=(x+y)^pw
return(z)
}
#menggunakan fungsi baru
angka_acak1(10,2)## [1] 0.4046073 1.2672073 2.5443188 1.0943652 0.8401729 0.6548883 1.4720642
## [8] 0.9428687 0.8586727 0.7093297
Return menggunakan object list
#return menggunakan object list
angka_acak2=function(n,pw) {
x=runif(n)
y=runif(n)
z=(x+y)^pw
return(list(x=x,y=y,z=z))
}
angka_acak2(10,2)## $x
## [1] 0.90951526 0.03459733 0.86592606 0.65723122 0.84838157 0.95331140
## [7] 0.89185302 0.24328161 0.70367122 0.09065768
##
## $y
## [1] 0.8818494 0.2343555 0.5689263 0.5419852 0.1496842 0.5351268 0.2974807
## [8] 0.2174779 0.1122006 0.6793006
##
## $z
## [1] 3.2089875 0.0723356 2.0588014 1.4381201 0.9961352 2.2154484 1.4145147
## [8] 0.2122994 0.6656469 0.5928358
Argumen menggunakan nilai default
#argumen menggunakan nilai default
angka_acak3=function(n=10,pw=2) {
x=runif(n)
y=runif(n)
z=(x+y)^pw
return(z)
}
angka_acak3()## [1] 1.0111672 0.8550076 1.7487855 1.7313907 0.2627943 2.0075324 0.4198806
## [8] 0.3031140 0.8421742 0.9065769
Argumen didefinisikan terlebih dahulu sebelum memanggil fungsi baru
angka_acak4=function(){
x=runif(n)
y=runif(n)
z=(x+y)^pw
return(z)
}
#argumen di definisikan terlebih dahulu sebelum memanggil fungsi baru
n <-5; pw <-3
angka_acak4()## [1] 0.38820230 2.79573768 0.04647987 1.36769416 0.23816756
Latihan Pembuatan Fungsi
- Buatlah fungsi untuk mencari median dari suatu vektor
med<-function(vect) {
n <-length(vect)
vects<-sort(vect)
if(n%%2 == 1) {m <-vects[(n+1)/2]}
else{m <-(vects[n/2]+vects[(n/2)+1])/2}
return(m)
}
x1<-c(1,5,3,7,3,4,2,7) #input vektor yang akan dicari mediannya
med(x1)## [1] 3.5
- Buatlah fungsi untuk mencari modus dari suatu vektor
modus <-function(vect) {
v <-unique(vect)
f <-NULL
for(i in v) {
byk<-sum(vect==i)
f <-c(f,byk)
}
fmax<-max(f)
vf<-cbind(v,f)
mode <-vf[f==fmax,]
return(mode)
}
modus(x1)## v f
## [1,] 3 2
## [2,] 7 2
- Buatlah fungsi untuk menduga parameter pada regresi berganda
p.est<-function(A){
if(!is.matrix(A))
stop("input must be on matrix")
x1<-A[,-1]
y <-A[,1]
one<-rep(1,nrow(A))
x <-cbind(one,x1)
colnames(x)<-paste("x",1:ncol(x),sep="")
b.est<-as.vector(solve(t(x) %*% x) %*% (t(x) %*% y))
names(b.est)<-paste("b",0:(length(b.est)-1),sep="")
fitted.value<-as.vector(x%*%b.est)
error<-as.vector(y-fitted.value)
names(fitted.value)<-names(error)<-1:nrow(A)
list(beta.est=b.est,fit.val=fitted.value,error=error)
}
Pendapatan<-c(3.5,3.2,3.0,2.9,4.0,2.5,2.3)
Biaya.Iklan<-c(3.1,3.4,3.0,3.2,3.9,2.8,2.2)
Jumlah.Warung<-c(30,25,20,30,40,25,30)
X<-cbind(Pendapatan,Biaya.Iklan,Jumlah.Warung)
p.est(X) #memanggil fungsi## $beta.est
## b0 b1 b2
## -0.21381852 0.89843390 0.01745279
##
## $fit.val
## 1 2 3 4 5 6 7
## 3.094910 3.277176 2.830539 3.184754 3.988185 2.738116 2.286320
##
## $error
## 1 2 3 4 5 6
## 0.40508982 -0.07717642 0.16946108 -0.28475357 0.01181483 -0.23811608
## 7
## 0.01368033
Jika dibandingkan hasilnya dengan fungsi lm yang sudah ada
#membandingkan dengan fungsi lm
Pendapatan<-c(3.5,3.2,3.0,2.9,4.0,2.5,2.3)
Biaya.Iklan<-c(3.1,3.4,3.0,3.2,3.9,2.8,2.2)
Jumlah.Warung<-c(30,25,20,30,40,25,30)
model<-lm(Pendapatan~Biaya.Iklan+Jumlah.Warung)
model$coefficients## (Intercept) Biaya.Iklan Jumlah.Warung
## -0.21381852 0.89843390 0.01745279
## 1 2 3 4 5 6 7
## 3.094910 3.277176 2.830539 3.184754 3.988185 2.738116 2.286320
## 1 2 3 4 5 6
## 0.40508982 -0.07717642 0.16946108 -0.28475357 0.01181483 -0.23811608
## 7
## 0.01368033
Object Oriented Programming
R adalah bahasa pemrograman yang berbasis objek (PBO). PBO menitikberatkan pada identifikasi objek-objek yang terlibat dalam sebuah program dan bagaimana objek-objek tersebut berinteraksi. Pada PBO, program yang dibangun akan dibagi-bagi menjadi objek-objek.
Prinsip dari PBO adalah :
Abstraksi adalah suatu cara melihat suatu objek dalam bentuk yang sederhana. Sebagai contoh jika kita melihat sepeda motor. Kita tidak perlu melihat susunan komponen mesin dan dukungan elektriknya yang cukup kompleks dan rumit, namun kita bisa melihat sepeda motor itu sebagai sebuah entitas / satuan tunggal (single entity) yang merupakan sebuah objek yang mempunyai sifat dan karakteristik tersendiri.
Enkapsulasi adalah konsep tentang pengikatan data atau metode yang berbeda yang disatukan atau “dikapsulkan” menjadi satu unit data. Enkapsulasi dapat mempermudah dalam pembacaan code karena informasi yang disajikan tidak perlu dibaca secara rinci dan sudah merupakan satu kesatuan.
Inheritance adalah konsep OOP di mana kita dapat membentuk class baru yang “mewarisi” atau memiliki bagian-bagian dari class yang sudah ada sebelumnya. Konsep ini menggunakan sistem hirarki atau bertingkat. Semakin spesifik subclassnya, semakin sedikit pula komponen yang dapat diwarisi class tersebut.
Polymorphism adalah konsep di mana suatu objek yang berbeda-beda dapat diakses melalui interface yang sama. Sebuah objek yang polymorphic dapat beradaptasi dengan metode apapun yang diimplementasikan pada objek tersebut, dan setiap class memiliki interpretasinya tersendiri terhadap interfacenya. Dalam pemrograman, polimorfisme dapat diartikan sebagai modul yang memiliki nama sama, namun memiliki behaviour (tingkah laku) yang berbeda sehingga listing code implementasinya juga berbeda.
Class
Class adalah cetak biru atau blueprint dari object. Class digunakan hanya untuk membuat kerangka dasar. Yang akan kita pakai nantinya adalah hasil cetakan dari class, yakni object.
Suatu class dibagi menjadi property dan method
Property
Property (atau disebut juga dengan atribut) adalah data yang terdapat dalam sebuah class.
Method
Method adalah tindakan yang bisa dilakukan di dalam class. Method pada dasarnya adalah function yang berada di dalam class. Seluruh fungsi dan sifat function bisa diterapkan ke dalam method, seperti argumen/parameter, mengembalikan nilai (dengan keyword return), dan lain-lain.
Object
Pada bahasa pemrograman, object adalah komponen yang diciptakan dari class (instance of class).
Object Oriented Programming dalam R
Seperti sudah dijelaskan sebelumnya, R adalah bahasa pemrograman yang berbasis objek. Semua yang ada dalam R akan dianggap sebagai objek. Pengembangan awal objek di R menggunakan Class System S3 yang tidak terlalu ketat. Untuk pendefinisian yang ketat secara formal, R menggunakan Class System S4.
Object : Class System S3
Suatu Class dalam System S3 tidak didefinisikan dengan ketat. Fungsi class digunakan untuk menjadikan sebuah objek menjadi class yang diinginkan. Berikut adalah contoh class system S3
Class Integer
## [1] "integer"
Class Matrix dan Array
## [1] "matrix" "array"
Class Data Frame
## [1] "data.frame"
## [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l"
Class Model Linier
## [1] "lm"
## [1] add1 alias anova case.names coerce
## [6] confint cooks.distance deviance dfbeta dfbetas
## [11] drop1 dummy.coef effects extractAIC family
## [16] formula hatvalues influence initialize kappa
## [21] labels logLik model.frame model.matrix nobs
## [26] plot predict print proj qr
## [31] residuals rstandard rstudent show simulate
## [36] slotsFromS3 summary variable.names vcov
## see '?methods' for accessing help and source code
##
## Call:
## lm(formula = A5 ~ A3)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.1599 -0.2743 -0.1014 0.2922 1.3014
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 10.34646 0.46829 22.09 8.09e-10 ***
## A3 0.95067 0.06363 14.94 3.63e-08 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.7609 on 10 degrees of freedom
## Multiple R-squared: 0.9571, Adjusted R-squared: 0.9528
## F-statistic: 223.2 on 1 and 10 DF, p-value: 3.631e-08
## [1] "coefficients" "residuals" "effects" "rank"
## [5] "fitted.values" "assign" "qr" "df.residual"
## [9] "xlevels" "call" "terms" "model"
## (Intercept) A3
## 10.3464623 0.9506728
Class list
## [1] "list"
## $x
## [1] -1.74 -0.99 -1.62 -2.37 2.56
##
## $y
## [1] -0.24 0.93 0.57 -1.54 -0.55
Mengubah Menjadi class
class(obj) <- “class.name”
Contoh :
## [1] "list"
class(Mobil1) <-"mobil"
Mobil2 <-list(Nama="Suzuki", Panjang=1, Lebar=1.8, Kecepatan=150)
class(Mobil2) <-"mobil"Selanjutnya class pts akan dijadikan sebagai class baru
## [1] "coords"
## $x
## [1] -1.74 -0.99 -1.62 -2.37 2.56
##
## $y
## [1] -0.24 0.93 0.57 -1.54 -0.55
##
## attr(,"class")
## [1] "coords"
Fungsi konstruktor
Langkah untuk mengubah menjadi class diatas tidak disarankan karena nilai-nilai instan-nya mungkin tidak tepat. Untuk mengubah menjadi class, lebih disarankan dengan fungsi konstruktor karena fungsi ini menambahkan screening sebelum menambahkan class. Screening tersebut meliputi :
- x dan y harus berupa numerik
- vektor tidak boleh NA, NaN, Inf
- vektor harus memiliki panjang yang sama
Contoh :
Mobil <-function(Nama,Panjang,Lebar,Kecepatan){
if(Panjang<2 || Lebar<1.5 || Kecepatan<80)
stop("atribut tidak sesuai")
Mobil <-list(Nama=Nama, Panjang=Panjang,
Lebar=Lebar, Kecepatan=Kecepatan)
class(Mobil) <-"mobil"
Mobil
}
Mobil3 <-Mobil("Daihatsu", 2.1, 1.9, 120)Jika dijalankan syntax :
Mobil4 <-Mobil(“Proton”, 2, 1.8, 70)
Mobil Proton tidak lolos screening karena atribut tidak sesuai dengan yang diinginkan.
Contoh lain :
coords <- function (x, y) {
if (!is.numeric (x) || !is.numeric (y) || !all(is.finite(x)) || !all(is.finite(y)))
stop (" Titik koordinat tidak tepat !")
if ( length (x) != length (y))
stop (" Panjang koordinat berbeda ")
pts <- list (x=x, y=y)
class (pts) = " coords "
pts
}
pts <- coords (x = round ( rnorm (5) , 2) ,
y = round ( rnorm (5) , 2))Fungsi Aksesor
Untuk mengakses data dalam class, dapat menggunakan akses objek awalnya (list). Misal :
## [1] "Suzuki"
## [1] 2.1
Namun cara ini tidak dianjurkan, diperlukan suatu fungsi aksesor untuk mengakses data dalam class.
## [1] "Toyota"
## [1] 120
Contoh lain :
## [1] -0.59 -0.96 -0.13 0.61 -0.83
## [1] 1.14 0.99 -1.09 -1.46 0.44
Fungsi Generik
Fungsi generik merupakan suatu method dari suatu class objek dalam R. Fungsi generik bertindak untuk beralih memilih fungsi tertentu atau metode tertentu yang dijalankan sesuai dengan classnya
Terdapat beberapa fungsi generik yang sudah ada: print, plot, dll. Untuk mendefinisi ulang suatu fungsi generik digunakan syntax:
method.class <- function () ekspresibaru
Method Print
Method print merupakan cara menampilkan data pada suatu objek Class System S3
function(…){…}
Contoh :
print.mobil <-function(objek) {
print(cat("Nama : ",nama(objek),"\n", "Kecepatan : ", kecepatan(objek), sep=""))
}
Mobil1## Nama : Toyota
## Kecepatan : 180NULL
Contoh lain :
print.coords <- function (obj) {
print(paste("(", format ( xcoords (obj )), ", ", format (ycoords (obj )),")", sep=""),
quote = FALSE )
}
pts## $x
## [1] -0.59 -0.96 -0.13 0.61 -0.83
##
## $y
## [1] 1.14 0.99 -1.09 -1.46 0.44
##
## attr(,"class")
## [1] " coords "
Method Length
Fungsi length menghitung banyaknya anggota dari objek
## [1] 4
Class pts adalah suatu list, sehingga untuk menghitung length nya kurang tepat. Maka akan didefinisikan ulang class pts
## [1] 2
## [1] 2
Membuat Fungsi Generik Baru
Untuk membuat suatu method yang dapat diwariskan, maka method tersebut harus dijadikan fungsi generik
fungsibaru<-function (objek) UseMethod(“fungsibaru”)
Misal akan dibuatkan method bbox: merupakan boundary box.
Method Plot
plot.coords <- function (obj , bbox =FALSE , ...) {
if ( bbox ) {
plot ( xcoords (obj),ycoords ( obj), ...) ;
x <- c( bbox (obj )[1] , bbox (obj)[2] , bbox (obj)[2] , bbox
(obj) [1]) ;
y <- c( bbox (obj )[3] , bbox (obj)[3] , bbox (obj)[4] , bbox
(obj) [4]) ;
polygon (x,y)
} else {
plot ( xcoords (obj),ycoords ( obj), ...)
}
}
plot(pts) ### Pewarisan Class
Misalkan diinginkan sebuah objek yang berisi lokasi (coords) dan terdapat nilai pada lokasi tersebut. Diperlukan menciptakan class baru vcoords sebagai turunan dari coords
Fungsi konstruktor dari class vcoords:
vcoords <- function (x, y, v) {
if (!is.numeric (x) || !is.numeric (y) || !is.numeric (v) || !all(is.finite (x)) || !all(is.finite (y)))
stop (" Titik koordinat tidak tepat !")
if ( length (x) != length (y) || length (x) != length (v) )
stop (" Panjang koordinat berbeda ")
pts <- list (x=x, y=y, v=v)
class (pts) = c(" vcoords ", " coords ")
pts
}
nilai <- function (obj) obj$vPerhatikan fungsi xcoords dan ycoords dan method bbox dari kelas coords masih sama sehingga tidak perlu didefinisi ulang
vpts <- vcoords (x = round ( rnorm (5) , 2) ,
y = round ( rnorm (5) , 2) ,
v = round ( runif (5 ,0 ,100)))
vpts## $x
## [1] 0.91 0.14 -1.92 0.74 -0.49
##
## $y
## [1] -1.62 -0.50 0.30 -1.11 -0.37
##
## $v
## [1] 6 80 89 24 31
##
## attr(,"class")
## [1] " vcoords " " coords "
## [1] 0.91 0.14 -1.92 0.74 -0.49
## [1] -1.62 -0.50 0.30 -1.11 -0.37
Method print juga masih diwariskan dari class coords tetapi perlu didefinisi ulang
print.vcoords <- function (obj ) {
print ( paste ("(",
format ( xcoords (obj )),", ",
format ( ycoords (obj )),"; ", format ( nilai ( obj)),")",sep=""),
quote = FALSE )
}
vpts## $x
## [1] 0.91 0.14 -1.92 0.74 -0.49
##
## $y
## [1] -1.62 -0.50 0.30 -1.11 -0.37
##
## $v
## [1] 6 80 89 24 31
##
## attr(,"class")
## [1] " vcoords " " coords "
Method Subset
Diinginkan untuk memiliki akses terhadap metode subset
Ekspresi berikut misal diinginkan:
vpts [ xcoords ( vpts ) < 0 & ycoords ( vpts ) < 0]
'[. vcoords ' <- function (x, i) {
vcoords ( xcoords (x)[i], ycoords (x)[i],
nilai (x)[i])
}
vpts [1:3]## $x
## [1] 0.91 0.14 -1.92
##
## $y
## [1] -1.62 -0.50 0.30
##
## $v
## [1] 6 80 89
##
## attr(,"class")
## [1] " vcoords " " coords "
Pemeriksaan Suatu Class Objek
Untuk mengecek apakah suatu objek merupakan suatu class digunakan fungsi inherits
## [1] TRUE
## [1] FALSE
## [1] TRUE
## [1] TRUE
Sehingga dapat disimpulkan dari Class System S3 bahwa :
Class System S3 memberikan fasilitas object-oriented, tetapi terlalu longgar
Ekspresi berikut diperbolehkan dalam R, padahal class “lm” merupakan class untuk pemodelan linier
model <- 1:10; class ( model ) <- “lm”
- Masih banyak technical issue dalam Class System S3
Object : Class System S4
Class System S4: Mengatasi masalah dalam Class System S3 dengan sistem objek lebih formal. Dalam sistem objek formal, setiap objek didefinisikan secara formal dalam suatu class.
Keuntungan dari class system s4 adalah sistem penurunan dari class/objek.
Sebuah class terdiri dari slot dengan tipe atau class spesifik.
Mendefinisikanclass baru
setClass(“class.name”, representation(x=“type”), prototype(x=“…”))
Medefinisikan objek baru dari kelas tertentu
new(class.name,…)
setClass("car", representation(Nama="character",
Panjang="numeric",Lebar="numeric",Kecepatan="numeric"))
Car1 <-new("car", Nama="Toyota",Panjang=3.5, Lebar=2, Kecepatan=180)Fungsi Konstruktor
Car <-function(Nama,Panjang,Lebar,Kecepatan){
if(Panjang<2 || Lebar<1.5 || Kecepatan<80)
stop("atribut tidak sesuai")
new("car", Nama=Nama, Panjang=Panjang, Lebar=Lebar, Kecepatan=Kecepatan)
}
Car2 <-Car("Suzuki", 2.4, 1.8, 150)
class(Car2)## [1] "car"
## attr(,"package")
## [1] ".GlobalEnv"
## [1] "mobil"
Fungsi Aksesor
Akses terhadap slot menggunakan fungsi slot atau operator @
## [1] "Toyota"
## [1] 150
Namun disarankan dengan fungsi aksesor
## [1] "Toyota"
## [1] 150
Fungsi Generik
Fungsi generik show setara dengan fungsi generik print pada class System S3
Penciptaan fungsi generik menggunakan fungsi setMethod
setMethod(“method”,“class.name”,function(…){…})
setMethod(show, "car", function(object) {
print(cat("Nama: ", nama1(object), "\n", "Kecepatan: ", kecepatan1(object), sep=""))}
)
Car2## Nama: Suzuki
## Kecepatan: 150NULL
Menciptakan fungsi generik di Object Class S4
setGeneric(“fungsibaru”, function(objek) standardGeneric(“fungsibaru”))