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阅读 199,519评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,842评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,544评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,742评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,646评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,027评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,513评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,169评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,324评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,268评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,299评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,996评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,591评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,667评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,911评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,288评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,871评论 2 341

推荐阅读更多精彩内容

  • 写在之前 因为简书字数限制,完整版地址:https://www.zybuluo.com/hainingwyx/no...
    hainingwyx阅读 13,848评论 0 41
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,531评论 18 399
  • 接R-面向对象编程 下面演示如何基于TimeSeries类实现一个WeightHistory类以记录个人的历史体重...
    王诗翔阅读 910评论 0 1
  • OOA:Object-Oriented Analysis面向对象分析方法 是在一个系统的开发过程中进行了系统业务调...
    楚易枫阅读 3,626评论 0 5
  • 不知何时 你竟开始质疑面向佛陀的意义 遗忘了三宝与每日的叩拜 背弃了牧人的原野 丢失了谦卑的心 你止步于拥挤的佛堂...
    喇叭奏花腔阅读 292评论 0 5