Bagian 8 Pengembangan Fungsi
Fungsi (function) adalah kode-kode yang disusun untuk melakukan tugas tertentu, seperti perhitungan matematis, pembacaan data, analisis statistik, dan lainnya
8.1 Membuat Fungsi
Struktur fungsi adalah
<- function(arg1, arg2, … ){
myfunction
statementsreturn(object)
}
Fungsi 1 dengan output hanya nilai z saja.
= function(n,pw) {
angka_acak1 =runif(n)
x=runif(n)
y=(x+y)^pw
zreturn(z)
}# menggunakan fungsi
angka_acak1(10,2)
## [1] 3.2322800 0.6242086 0.3326876 0.5492360 1.0590209 1.1219177 0.7870891
## [8] 1.3319721 1.4719276 0.0555511
Fungsi 2 dengan output berupa nilai x, y, dan z.
# Membuat fungsi
= function(n,pw) {
angka_acak2 = runif(n)
x = runif(n)
y = (x+y)^pw
z return(list(x=x,y=y,z=z))
}
# Menggunakan fungsi
angka_acak2(10,2)
## $x
## [1] 0.13004849 0.97871535 0.06772972 0.65846763 0.82405551 0.28659556
## [7] 0.25492677 0.69414124 0.02902345 0.52910248
##
## $y
## [1] 0.9110802 0.9665378 0.3187146 0.4496721 0.9357783 0.4232877 0.5029422
## [8] 0.1356157 0.3556640 0.5645224
##
## $z
## [1] 1.0839489 3.7840098 0.1493392 1.2279736 3.0970152 0.5039343 0.5743654
## [8] 0.6884966 0.1479844 1.1960153
Fungsi 3 dengan memberikan nilai default pada argumen berupa n = 1
dan pw = 2
, sehingga ketika fungsi tersebut dipanggil tanpa menuliskan argumen, akan dijalankan fungsi defaultnya.
= function(n=10,pw=2) {
angka_acak3 = runif(n)
x = runif(n)
y = (x+y)^pw
z return(z)
}
angka_acak3()
## [1] 3.1055386 1.0626201 0.2837552 0.4773961 0.2354465 0.6206851 2.8971498
## [8] 1.2952584 2.3422619 0.4302200
Fungsi 4 dituliskan tanpa menggunakan argumen. Ketika fungsi tersebut akan digunakan maka dilakukan assign nilai yang diperlukan di dalam fungsi tersebut.
= function() {
angka_acak4 = runif(n)
x = runif(n)
y = (x+y)^pw
z return(z)
}
<- 5; pw <- 3
n angka_acak4()
## [1] 0.544510060 1.069862964 0.339701179 3.082262400 0.007045662
Latihan 1 Menghitung median dari suatu vektor
<- function(vect) {
med <- length(vect)
n <- sort(vect)
vects if(n%%2 == 1) {
<- vects[(n+1)/2]
m
}else {
<- (vects[n/2]+vects[(n/2)+1])/2
m
}return(m)
}
<- c(1,5,3,7,3,4,2,7)
x1 med(x1)
## [1] 3.5
Latihan 2 Menghitung modus dari suatu vektor
<- function(vect) {
modus <- unique(vect)
v <- NULL
f for(i in v) {
<- sum(vect==i)
byk <- c(f,byk)
f
}
<- max(f)
fmax <- cbind(v,f)
vf <- vf[f==fmax,]
mode return(mode)
}
modus(x1)
## v f
## [1,] 3 2
## [2,] 7 2
Latihan 3 menduga parameter pada regresi berganda
# Membuat fungsi
<- function(A) {
p.est if(!is.matrix(A))
stop("input must be on matrix")
<-A[,-1]
x1<-A[,1]
y <-rep(1,nrow(A))
one<-cbind(one,x1)
x colnames(x)<-paste("x",1:ncol(x),sep="")
<-as.vector(solve(t(x) %*% x) %*% (t(x) %*% y))
b.estnames(b.est)<-paste("b",0:(length(b.est)-1),sep="")
<-as.vector(x%*%b.est)
fitted.value<-as.vector(y-fitted.value)
errornames(fitted.value)<-names(error)<-1:nrow(A)
list(beta.est=b.est,fit.val=fitted.value,error=error)
}
# Memasukkan data
<-c(3.5,3.2,3.0,2.9,4.0,2.5,2.3)
Pendapatan<-c(3.1,3.4,3.0,3.2,3.9,2.8,2.2)
Biaya.Iklan<-c(30,25,20,30,40,25,30)
Jumlah.Warung<-cbind(Pendapatan,Biaya.Iklan,Jumlah.Warung)
Xp.est(X)
## $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
8.2 Object Oriented Programming
Pemrograman berorientasi objek merupakan sebuah paradigma dalam pembuatan sebuah program. OOP menitikberatkan pada identifikasi objek-objek yang terlibat dalam sebuah program dan bagaimana objek-objek tersebut berinterakasi. Pada OOP, program yang dibangun akan dibagi-bagi menjadi objek-objek. OOP menyediakan class dan object sebagai alat dasar untuk meminimalisir dan mengatur kompleksitas dari program.
8.2.1 Class (kelas)
Merupakan definisi statik (kerangka dasar) dari objek yang akan diciptakan. Suatu class dibagi menjadi:
- Property : data atau state yang dimiliki oleh class. Contoh pada class Mobil, memiliki property: warna, Model, Produsen.
- Method : behavior (perilaku) sebuah class. Bisa dikatakan sebagai aksi atau tindakan yang bisa dilakukan oleh suatu class. Contoh pada class Mobil, memiliki method: Start, Stop, Change Gear, Turn.
8.2.2 Object
Objek adalah komponen yang diciptakan dari class (instance of class). Satu class bisa menghasilkan banyak objek. Proses untuk membuat sebuah objek disebut instantiation. Setiap objek memiliki karakteristik dan fitur masing masing. Objek memiliki siklus creation, manipulation, dan destruction.
Prinsip dasar dari OOP adalah abstraksi, enkapsulasi, inherintance (pewarisan), dan polymorphism.
8.2.3 OOP in R
R telah mengimplementasikan pemrograman berorientasi objek. Semua dalam R adalah objek. Pengembangan awal objek di R menggunakan Class System S3 yang tidak terlalu ketat. Pendefinisian yang ketat secara formal, R menggunakan Class System S4.
Ilustrasi:
Sebuah class coords
dirancang untuk digunakan dengan menyimpan data koordinat titik pada dua buah vektor X
dan Y
. Metode pada class ini terdiri dari metode print
, length
, bbox
, dan plot
. Class lain dirancang sebagai turunan dari class coords dengan menambahkan data nilai untuk setiap titik pada koordinat X
dan Y
. Metode pada class vcoords
merupakan pewarisan dari class coords
dan operasi-operasi aritmetik terhadap nilainya.
8.3 Object : Class System S3
Contoh
# List creation with its attributes x and y.
<- list(x = round(rnorm(5),2),
pts y = round(rnorm(5),2))
class(pts)
## [1] "list"
Menjadikan pts sebagai class baru:
class(pts) <- "coords"
class(pts)
## [1] "coords"
pts
## $x
## [1] -1.06 -0.70 0.93 0.07 1.64
##
## $y
## [1] -0.43 -0.45 1.30 -0.28 -0.09
##
## attr(,"class")
## [1] "coords"
8.3.1 Konstruktor
Fungsi Konstruktor untuk Membuat class coords
<- function(x, y) {
coords 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")
<- list(x = x, y = y)
pts class(pts) = "coords"
pts
}<- coords(x = round(rnorm(5), 2), y = round(rnorm(5), 2))
pts pts
## $x
## [1] -0.84 -0.63 0.25 -0.91 0.97
##
## $y
## [1] -1.20 0.71 1.09 1.53 -1.06
##
## attr(,"class")
## [1] "coords"
Fungsi Konstruktor untuk Membuat class mobil
# Membuat list Mobil1
<- list(Nama="Toyota",
Mobil1 Panjang=3.5,
Lebar=2,
Kecepatan=180)
class(Mobil1)
## [1] "list"
<- function(Nama, Panjang, Lebar, Kecepatan) {
Mobil if(Panjang<2 || Lebar<1.5 || Kecepatan<80)
stop("atribut tidak sesuai")
<- list(Nama = Nama,
Mobil Panjang =Panjang,
Lebar = Lebar,
Kecepatan = Kecepatan)
class(Mobil) <- "mobil"
Mobil
}
<- Mobil("Daihatsu", 2.1, 1.9, 120)
Mobil3 Mobil3
## $Nama
## [1] "Daihatsu"
##
## $Panjang
## [1] 2.1
##
## $Lebar
## [1] 1.9
##
## $Kecepatan
## [1] 120
##
## attr(,"class")
## [1] "mobil"
8.3.2 Aksesor
Akses pada class coord
dengan menggunakan 2 fungsi
<- function(obj) obj$x
xcoords <- function(obj) obj$y
ycoords xcoords(pts)
## [1] -0.84 -0.63 0.25 -0.91 0.97
ycoords(pts)
## [1] -1.20 0.71 1.09 1.53 -1.06
Akses pada class mobil menggunakan fungsi aksesor
<- function(objek) objek$Nama
nama <- function(objek) objek$Kecepatan
kecepatan <- function(objek) objek$Panjang
panjang <- function(objek) objek$Lebar
lebarnama(Mobil1)
## [1] "Toyota"
kecepatan(Mobil3)
## [1] 120
panjang(Mobil3)
## [1] 2.1
8.3.3 Fungsi Generik
Fungsi generik bertindak untuk beralih memilih fungsi tertentu atau metode tertentu yang dijalankan sesuai dengan class-nya. Untuk mendefinisi ulang suatu fungsi generik digunakan syntax
<-function() ekspresibaru method.class
8.3.3.1 Print
Untuk class coords
<- function(obj) {
print.coords print(paste("(", format(xcoords(obj)), ", ", format(ycoords(obj)),
")", sep = ""), quote = FALSE)
} pts
## [1] (-0.84, -1.20) (-0.63, 0.71) ( 0.25, 1.09) (-0.91, 1.53) ( 0.97, -1.06)
Untuk class mobil
<- function(objek) {
print.mobil print(cat("Nama : ", nama(objek),
"\n",
"Kecepatan : ", kecepatan(objek),
sep="",
"\n",
"Panjang:", panjang(objek),
"\n",
"Lebar:", lebar(objek),
"\n") )
}
print.mobil(Mobil1)
## Nama : Toyota
## Kecepatan : 180
## Panjang:3.5
## Lebar:2
## NULL
8.3.3.2 Length
length(pts)
## [1] 2
Definisi ulang
<- function(obj) length(xcoords(obj))
length.coords length(pts)
## [1] 5
8.3.4 Membuat Fungsi Generik Baru
Misal ingin membuat method bbox
yang merupakan boundary box
<- function (obj)
bbox UseMethod ("bbox") #menjadikan bbox sebagai fungsi generik
<- function (obj){
bbox.coords matrix (c(range (xcoords(obj)),
range (ycoords(obj))),
nc=2, dimnames = list (
c("min", "max"),
c("x:", "y:")))
}bbox(pts)
## x: y:
## min -0.91 -1.20
## max 0.97 1.53
Plot khusus untuk class coords
<- function (obj,bbox=FALSE,...){
plot.coords if (bbox){
plot (xcoords(obj),ycoords(obj),...);
<- c(bbox(obj)[1],bbox(obj)[2],bbox(obj)[2],bbox(obj)[1]);
x <- c(bbox(obj)[3],bbox(obj)[3],bbox(obj)[4],bbox(obj)[4]);
y polygon (x,y)
else {
} plot (xcoords(obj),ycoords(obj),...)
} }
plot(pts)
plot(pts, bbox=T, pch=19, col="red")
8.3.5 Pewarisan class
Sebagai ilustrasi jika diinginkan sebuah objek yang berisi lokasi (coords) dan terdapat nilai pada lokasi tersebut maka diperlukan class baru vcoords
sebagai turunan dari coords
Konstruktor untuk class vcoords
<- function(x, y, v) {
vcoords 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 ")
<- list(x = x, y = y, v = v)
pts class(pts) = c("vcoords", "coords")
pts
}<- function(obj) obj$v nilai
<- vcoords(x = round(rnorm(5), 2),
vpts y = round(rnorm(5), 2),
v = round(runif(5, 0, 100)))
vpts
## [1] (-0.94, -0.65) ( 0.68, 1.52) ( 0.77, -1.20) ( 0.14, -1.02) ( 0.74, -1.14)
xcoords(vpts)
## [1] -0.94 0.68 0.77 0.14 0.74
ycoords(vpts)
## [1] -0.65 1.52 -1.20 -1.02 -1.14
bbox(vpts)
## x: y:
## min -0.94 -1.20
## max 0.77 1.52
Pendefinisian ulang method print
<- function(obj) {
print.vcoords print(paste("(", format(xcoords(obj)), ", ", format(ycoords(obj)),
"; ", format(nilai(obj)), ")", sep = ""), quote = FALSE)
} vpts
## [1] (-0.94, -0.65; 98) ( 0.68, 1.52; 57) ( 0.77, -1.20; 11) ( 0.14, -1.02; 40)
## [5] ( 0.74, -1.14; 33)
Pendefinisian ulang method plot
<- function(obj, txt = FALSE, bbox = FALSE, ...) {
plot.vcoords if (bbox) {
if (!txt) {
plot(xcoords(obj), ycoords(obj), ...)
else {
} plot(xcoords(obj), ycoords(obj), type = "n", ...)
text(xcoords(obj), ycoords(obj), nilai(obj), ...)
}<- c(bbox(pts)[1], bbox(pts)[2], bbox(pts)[2], bbox(pts)[1])
x <- c(bbox(pts)[3], bbox(pts)[3], bbox(pts)[4], bbox(pts)[4])
y polygon(x, y)
else {
} if (!txt) {
plot(xcoords(obj), ycoords(obj), ...)
else {
} plot(xcoords(obj), ycoords(obj), type = "n", ...)
text(xcoords(obj), ycoords(obj), nilai(obj), ...)
}
} }
Menampilkan plot
plot(vpts)
plot(vpts, txt = T, bbox = T, col = "red")
Subseting
`[.vcoords` <- function(x, i) {
vcoords(xcoords(x)[i], ycoords(x)[i], nilai(x)[i])
}1:3] vpts[
## [1] (-0.94, -0.65; 98) ( 0.68, 1.52; 57) ( 0.77, -1.20; 11)
8.3.6 Pemeriksaan suatu class objek
inherits(pts, " coords ")
## [1] FALSE
inherits(pts, " vcoords ")
## [1] FALSE
inherits(vpts, " coords ")
## [1] FALSE
inherits(vpts, " vcoords ")
## [1] FALSE
<- list(1:10)
model class(model) <- "lm"
model
##
## Call:
## NULL
##
## No coefficients
8.4 Object : Class System S4
Class System S4 mengatasi masalah dalam Class System S3 dengan sistem objek lebih formal. Sebuah class terdiri dari slot dengan tipe atau class spesifik.
8.4.1 Deklarasi
Class dideklarasikan dengan fungsi setClass
Contoh 1, mendefinisikan ulang class coords
ke class system S4
setClass("coords",
representation(x="numeric",
y="numeric"))
Contoh 2, deklarasi class car
setClass("car",
representation(Nama="character",
Panjang="numeric",
Lebar="numeric",
Kecepatan="numeric"))
<- new("car",
Car1 Nama="Toyota",
Panjang=3.5, Lebar=2,
Kecepatan=180)
8.4.2 Konstruktor
Membuat objek coords
<- function(x, y) {
coords if (length(x) != length(y))
stop("length x dan y harus bernilai sama")
if (!is.numeric(x) || !is.numeric(y))
stop("x dan y harus vektor numeric")
new("coords", x = as.vector(x), y = as.vector(y))
}
set.seed(123)
<- coords(round(rnorm(5), 2), round(rnorm(5), 2))
pts pts
## An object of class "coords"
## Slot "x":
## [1] -0.56 -0.23 1.56 0.07 0.13
##
## Slot "y":
## [1] 1.72 0.46 -1.27 -0.69 -0.45
Membuat object car
menggunakan fungsi konstruktor
<- function(Nama,Panjang,Lebar,Kecepatan) {
car if(Panjang<2 || Lebar<1.5 || Kecepatan<80)
stop("atribut tidak sesuai")
new("car", Nama=Nama, Panjang=Panjang,
Lebar=Lebar, Kecepatan=Kecepatan)
}
<- car("Suzuki", 2.4, 1.8, 150)
Car2 class(Car2)
## [1] "car"
## attr(,"package")
## [1] ".GlobalEnv"
class(Mobil1)
## [1] "list"
8.4.3 Aksesor
Akses terhadap slot menggunakan operator @
slot(pts, "x")
## [1] -0.56 -0.23 1.56 0.07 0.13
@x pts
## [1] -0.56 -0.23 1.56 0.07 0.13
slot(pts, "y")
## [1] 1.72 0.46 -1.27 -0.69 -0.45
@y pts
## [1] 1.72 0.46 -1.27 -0.69 -0.45
Disarankan menggunakan fungsi
<- function(obj) obj@x
xcoords <- function(obj) obj@y
ycoords xcoords(pts)
## [1] -0.56 -0.23 1.56 0.07 0.13
Akses terhadap slot pada objek car
@Nama Car1
## [1] "Toyota"
@Kecepatan Car2
## [1] 150
Akses terhadap slot pada objek car
dengan fungsi aksesor
<- function(objek) objek@Nama
nama1 <- function(objek) objek@Kecepatan
kecepatan1
nama1(Car1)
## [1] "Toyota"
kecepatan1(Car2)
## [1] 150
8.4.4 Fungsi generik
Penciptaan fungsi generik menggunakan fungsi setMethod
. Argumen didefinisikan dalam signature
Contoj: show
(setara dengan print
pada S3)
setMethod(show, signature(object = "coords"),
function(object) print(paste("(",
format(xcoords(object)),
", ", format(ycoords(object)),
")", sep = ""),
quote = FALSE))
pts
## [1] (-0.56, 1.72) (-0.23, 0.46) ( 1.56, -1.27) ( 0.07, -0.69) ( 0.13, -0.45)
setMethod(show, "car",
function(object) {
print(cat("Nama : ", nama1(object), "\n",
"Kecepatan : ", kecepatan1(object),
sep="")
)}
) Car2
## Nama : Suzuki
## Kecepatan : 150NULL
8.4.5 Definisi fungsi generik baru
setGeneric("bbox", function(obj) standardGeneric("bbox"))
## [1] "bbox"
setMethod("bbox", signature(obj = "coords"),
function(obj)
matrix(c(range(xcoords(obj)),
range(ycoords(obj))),
nc = 2,
dimnames = list(c("min","max"),
c("x:", "y:")
)
))bbox(pts)
## x: y:
## min -0.56 -1.27
## max 1.56 1.72
8.4.5.1 Fungsi generik plot
setMethod("plot", signature(x = "coords"),
function(x, bbox = FALSE, ...) {
if (bbox) {
plot(xcoords(x), ycoords(x), ...)
.1 <- c(bbox(x)[1], bbox(x)[2], bbox(x)[2], bbox(x)[1])
x.1 <- c(bbox(x)[3], bbox(x)[3], bbox(x)[4], bbox(x)[4])
ypolygon(x.1, y.1)
else {
} plot(xcoords(x), ycoords(x), ...)
}
})
plot(pts)
plot(pts, bbox = T, pch = 19, col = "red", xlab = "x",
ylab = "y")
8.4.6 Pewarisan class
Akan dibuat class baru yang diturunkan dari coords
dengan menambahkan slot nilai
setClass("vcoords", representation(nilai = "numeric"),
contains = "coords")
<- function(x, y, nilai) {
vcoords if ((length(x) != length(y)) || (length(x) != length(nilai)))
stop("length x, y, dan nilai harus bernilai sama")
if (!is.numeric(x) || !is.numeric(y) || !is.numeric(nilai))
stop("x, y, dan nilai harus vektor numeric")
new("vcoords", x = as.vector(x), y = as.vector(y),
nilai = as.vector(nilai))
}
<- function(obj) obj@nilai nilai
<- vcoords(xcoords(pts), ycoords(pts), round(100*runif(5)))
vpts vpts
## [1] (-0.56, 1.72) (-0.23, 0.46) ( 1.56, -1.27) ( 0.07, -0.69) ( 0.13, -0.45)
Definisi ulang method show
setMethod(show, signature(object = "vcoords"),
function(object)
print(paste("(",
format(xcoords(object)),
", ",
format(ycoords(object)),
"; ",
format(nilai(object)),
")", sep = ""),
quote = FALSE))
vpts
## [1] (-0.56, 1.72; 89) (-0.23, 0.46; 69) ( 1.56, -1.27; 64) ( 0.07, -0.69; 99)
## [5] ( 0.13, -0.45; 66)
Definisi ulang method plot
setMethod("plot", signature(x = "vcoords"),
function(x, txt = FALSE, bbox = FALSE, ...) {
if (bbox) {
if (!txt) {
plot(xcoords(x), ycoords(x), ...)
else {
} plot(xcoords(x), ycoords(x), type = "n", ...)
text(xcoords(x), ycoords(x), nilai(x), ...)
}
.1 <- c(bbox(x)[1], bbox(x)[2], bbox(x)[2], bbox(x)[1])
x.1 <- c(bbox(x)[3], bbox(x)[3], bbox(x)[4], bbox(x)[4])
ypolygon(x.1, y.1)
else {
}
if (!txt) {
plot(xcoords(x), ycoords(x), ...)
else {
} plot(xcoords(x), ycoords(x), type = "n", ...)
text(xcoords(x), ycoords(x), nilai(x), ...)
}
} })
plot(vpts)
plot(vpts, txt = T, bbox = T, pch = 19, col = "red")
8.4.7 Operasi Aritmetika
Menggunakan perintah
setMethod("Arith", ...
<- function(e1, e2) (
sameloc length(nilai(e1)) == length(nilai(e2)) ||
any(xcoords(e1) == xcoords(e2)) ||
any(ycoords(e1) == ycoords(e2))
)
setMethod("Arith", signature(e1 = "vcoords",
e2 = "vcoords"),
function(e1, e2) {
if (!sameloc(e1, e2))
stop("Dibutuhkan titik identik")
vcoords(xcoords(e1), ycoords(e2), callGeneric(nilai(e1),
nilai(e2)))
})
+ vpts vpts
## [1] (-0.56, 1.72; 178) (-0.23, 0.46; 138) ( 1.56, -1.27; 128)
## [4] ( 0.07, -0.69; 198) ( 0.13, -0.45; 132)
2+vpts
## Error in 2 + vpts: non-numeric argument to binary operator
setMethod("Arith", signature(e1 = "numeric",
e2 = "vcoords"),
function(e1, e2) {
if (length(e1) > length(nilai(e2)))
stop("length yang tidak benar")
vcoords(xcoords(e2), ycoords(e2), callGeneric(as.vector(e1),
nilai(e2)))
})
2*vpts
## [1] (-0.56, 1.72; 178) (-0.23, 0.46; 138) ( 1.56, -1.27; 128)
## [4] ( 0.07, -0.69; 198) ( 0.13, -0.45; 132)
*vpts vpts
## [1] (-0.56, 1.72; 7921) (-0.23, 0.46; 4761) ( 1.56, -1.27; 4096)
## [4] ( 0.07, -0.69; 9801) ( 0.13, -0.45; 4356)
8.4.8 Subset
setMethod("[", signature(x = "vcoords",
i = "ANY",
j = "missing",
drop = "missing"),
function(x,i, j)
vcoords(xcoords(x)[i],
ycoords(x)[i],
nilai(x)[i]))
1:3] vpts[
## [1] (-0.56, 1.72; 89) (-0.23, 0.46; 69) ( 1.56, -1.27; 64)
8.4.9 Pemeriksaan Suatu Class Objek
is(pts ,"coords")
## [1] TRUE
is(pts ,"vcoords")
## [1] FALSE
is(vpts ,"coords")
## [1] TRUE
is(vpts ,"vcoords")
## [1] TRUE
8.4.10 Coerce
<- as(vpts, "coords")
vpts2 vpts2
## [1] (-0.56, 1.72) (-0.23, 0.46) ( 1.56, -1.27) ( 0.07, -0.69) ( 0.13, -0.45)
is(vpts2, "coords")
## [1] TRUE
<- as(pts , "vcoords")
pts2 pts2
## [1] (-0.56, 1.72; ) (-0.23, 0.46; ) ( 1.56, -1.27; ) ( 0.07, -0.69; )
## [5] ( 0.13, -0.45; )
is(pts2, "vcoords")
## [1] TRUE
<- list(x = round(rnorm(5), 2), y = round(rnorm(5), 2))
ob ob
## $x
## [1] 0.55 0.24 -1.05 1.29 0.83
##
## $y
## [1] -0.06 -0.78 -0.73 -0.22 -0.33
as(ob , "vcoords")
## Error in as(ob, "vcoords"): no method or default for coercing "list" to "vcoords"
<- list(123)
mdl class(mdl) <- "lm"
mdl
##
## Call:
## NULL
##
## No coefficients
8.4.10.1 Latihan
Buat fungsi bernama three.M
yang digunakan untuk menghitung mean
, median
, modus
dari suatu vector (tanpa menggunakan fungsi mean
, quantile
atau pun fungsi “instan” lain yang sudah tersedia sebelumnya di R).
Hitung mean
, median
, dan modus
dari suatu data rbinom(100,10, 0.5)
dengan seed(123)
.
<- function(vect) {
three.M <- length(vect) # banyak data
n
# rataan
<- sum(vect)
jumlah <- jumlah/n
rataan
# median
<- sort(vect) # urutkan
vects if(n%%2 == 1) {m <- vects[(n+1)/2]}
else {m <- (vects[n/2]+vects[(n/2)+1])/2}
# modus
<- unique(vect)
v <- NULL
f for(i in v) {
<- sum(vect==i)
byk <- c(f,byk)
f
}
<- max(f)
fmax <- cbind(v,f)
vf <- vf[f==fmax,]
mode
# output
<- list("mean" = rataan, "median" = m, "modus" = mode)
my_list class(my_list) <- "threeM"
return(my_list)
}
Fungsi generik print
<- function(obj){
print.threeM cat("three.M Statitic\n")
cat("\nMean: ", obj$mean)
cat("\nMedian: ", obj$median)
cat("\nModus:\n")
print(obj$modus)
}
set.seed(123)
<- rbinom(100,10,0.5)
x1 three.M(x1)
## three.M Statitic
##
## Mean: 4.99
## Median: 5
## Modus:
## v f
## [1,] 6 24
## [2,] 5 24
Latihan, membuat fungsi Regresi Komponen Utama
<- function(X){
AKU
# transform X into matrix
<- as.matrix(X)
X
# transform all var into z-score
<- scale(X, center = TRUE, scale = TRUE)
X <- attr(X, "scaled:center")
x.bar <- attr(X, "scaled:scale")
x.stdev
# compute singular-value decomposition
<- La.svd(X)
SVD <- SVD$d
D
# compute principal component
<- SVD$u %*% diag(D, nrow = ncol(X))
pc.score
# get eigenvector from SVD
<- SVD$vt
eigenvector
# compute eigenvalues and PC contributions
<- D / sqrt(max(1, nrow(X) - 1))
pc.score.stdev <- pc.score.stdev^2
eigenvalue <- eigenvalue/sum(eigenvalue)
eigenvalue.proportion <- cumsum(eigenvalue.proportion)
eigenvalue.cum.proportion <- rbind(eigenvalue, eigenvalue.proportion, eigenvalue.cum.proportion)
eigenanalysis
# assign names
<- paste0('PC', seq(ncol(X)))
pc.name colnames(pc.score) <- rownames(eigenvector) <- colnames(eigenanalysis) <- names(pc.score.stdev) <- pc.name
rownames(pc.score) <- rownames(X)
colnames(eigenvector) <- colnames(X)
rownames(eigenanalysis) <- c("Eigenvalue", "Proportion", "Cumulative")
# wrap output into list
<- list(
out n.col = ncol(X),
n.row = nrow(X),
x.bar = x.bar, x.stdev = x.stdev,
pc.score = pc.score,
pc.score.stdev = pc.score.stdev,
eigenvalue = eigenanalysis, eigenvector = t(eigenvector)
)
# asign a class
class(out) <- "AKU"
return(out)
}
Metode generik print.AKU
<- function(obj) {
print.AKU cat("PRINCIPAL COMPONENT ANALYSIS\n")
cat("Input: ", obj$n.row, "rows X", obj$n.col, "columns\n")
cat("\nEigenanalysis of Correlation Matrix:\n")
print(obj$eigenvalue)
cat("\nEigenvectors:\n")
print(obj$eigenvector)
cat("\nScore of Principal Component (Preview):\n")
print(rbind(head(obj$pc.score)))
if(nrow(obj$pc.score) > 6) cat("...")
}
Contoh penggunaan
<- "https://raw.githubusercontent.com/nurandi/sta561-uts/main/data/pca-data.csv"
url <- read.csv(url)
dta
<- dta[1]
y <- dta[-1] X
<- AKU(X) aku
aku
## PRINCIPAL COMPONENT ANALYSIS
## Input: 15 rows X 4 columns
##
## Eigenanalysis of Correlation Matrix:
## PC1 PC2 PC3 PC4
## Eigenvalue 3.7693710 0.16253376 0.04423637 0.023858911
## Proportion 0.9423427 0.04063344 0.01105909 0.005964728
## Cumulative 0.9423427 0.98297618 0.99403527 1.000000000
##
## Eigenvectors:
## PC1 PC2 PC3 PC4
## X1 0.5056158 -0.3398479 0.35682315 0.7081902
## X2 0.4940545 0.6392714 0.50650265 -0.3011600
## X3 0.5035406 0.3178941 -0.78135788 0.1867354
## X4 0.4966988 -0.6121919 -0.07491445 -0.6106547
##
## Score of Principal Component (Preview):
## PC1 PC2 PC3 PC4
## [1,] -3.2417574 -1.03926963 -0.21320529 0.18559324
## [2,] -1.8486832 0.01142542 0.22832852 -0.10777842
## [3,] -0.7795219 0.46096143 0.04824186 -0.14517167
## [4,] -0.1361711 0.04200545 -0.08603160 0.01717014
## [5,] -1.0044094 -0.07221540 0.24797726 0.02243639
## [6,] 1.8019258 -0.23968031 -0.11141042 -0.03474123
## ...
print(aku)
## PRINCIPAL COMPONENT ANALYSIS
## Input: 15 rows X 4 columns
##
## Eigenanalysis of Correlation Matrix:
## PC1 PC2 PC3 PC4
## Eigenvalue 3.7693710 0.16253376 0.04423637 0.023858911
## Proportion 0.9423427 0.04063344 0.01105909 0.005964728
## Cumulative 0.9423427 0.98297618 0.99403527 1.000000000
##
## Eigenvectors:
## PC1 PC2 PC3 PC4
## X1 0.5056158 -0.3398479 0.35682315 0.7081902
## X2 0.4940545 0.6392714 0.50650265 -0.3011600
## X3 0.5035406 0.3178941 -0.78135788 0.1867354
## X4 0.4966988 -0.6121919 -0.07491445 -0.6106547
##
## Score of Principal Component (Preview):
## PC1 PC2 PC3 PC4
## [1,] -3.2417574 -1.03926963 -0.21320529 0.18559324
## [2,] -1.8486832 0.01142542 0.22832852 -0.10777842
## [3,] -0.7795219 0.46096143 0.04824186 -0.14517167
## [4,] -0.1361711 0.04200545 -0.08603160 0.01717014
## [5,] -1.0044094 -0.07221540 0.24797726 0.02243639
## [6,] 1.8019258 -0.23968031 -0.11141042 -0.03474123
## ...
$eigenvalue aku
## PC1 PC2 PC3 PC4
## Eigenvalue 3.7693710 0.16253376 0.04423637 0.023858911
## Proportion 0.9423427 0.04063344 0.01105909 0.005964728
## Cumulative 0.9423427 0.98297618 0.99403527 1.000000000
head(aku$pc.score)
## PC1 PC2 PC3 PC4
## [1,] -3.2417574 -1.03926963 -0.21320529 0.18559324
## [2,] -1.8486832 0.01142542 0.22832852 -0.10777842
## [3,] -0.7795219 0.46096143 0.04824186 -0.14517167
## [4,] -0.1361711 0.04200545 -0.08603160 0.01717014
## [5,] -1.0044094 -0.07221540 0.24797726 0.02243639
## [6,] 1.8019258 -0.23968031 -0.11141042 -0.03474123
Fungsi regresi komponen utama
<- function(y, X, k){
RKU
if(is.null(colnames(X))) colnames(X) <- paste0("V", seq(ncol(X)))
<- AKU(X)
aku
if(is.null(k)){
<- ncol(X)
k else if(k < 1){
} <- sum(aku$eigenvalue[3,] < k) + 1
k
}
<- aku$pc.score[,1:k]
pc.score <- as.data.frame(cbind(y, pc.score))
pcr.data <- colnames(aku$pc.score)[1:k]
pc.name colnames(pcr.data) <- c("y", pc.name)
<- lm(y ~ ., data = pcr.data)
pcr.lm <- summary.lm(pcr.lm)[c("coefficients", "sigma",
pcr.summary "r.squared", "adj.r.squared",
"fstatistic", "df")]
<- as.matrix(pcr.lm$coefficients)
beta.pcr
<- (aku$eigenvector)[,1:k] %*% as.matrix(beta.pcr[-1])
beta.z.score1 <- rbind(beta.pcr[1], beta.z.score1)
beta.z.score <- rbind(beta.pcr[1] - (aku$x.bar/aku$x.stdev) %*% beta.z.score1,
beta.x /aku$x.stdev)
beta.z.score1
# asign name
colnames(beta.pcr) <- colnames(beta.z.score) <- colnames(beta.x) <- "Estimates"
rownames(beta.z.score) <- c("(Intercept)", paste0("Z_", colnames(X)))
rownames(beta.x) <- c("(Intercept)", colnames(X))
<- list(pca = aku,
out k = k,
pcr.lm = pcr.lm,
pcr.summary = pcr.summary,
pcr.coefficient = summary.lm(pcr.lm)$coefficients,
beta.z.score = beta.z.score,
beta.x = beta.x)
<- c(aku, out)
out class(out) <- "RKU"
return(out)
}
<- function(obj, mode = "simple") {
print.RKU
if(mode == "ext"){
print(obj$pca)
cat("\n\n")
}
cat("PRINCIPAL COMPONENT REGRESSION\n")
cat("With", obj$k, "Principal Component(s)\n")
cat("\nFormula: y ~ Principal Component Score\n\n")
print(obj$pcr.coefficient)
cat("\nR-squared: ", obj$pcr.summary$r.squared)
cat(", Adjusted R-squared: ", obj$pcr.summary$adj.r.squared,
"\nF Statistics:", obj$pcr.summary$fstatistic[1])
cat(", DF1:", obj$pcr.summary$fstatistic[2])
cat(", DF2:", obj$pcr.summary$fstatistic[3])
cat(", p-value:", format.pval(pf(obj$pcr.summary$fstatistic[1],
$pcr.summary$fstatistic[2],
obj$pcr.summary$fstatistic[3],
objlower.tail = FALSE)))
if(mode == "simple"){
cat("\n\nNote: use print(obj, 'ext') to print extended output\n")}
if(mode == "ext"){
cat("\n\nInverse Transform into Z Score\n")
print(obj$beta.z.score)
cat("\nInverse Transform into X\n")
print(obj$beta.x)
}
}
<- RKU(y = y, X = X, k = 1) rku
rku
## PRINCIPAL COMPONENT REGRESSION
## With 1 Principal Component(s)
##
## Formula: y ~ Principal Component Score
##
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 76.273333 0.5588331 136.48679 0.0000000000000000000006595387
## PC1 3.755193 0.2979403 12.60384 0.0000000115720528926616900058
##
## R-squared: 0.9243556, Adjusted R-squared: 0.9185368
## F Statistics: 158.8568, DF1: 1, DF2: 13, p-value: 0.000000011572
##
## Note: use print(obj, 'ext') to print extended output
print(rku)
## PRINCIPAL COMPONENT REGRESSION
## With 1 Principal Component(s)
##
## Formula: y ~ Principal Component Score
##
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 76.273333 0.5588331 136.48679 0.0000000000000000000006595387
## PC1 3.755193 0.2979403 12.60384 0.0000000115720528926616900058
##
## R-squared: 0.9243556, Adjusted R-squared: 0.9185368
## F Statistics: 158.8568, DF1: 1, DF2: 13, p-value: 0.000000011572
##
## Note: use print(obj, 'ext') to print extended output
print(rku, mode = "ext")
## PRINCIPAL COMPONENT ANALYSIS
## Input: 15 rows X 4 columns
##
## Eigenanalysis of Correlation Matrix:
## PC1 PC2 PC3 PC4
## Eigenvalue 3.7693710 0.16253376 0.04423637 0.023858911
## Proportion 0.9423427 0.04063344 0.01105909 0.005964728
## Cumulative 0.9423427 0.98297618 0.99403527 1.000000000
##
## Eigenvectors:
## PC1 PC2 PC3 PC4
## X1 0.5056158 -0.3398479 0.35682315 0.7081902
## X2 0.4940545 0.6392714 0.50650265 -0.3011600
## X3 0.5035406 0.3178941 -0.78135788 0.1867354
## X4 0.4966988 -0.6121919 -0.07491445 -0.6106547
##
## Score of Principal Component (Preview):
## PC1 PC2 PC3 PC4
## [1,] -3.2417574 -1.03926963 -0.21320529 0.18559324
## [2,] -1.8486832 0.01142542 0.22832852 -0.10777842
## [3,] -0.7795219 0.46096143 0.04824186 -0.14517167
## [4,] -0.1361711 0.04200545 -0.08603160 0.01717014
## [5,] -1.0044094 -0.07221540 0.24797726 0.02243639
## [6,] 1.8019258 -0.23968031 -0.11141042 -0.03474123
## ...
##
## PRINCIPAL COMPONENT REGRESSION
## With 1 Principal Component(s)
##
## Formula: y ~ Principal Component Score
##
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 76.273333 0.5588331 136.48679 0.0000000000000000000006595387
## PC1 3.755193 0.2979403 12.60384 0.0000000115720528926616900058
##
## R-squared: 0.9243556, Adjusted R-squared: 0.9185368
## F Statistics: 158.8568, DF1: 1, DF2: 13, p-value: 0.000000011572
##
## Inverse Transform into Z Score
## Estimates
## (Intercept) 76.273333
## Z_X1 1.898685
## Z_X2 1.855270
## Z_X3 1.890892
## Z_X4 1.865200
##
## Inverse Transform into X
## Estimates
## (Intercept) 44.0669992
## X1 0.7520572
## X2 0.8271652
## X3 3.0821554
## X4 3.6330905
$pcr.coefficient rku
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 76.273333 0.5588331 136.48679 0.0000000000000000000006595387
## PC1 3.755193 0.2979403 12.60384 0.0000000115720528926616900058
# print class lm
summary(rku$pcr.lm)
##
## Call:
## lm(formula = y ~ ., data = pcr.data)
##
## Residuals:
## Min 1Q Median 3Q Max
## -3.6187 -1.4432 -0.4312 1.5546 3.4001
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 76.2733 0.5588 136.5 < 0.0000000000000002 ***
## PC1 3.7552 0.2979 12.6 0.0000000116 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 2.164 on 13 degrees of freedom
## Multiple R-squared: 0.9244, Adjusted R-squared: 0.9185
## F-statistic: 158.9 on 1 and 13 DF, p-value: 0.00000001157
Ref (Raharjo 2021b) (Soleh 2021b) (Rahmi 2021b)