当前课程知识点:R语言数据分析 >  中部:执具 >  第6章 基础编程——用别人的包和函数讲述自己的故事 >  6.5 函数(I)

返回《R语言数据分析》慕课在线视频课程列表

6.5 函数(I)在线视频

下一节:6.6 函数(II)

返回《R语言数据分析》慕课在线视频列表

6.5 函数(I)课程教案、知识点、字幕

大家好

欢迎来到《R语言数据分析》课程

今天和大家交流一下函数相关的内容

我们先回到我们的Mini案例

其中 我们说迷你案例里面

我们涉及了很多数据分析的一些具体的步骤

比如说认识数据

数据预处理

建模 评估 等等

咱们看一看其中的数据预处理这个环节

我们将代码稍微放大一点

看一下

我们这个数据预处理里面其中有一条

就是对这个数据进行分箱

为了进行关联规则的挖掘

我们对每一门课 语文 数学 外语 等等

一直到生物这九门课

每门课由百分制转换成五分制

我们采用这么一种方式来做的

对这个分箱的操作

这么一种写代码方式当然是可以的

还有另外一种方式是

因为你是要对语文数学外语政治历史等等

一直到生物这九门课都要做同样的操作

都是通过这个cut()

我将百分制cut成五分制

然后我们经常有一种写法

语文这个写完了然后我数学复制

粘贴 复制 粘贴 复制 粘贴 一直复制粘贴到生物

然后把其中的函数的某一些变量

这个参数我改成由yw改成sx 改成wy

这么一种写代码的方式

经常有人犯这个错误

当然本质上讲也不能说是一种错误

但我们特别不倡导这种写法

为什么呢

比如说我现在在写数学的时候

拷贝过来当然是可以的

等到你写到政治历史地理的时候

因为我们人是不善于做这种重复简单劳动的

然后你可能到这个历史或者到这个物理

这时候我就忘了把这个里面那个yw成绩

直接就交给地理dl = cut(yw,...)

直接cut一下

这里面那个yw忘了改

那怎么办

后面再做调试的时候

几乎很难发现这个问题

因为本身这个代码它没有语法错误

同时比如说我们现在拿到的成绩里面

就每门课的成绩可能差不多

你看完之后

你发现数据的取值也没有太大的异常

所以这种代码是特别特别难调试的

当我们在后面做代码的调试和维护的时候

你会发现这种简单的复制粘贴复制粘贴多次的话

其实有很大的问题的

有很大的隐患

这也就引出来我们今天的主题

我们需要编写相应的函数

而不是简单的拷贝在那拷贝粘贴

什么时候需要用到函数呢

我们的哈德利Hadley

这帅哥 他这样说的

当反反复复复制粘贴你的代码

超过两次以上的时候

就需要考虑是不是应该写一个函数来实现它

当然具体的在编码法则里面有一个叫

叫rule of three

当我们把它翻译成中文的话

我们可以简单的说 叫事不过三

复制粘贴复制粘贴多次的时候

重复三次以上

我们应该考虑最好是写个函数

而不是简单的把它拷贝过来变成一个硬代码

我们后面很难维护它

那在R里面如何实现如何来编写这个函数

我们都知道R里面其实一切都是对象

我们在前面讲这个顺序结构

分支结构等等的时候都发现

我们其实在R里面一切都是对象

通过赋值来产生这个对象

那函数也是一样的

函数也是一样

其实函数也是

比如说我现在要创建一个函数

给函数起个名

就像那个变量取个名字

然后我通过赋值的方式来创建它

就把后面这一个函数体赋值给这个变量名

就完成了这个函数定义的过程

其实也就是函数对象的创建的过程

我们说创建可能更合适一点

因为R里面其实是不需要定义的

都是通过直接创建来得到相应的结果

同样是通过这个小于号一个减号 <-

这么一种方式来创建我们的相应的这个函数

这个函数对象

因为它是一个函数

相对比较特殊

所以它要加一个这个function这个关键词

我们都知道函数其实是一个

输入-处理-输出的过程

应该是一个Input-Process-Output的过程

所谓输入就是我这些参数

参数就是这个函数的输入

然后中间有些处理的过程

处理完之后

最后结果会return

将这个结果返回就可以了

就是输入-处理-输出

这是一个函数最基本的一个过程

我们举个例子来看看R里面是如何实现函数的

比如说我现在有这么一个需要做的事情

就是由摄氏度转化成华氏度

那这个时候我先有一个变量的名称ce2fa

其实也是通过一个赋值的方式来做的

通过赋值将这一部分函数体赋给它

赋值给它

这时候我接受参数是ce 原来的摄氏度

然后我返回结果就是华氏度

中间处理过程其实比较简单

就是一个摄氏度到华氏度一个转变的过程

其实就是用1.8乘以这个摄氏度的再加上32

这就变成华氏度了

我们一旦定义完这个函数之后

就可以像调用其它函数一样

来调用我们自己定义的这个函数

先是这个函数的名称

后面加上括符

大家注意了

调用函数的过程就是函数名后面跟着小括符

小括号里面就是我们这个相应的参数了

可以将这个0传过来

下面这个ce的取值就为0了

然后毫无疑问这个华氏度就32

假如我这里面交给它参数多少是0到10的话

0-1-2-3-4-5-6-7-8-9-10

总共有11个摄氏度的温度

这时候相当于返回结果是多少

还是长度为11的一个华氏度的温度

这里面其实就是一个函数的定义和调用的过程

我们说了这个函数调用

应该是这个函数名紧跟小括号

假如我不跟的话怎么办

不跟的话它其实就是把这个ce2fa这个函数体

因为我们把函数体赋给它了

那就像其它的变量一样

它只要把这个函数体给你显示了

而不是调用这个函数

所以大家注意下这个区别

假如你要调用某个函数的话

就这个函数名()

括符里面是它的相应的参数

这是我们R里面这个定义函数的最基本的方式

定义和这个调用函数最基本的方式

在这个R里面使用这个函数的话

一个非常关键点是

要注意这个位置参数和名义参数

我们再举个例子

比如说我现在定义了一个函数

名字叫做frm

它接受两个参数

就是某个人来自于哪

有name frm

我们在当然这边比较简单

为了演示

为了演示

我们只是输出一下cat()这是输出 在控制台输出

我们只是输出一下cat()这是输出 在控制台输出

输出某个人is frm它后面这个参数

我们看一下

假如我现在这样调用的话

frm括符空的

因为我这里面其实定义了两个参数

一个是name

另外一个frm

接收两个参数

第一个参数没有默认值

第二个参数有默认值是BUPT

那这个时候假如我在调用这个函数的话

括符里面什么参数都没有

那会怎么样

这个时候会出错

为什么

因为我这个argument name

name这个参数它是缺失的

事先没有一个默认值

没有一个缺省值

这个时候就会出错

但假如说这种情况

比如说我frm里面加一个axb

axb 我的拼音的第一个字母

这个时候它自动输出

axb is from BUPT

就是说第二个参数没有赋给它的时候

那怎么办

因为它有个默认值

我就直接采用那个默认值

咱们再看看

因为我是定义了name和frm

那我在调这个函数的时候

我可以直接指定它name等于AXB

然后frm等于比如说我可以换一下BJTU

这个时候毫无疑问我的结果

就应该就是AXB is frm BJTU

就改了 而不是默认值了

当然这个时候其实和下面这条语句

是完全等价的

为什么呢

因为它相应的位置取相应的值

那我直接把

这个取值直接放到这个小括号里面来就可以

放到这个小括号里面来就可以

大家注意了 下面这条语句也是正确的

我先frm="BJTU" 然后name="AXB"

也是可以的

为什么呢

因为这个时候用的是名义参数

而不是位置

不是说位置上一一对应

因为这个时候已经没有二义性

这边只有两个参数

而且我把每个参数的名字都指定了

毫无疑问没有二义性

没有二义性的话

那我这在R里面这种语法也是允许的

就是你的原始的定义的位置

name在前frm在后

那你在调用的时候

我直接指定frm等于多少name等于多少就可以

位置没有影响

这里面其实就是我们讲到的

R里面既有位置参数

也有名义参数

我们再看几行比较熟悉代码

我们前面在讲这个控制流的时候就用到这个c()

combine这个函数

比如说通过c()这个函数来创建一个向量

我创建这个xm yw xb都可以

这个时候我们再考虑一下

我们前面所谓的两种参数的方式

一种是位置参数

一种是名义参数

我们看第一个姓名

它包含着六个同学

然后我再看性别的时候

你发现FALSE TRUE TRUE

这时候问题就出来了

为什么呢

你发现这里面它其实长度都不一样

我没办法定义这个位置

而且它名称也没有办法定义

我们来说第一个参数名字是什么

第二个参数名字是什么

因为这里面c()这个函数可以接受任意多个参数

再比如我们那个sum()这个函数也是一样

你交给sum()的时候

你可以1 3 5 7就交给它

也可以交给比如说我们前面这六位同学的成绩

语文成绩也可以

那这时候我们就出一个问题了

假如我自己来定义这个c()函数

或者sum()函数的时候

那这个参数怎么设置

怎么接收这个参数

毫无疑问

因为它是任意多个参数都可以传递过来

那就比较特殊了

就用到我们打开这个帮助文档

就会发现

它这个c()也好

这个sum()也好

你发现它接受参数

它不是参数的名称

而是三个点...

三个点...代表任意参数

你可以把任意多个参数传递过来

好 任意多个参数传递过来之后

我怎么使用

我们看一下

其实我们自己也可以用...作为参数

比如我第一个函数叫my_func

这个时候我接受...作为参数

那其实我要假如我想知道第二个参数什么的话

用 ..2

比如说第三个参数 ..3

就是 ..2 ..3

就表示提取第二个和第三个参数

假如我要把所有这个三个点里面传递过来参数

我都给捕获到的话怎么办

我可以通过这个list

通过这个列表来捕获到它

我们后面会讲

这个list是R里面最灵活一种数据结构

就任意的对象的集合都可以作为list

也就说我们后面会来通过这个list这个办法

来捕获它之后

毫无疑问

比如说我交给这个dot_args

那dot_args 比如说第一个参数

任意一个参数

我都可以把它提取出来

这里面其实就是

对三个点的这种特殊参数的一个使用

除了这个位置参数名义参数之外

我们对这三个点的参数也简单介绍一下

当然因为我们现在还没有讲那个

具体的数据对象

这个列表还有点不熟悉

没关系

我们在后续课程讲完之后

再重新温习这段代码的话就比较简单

讲完了前面我们参数设置之后

我们想再看看这几行代码

比如说1+2

毫无疑问这是最简单的计算

1+2=3

但这时候我下面这种代码写法

大家看一看

加号用双引号引起来

然后(1, 2)

我们前面讲了

函数名后面加上小括号里面是参数的话

这就是个函数调用的过程

对吧

看完这个形式之后

我们就突然间发现

原来这个加号这个二元操作符

其实也是一个函数而已

它是一个特殊的函数

再比如这个

这个毫无疑问是2除以3

等于0.66666

再比如这个10的平方

这尖号都代表几次方

然后这个呢 2大于1

毫无疑问返回是TRUE

再比如这个毫无疑问我们一看是

这是一个赋值的符号

其实非常形象

将某一个值赋给谁赋给某个变量

这是new

我们创建了一个新的变量赋给它

其实包括后面我们可能会接触到的

比如说这个冒号

冒号表示什么

比如说 1:10

就是1-2-3-4-5-6-7-8-9-10

一个步长为1的等差数列

包括其实后面讲

比如下标等等

其实本质上都是二元操作符

咱们再看看这个二元操作符里面

用的非常多的就是百分号括起来

作为一个二元操作符

比如说1 3 9是不是在这个1 2 3里面

毫无疑问它返回结果

长度为3的一个逻辑向量

1在这里面3也在这里面9就不在了

所以返回结果TRUE TRUE FALSE

我们也可以自己定义自己的二元操作符

比如说我定义一个由两个直角边

求出斜边的这么一个函数

我接收两个参数

一个a和b都是直角边

然后怎么样

我求这个斜边的长度c

当然这个求的过程其实很简单

就是就a的平方加上b的平方

然后再开根号

这就返回它就可以了

当然假如我们在这个定义函数的时候

没有写return这个语句的话

它就把最后一条语句的结果就返回过来

这时候我们再写

比如3我们双引号引起来的

%ab2c% 然后4

结果是多少

结果就是5了

它像我们一般的调用方式

比如 3+4

3/4

3*4

二元操作符是完全一样的

就左边一个参数

右边一个参数

把这个二元操作符放在中间

我们看完了这种那个自己定义的这个

由两个直角边求出斜边的函数之后

再来看后面这个

再看这个Mini小案例的时候

其实讲到一个什么操作呢

管道操作符

就两个百分号括起来一个大于号 %>%

刚开始看的时候觉得奇奇怪怪的

而且是比如说前面是一个数据对象

然后后面是一个函数

这个觉得好复杂

莫名其妙

其实我们一旦看完了前面我们自己定义的这个

%ab2c%之后毫无疑问

这里面的管道操作符其实也只是一个

二元操作符也是一个函数而已

假如我们一旦有了这个二元操作符

是函数这个概念的话

这个代码就不奇怪了

它就相当于(等价于)下面这个代码

就比如说我先定一个x然后

把x里面重复的部分去掉它

unique(x)然后再对这个去掉重复的元素之后的

这个新的x进行sort()

从低到高进行排序

当然我们用这个管道操作符进行操作的时候

它其实没有中间这些变量

x2 x3都没有创建

它只是个临时变量

好 即便我们对这个加减乘除这个操作符

其实我们也可以做一些自己的定义

比如说我们通常来讲

直接说输入一个5+2

毫无疑问告诉你结果是7

但这时候我可以来点恶作剧

我先定义一个加号

注意了

我们在定义二元操作符的时候

必须用单引号'

双引号"

或者这个反单引号`把它括起来

括起来之后 也是通过赋值的方式来创建它

大家一看我们这里面是接受x和y

作为两个参数

然后我做的不是加我是乘

我是乘以它

那这个你再调用5+2的话

它结果就不是7了 而是多少

10

当然我们为了避免这个恶作剧

这种效果我们可以把这个rm = remove

将我们刚才定义的这个加号去掉

这个时候又恢复到原来那个正常的加号的含义

这里面我们就简单讲了一下

这个二元操作符本质上也是一个函数

当然是二元操作符我们在定义的时候

一个比较特殊的地方是要加上这个双引号

单引号或者反单引号

我们同样在调用它帮助文档的时候也得注意了

也得把它引起来

其实针对我们一般的函数

比如说round这是四舍五入的

其实你用这个单引号双引号

或者反单引号来引起来的话

这样查找帮助文档也是可以的

大家稍微注意一下

否则的话你要是不加这个单引号 双引号

或者反单引号的话那这个语句是不完整

这里我们提了一下

在这个查这些特殊的二元操作符

这么一种特殊的函数的时候

查它的帮助文档

需要用这个引号把它引起来

以上我们关于这个函数

将我们函数的定义

以及我们这个函数的一些参数的设置

包括我们讲的这个二元操作符

作为特殊的函数做一个简单介绍

关于函数更多的内容

我们接下来课程继续讲

本次课到此结束

谢谢大家

R语言数据分析课程列表:

上部:问道

-第1章 气象万千、数以等观

--第1章 气象万千、数以等观

--第1章 作业

-第2章 所谓学习、归类而已

--2.1 所谓学习、归类而已(I)

--2.2 所谓学习、归类而已(II)

--2.3 所谓学习、归类而已(III)

--2.4 所谓学习、归类而已(IV)

--第2章 作业

-第3章 格言联璧话学习

--第3章 格言联璧话学习

--第3章 作业

-第4章 源于数学、归于工程

--第4章 源于数学、归于工程

--第4章 作业

-讨论题

--如何发挥人工智能的头雁效应

中部:执具

-第5章 工欲善其事、必先利其器

--第5章 工欲善其事、必先利其器

--第5章 作业

-第6章 基础编程——用别人的包和函数讲述自己的故事

--6.1 编程环境

--6.2Mini案例

--6.3 站在巨人的肩膀上

--6.4 控制流

--6.5 函数(I)

--6.6 函数(II)

--第6章 作业

-第7章 数据对象——面向数据对象学习R语言

--7.1 向量与因子(I)

--7.2 向量与因子(II)

--7.3 矩阵与数组(I)

--7.4 矩阵与数组(II)

--7.5 列表与数据框(I)

--7.6 列表与数据框(II)

--第7章 作业

-第8章 人人都爱tidyverse

--第8章 人人都爱tidyverse

--第8章 作业

-第9章 最美不过数据框

--第9章 最美不过数据框

--第9章 作业

下部:博术

-第10章 观数以形

--10.1 一维数据空间(I)

--10.2 一维数据空间(II)

--10.3 二维数据空间

--10.4 高维数据空间

--第10章 作业

-第11章 相随相伴、谓之关联

--11.1 导引

--11.2 关联规则(I)

--11.3 关联规则(II)

--11.4 关联规则(III)

--第11章 作业

-第12章 既是世间法、自当有分别

--12.1 导引

--12.2 近邻法(I)

--12.3 近邻法(II)

--12.4 决策树(I)

--12.5 决策树(II)

--12.6 随机森林

--12.7 朴素贝叶斯

--12.8 逻辑斯蒂回归

--12.9 人工神经网络(I)

--12.10 人工神经网络(II)

--12.11 支持向量机

--第12章 作业

-第13章 方以类聚、物以群分

--13.1 导引

--13.2 划分方法

--13.3 层次方法

--第13章 作业

-第14章 庐山烟雨浙江潮

--第14章 庐山烟雨浙江潮

--第14章 作业

6.5 函数(I)笔记与讨论

也许你还感兴趣的课程:

© 柠檬大学-慕课导航 课程版权归原始院校所有,
本网站仅通过互联网进行慕课课程索引,不提供在线课程学习和视频,请同学们点击报名到课程提供网站进行学习。