R--面向對象的編程

OOP

#封裝,將相關的數據項目打包為一個類的實例
#多態,相同的函數使用不同的類的對象的時候可以調用不同的操作
#繼承,允許把一個給定的類的性質自動賦予為其下屬的更特殊化的類

#S3類包含一個列表,附加一個類名屬性和調度的功能
#具有多態性的函數如plot()和print()稱為泛型函數
#調用泛型函數的時候,R會將該調用調度到適當的類方法
#也就是將對泛型函數的調用重新定向到針對該對象的類所定義的函數上

x <- c(1,2,3)
y <- c(1,3,8)
lmout <- lm(y~x)
#lm()函數將返回一個lm類的對象
class(lmout)
lmout
#直接輸入lmout會調用print.lm()```

#泛型函數的實現方法

methods()找到給定泛型函數的所有實現方法

methods(print)

星號是不可見函數,不在默認命名空間中的函數

通過getAnywhere()函數來找到函數,并且使用命名空間限定符訪問他們

getAnywhere(print.lm)

可以看出這個函數在stats命名空間下,使用下面限定符執行它

stats:::print.lm(y~x)

操作符 :: :::訪問命名空間變量

pkg::name returns the value of the exported variable name in namespace pkg

and pkg:::name returns the value of the internal variable name

查看所有的泛型函數

methods(class="default")

S3類的實例是通過構建一個列表的方式創建的,列表的組件是該類的成員變量

類屬性是通過attr()或者class()函數手動設置,再定義各種泛型函數的實現方法

j <- list(name="joe",salary=55000,union=T)

創建一個類

class(j) <- "employee"
attributes(j)
j#打印的時候被當成一個列表

定義自己這個類的打印方法,打印的時候就會默認調度到這個方法上

print.employee <- function(wrkr){
cat(wrkr$name,"\n")
cat("salary",wrkr$salary,"\n")
cat("union member",wrkr$union,"\n")
}```

使用繼承

k <- list(name="kate",salary=68000,union=F,hrsthismonth=2)
#建立hrlyemployee類繼承至employee
class(k) <- c("hrlyemployee","employee")
#新類繼承了原有類的方法,因從可以使用其print```

#用于存儲上三角矩陣的類

function returns 1+..+i

sum1toi <- function(i) return(i*(i+1)/2)

create an object of class ut from the full matrix inmat

ut <- function(inmat){

nrow and ncol return the number of rows or columns present in x

n <- nrow(inmat)

start to build the object

創建一個列表作為類對象的主體,rtrn表示將會創建并返回這個類實例

rtrn <- list()

將ut設為一個類

class(rtrn) <- "ut"
rtrn$mat <- vector(length = sum1toi(n))

ix也是個向量,存儲了開始的位置索引

rtrn$ix <- sum1toi(0:(n-1))+1
for (i in 1:n){
#store column i
ixi <- rtrn$ix[i]
rtrn$mat[ixi:(ixi+i-1)]<-inmat[1:i,i]
}
return(rtrn)
}

uncompress utmat to a full matrix

expandut <- function(utmat){

numbers of rows and cols of matrix

n <- length(utmat$ix)

initialize a matrix

fullmat <- matrix(nrow = n,ncol = n)
for(j in 1:n){
start <- utmat$ix[j]
#這一行有多少個元素,然后計算出finish
fin <- start + j - 1
#above-diag part of col j
abovediagj <- utmat$mat[start:fin]
#將向量填充至矩陣的每一列中,然后剩下元素補0
fullmat[,j] <- c(abovediagj,rep(0,n-j))
}
return(fullmat)
}

print matrix

print.ut<-function(utmat){
print(expandut(utmat))
}

multiply one ut matrix by another,returning another ut instance

"%mut%" <- function(utmat1,utmat2){

一個二元操作符

ix向量的長度就是矩陣的維數

n <- length(utmat1$ix)

初始化一個輸出的上三角矩陣

utprod <- ut(matrix(0,nrow=n,ncol=n))

開始迭代計算乘法,i表示矩陣2計算第幾列,j表示進行計算的具體元素

for(i in 1:n){
#提取出來utmat2的第i列元素的初始索引位置
startbi <- utmat2$ix[i]
#第i列就有i個元素,初始化乘積矩陣的每一列
prodcoli <- rep(0,i)
for(j in 1:i){
#通過j來選取應該和第i列計算的矩陣1的元素
startaj <- utmat1$ix[j]
#選取矩陣2的要計算的元素,單個值
bielement <- utmat2$mat[startbi+j-1]
#對于j的變化,從1到i,計算矩陣1相應的元素和矩陣2每列的元素乘積
#如果i=2,那么prodcoli[1]=prodcoli[1]+b3=2a+3b,prodcoli[2]=3c
#用兩個輸入矩陣的列項來解決乘法問題
prodcoli[1:j] <- prodcoli[1:j]+bielement
utmat1$mat[startaj:(startaj+j-1)]
}
#矩陣每次開始計算的位置
startprodcoli <- sum1toi(i-1)+i
#乘積矩陣的第1或者第2,3個或者第4,5,6個元素,由計算出來的prodcoli來賦值
utprod$mat[startbi:(startbi+i-1)] <- prodcoli
}
return(utprod)
}

做一個測試

test <- function(){
utm1 <- ut(rbind(1:2,c(0,2)))
utm2 <- ut(rbind(3:2,c(0,1)))
utp <- utm1 %mut% utm2
print(utm1)
print(utm2)
print(utp)
utm1 <- ut(rbind(1:3,0:2,c(0,0,5)))
utm2 <- ut(rbind(4:2,0:2,c(0,0,1)))
utp <- utm1 %mut% utm2
print(utm1)
print(utm2)
print(utp)
}```

S4類

#S3類僅僅是列表,所以可以隨時添加任何組件,因此滿足不了面向對象編程的安全性
#S4類就可以避免這些問題
#setClass()來定義一個S4類,每個成員變量都有明確的類型
setClass("employee",representation(name="character",salary="numeric",
                                      union="logical"))
#創建對象,使用new()來為此類創建一個實例
joe <- new("employee",name="joe",salary=56000,union=T)
#成員變量稱為slot,@用來訪問成員變量,可以寫入可以讀取
joe@salary <- 64000
#或者使用slot()函數
slot(joe,"salary") <- 78000

#直接輸入joe相當于執行了show(joe)
#改寫這個show()函數,定義泛型函數
#第一個參數是將要定義給類方法的泛型函數名
#第二個參數是類的名稱,第三個是一個匿名函數,定義這個新函數
setMethod("show","employee",function(object){
  #iselse語句
  inorout <- ifelse(object@union,"is","is not")
  cat(object@name,"has a salary of",object@salary,
      "and",inorout,"in the union","\n")
})```

#對象的管理

ls()函數列出所有的對象

ls()

pattern這個具名參數,可以列出名稱具有特定模式的對象

ls(pattern = 'dd')#雙引號和單引號都可以

rm()函數刪除特定對象

刪除a,b對象

rm(a,b)

刪除ls()列出的所有對象,rm的具名參數list=

rm(list=ls())

使用ls()的pattern具名參數

pattern參數后面要加雙引號

rm(list=ls(pattern = "dd"))```

save()函數保存對象集合

#若干個對象調用save()可以將對象寫入硬盤,以待之后用load()恢復
#生成符合正態分布的隨機數10000個
z <- rnorm(10000)
hz <- hist(z)
save(hz,"hzfile")
rm(hz)
load("hzfile")
ls()
plot(hz)

#保存和加載R的數據(與R.data的交互:save()函數和load()函數)
a <- 1:10
save(a, file = "data/dumData.Rdata") #
#data文件為當前工作目錄下的文件,必須存在
rm(a)
load("data/dumData.Rdata")
print(a)```

#一些有用的函數

unclass()顧名思義,對一個對象使用得到的結果仍然屬于其基礎類

page()查看一個對象,比如函數,page(table),主要解決問題是函數太長,

不容易顯示的問題

edit()同樣可以解決這種問題,可以在文本編輯器中進行查閱

names()函數可以顯示出對象有哪些組件

attributes()函數顯示對象組件并且給出更多信息,比如類名稱```

exists()函數

#來檢測對象是否存在
exists("abc")
#返回TRUE 或者 FALSE```
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,578評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,701評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,691評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,974評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,694評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,026評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,015評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,193評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,719評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,442評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,668評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,151評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,846評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,255評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,592評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,394評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,635評論 2 380

推薦閱讀更多精彩內容

  • 寫在之前 因為簡書字數限制,完整版地址:https://www.zybuluo.com/hainingwyx/no...
    hainingwyx閱讀 13,984評論 0 41
  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,737評論 18 399
  • 接R-面向對象編程 下面演示如何基于TimeSeries類實現一個WeightHistory類以記錄個人的歷史體重...
    王詩翔閱讀 934評論 0 1
  • OOA:Object-Oriented Analysis面向對象分析方法 是在一個系統的開發過程中進行了系統業務調...
    楚易楓閱讀 3,707評論 0 5
  • 不知何時 你竟開始質疑面向佛陀的意義 遺忘了三寶與每日的叩拜 背棄了牧人的原野 丟失了謙卑的心 你止步于擁擠的佛堂...
    喇叭奏花腔閱讀 311評論 0 5