当前课程知识点:R语言数据分析 > 中部:执具 > 第7章 数据对象——面向数据对象学习R语言 > 7.1 向量与因子(I)
大家好
欢迎来到《R语言数据分析》课程
今天和大家交流一下
向量与因子的相关内容
在我们前面的课程里面提出了一个
有关R语言的三段论
对吧
也就是说
就知识体系而言
其实R语言也可以分成实体性的
有数据对象
再加上什么
一些过程性的基础编程
具体来讲基础编程这块
我们涉及到
R的运行机制
它的那个扩展包的查找
基本控制流
以及有关函数的相关的内容
在前面课程里面
我们已经将前面基础编程部分
进行了简要的交流
从今天开始我们正式进入这一部分
就是数据对象部分
数据对象主要分成三组六类
当然对于数据对象而言
其实它都是什么
它都是关于我们数据的
一个存储
我们说数据其实都是什么
都是对现实系统进行观测
进行记录
它的结果就是数据
假如我们对现实对象进行单一维度的观测的话
比如说我要观测建筑物的高度
只关注这一个维度的话
那好
那其实我们拿到就是说
不同建筑物的高度的数据
这个时候我通过什么
向量来进行存储
再比如说我要观测这个学生的
属性
观测一百个学生
他的性别 或者说他的姓名等等
其实像这个单一维度的观测的话
我们都通过什么
向量或者是因子进行存储
当然根据这个观测所得的数据
它的类别不同
比如说它可以是类别数据
也可以什么
数值型的数据
假如说数值型的变量的话
这个时候怎么样
我通过向量进行存储
假如是类别变量的话怎么样
我通过这个因子进行存储
这就是单一属性
它相应的一些记录
也就是说是单变量的数据的存储
通过向量或者因子进行存储
假如多个变量的话
比如说我对这个学生他的属性
我既要观测他的 记录他的姓名
也要记录他的性别 记录他的什么
各门科目的成绩等等
那这个时候我就涉及到什么
要么就矩阵
要么就是什么
要么就数据框进行存储
假如我这个观察到属性都是同质的
同一种类型
比如说我要观测不同的同学
他的语文 数学 外语成绩
这个语文 数学 外语成绩
它都什么
都是数值型的
那我就通过什么
我通过矩阵来进行存储
当然矩阵它是属于什么
它属于那个数组的一种特殊形式
矩阵是二维的 数组可以是更高维的
这就我们要讲的第二组
这个矩阵或者数组
这是第二组对象
和矩阵形式上差不多的
它形式上和矩阵非常相似
就是我们这个数据框了
比如说我观察多个属性
但是不同的属性的类别(数据类型)不一样
我既要观测这个成绩
语文 数学 外语的成绩
但同时我还想
记录他的姓名 性别
那这个时候它类型不一样的时候
就通过什么
就通过这个数据框来进行存储
数据框它形式上和矩阵很相似
但本质上属于列表
本质上属于列表
所以这里面我们就讲第三组
就是这个列表或者数据框
这是我们整个这个R里面
三组六类数据对象
当然其实对R来讲
它的数据对象还有其他一些
但假如我们掌握了这三组六类的话
基本上典型的数据分析
已经足够用了
无论我们外部数据怎么样
从哪来
比如说你的从关系数据库里面来
通过传感器获得相应的数据
实时监测数据
或者通过互联网爬取相关的数据
当然有可能是你拿到一些平面数据
比如说excel表的数据
或者说这个csv文件的数据
它其实最终都要什么
最终都要变成我们的六种数据类型之一
假如你通过
R来做这个数据分析的话
应该说是万法归宗
最终它就是这么六种数据对象
六种数据对象
比如单变量的向量或者因子
多变量的什么
矩阵或者是数据框
高维的数组或者是更加灵活的列表
当然这是对于数据的一个组织的形式
典型来讲有这么六种
那具体数据材质有哪几种
其实也是六种
具体来讲有 逻辑型
整型 双精度型
复数型 字符型以及原始的字节数据
当然这一种基本很少用
原始字节的数据很少用
比如说我们涉及到一些编码等等
比如中文编码等等
转换的过程可能会涉及到一部分
其他绝大部分情况用得比较少
用得比较多 是哪几种
加※号的这几种
逻辑型 整型 双精度型以及这个字符型
这四种用得非常多的
咱们稍微补充一下
是在其它一些语言里面
比如说我们涉及到这个数值型的时候
有单精度型 双精度型
对吧
R里面其实只有一个什么
是一个双精度型
或者说这个整型也是一样
所以我们后面加一个什么
加一个L
没有什么
就是长整型 短整型
我们这边都是什么
都是L
这是我们材质的话
总共这么四种是最主要的
我们记住一下逻辑型 整型
双精度型以及字符型
R里面也不区分什么
也不区分这个字符或者是字符串
我们统一称为什么
统一称为字符型
单引号 双引号基本也不作区分
单引号和双引号都是可以的
用它括起来
要不括单个字符也好
就包括单引号也可以用到什么
括一个字符串
都是可以的
好 看完我们这个数据的最基本的材质
之后我们就进入我们具体内容讲解了
这个数据对象
咱们三组六类
咱们先看第一组的第一种
所谓的向量
创建向量的话
我们用的最多的方式什么
通过c()这个函数
我们前面讲了
这个c这个函数并不是abc的意思
对吧
而是什么
combine将你的不同的值
Combine Values into a Vector
就将不同的数值
我把它什么
组合成一个什么
组合成一个向量
比如说
我现在要记录了六个同学的
那个姓名的话
就是把那个同学的姓名这个字符怎么样
我交给谁
交给这个c()这个函数
这个c()是函数
它自然就Combine成一个什么
Combine成一个字符的这个向量了
再比如说后面这个
性别
女 男 男 女 男 女
我也可以交给什么
交给xb这么一个字符向量
当然比如说我是语文成绩的话
这六位同学的语文成绩我可以通过什么
将这些具体得分c()一下
生成(创建)一个什么
yw这么一个数值型的一个向量
当然我们也可以创建逻辑型的
比如说我通过这个TRUE or FALSE
因为逻辑取值只有两种
要么是TRUE 要不就FALSE
比如说我生成一个什么
创建一个xb的
xb的一个逻辑向量
当然在R里面这个TRUE和FALSE简写
为T或者是F
T或者F
大家注意一下
这个TRUE和FALSE都必须是所有字符都是大写
所有字符都是大写
那当然可以简写成T和F
应该讲T和TRUE或者
F和FALSE基本上没什么区别
唯一区别是什么
TRUE和FALSE属于什么
属于常量
然后T和F属于什么
预先定义好的全局变量
所以这个时候你可以把FALSE赋值T: FALSE -> T
但毫无疑问
你不可以把什么不可以把FALSE -> TRUE
那肯定不可以的
比如说我们现在创建一个
向量叫3.1415926
这就是个π对吧 π
但毫无疑问
这个时候π的每一位上的一个元素
我交给这个c()的时候
它既有什么
既有数值也有什么
也有字符
那这时候怎么办
在R里面你一旦是交给c()的时候
它会要求你所有的类型都是一样的
假如类型不一样怎么办
它强制类型转换
那毫无疑问
你这点号
没有办法转化成什么
没有办法
转换成一个数值
只能把数值转换成字符
所以我们得到结果
你会发现它是什么
它是一个字符向量
是一个字符向量
当然比如说下面这个我既有数值
又有什么
又有这个逻辑值
3 1 4 1 5 9 2 6
这它就转换了一下
就把这个TRUE转换成1
把那个FALSE 假如有FALSE的话
就转换成0了
所以大家注意一下
在创建向量的时候
通过这个c()创建向量的时候
第一个注意点是什么
它会要求你所有的材质都是一样
假如不一样
它会做一个强制类型转换
好
我们再来看下面一个
看下面这行代码
我这边也是c()一组数
第一个元素是1
第二个元素是2
第三个元素
我们在创建的时候
它是一个什么
是一个向量
对不对
c(4, 3)
对吧
第四个元素什么
c(1, 0)
假如我们把这些部分一起
c()成一起之后
这个时候结果是什么
那我第三个元素是究竟是4还是c(4, 3)
这个时候第三个元素是什么
是4
而不是c(4, 3)
为什么
因为在R里面一旦进行c()的时候
它就会把所有的什么
所有的这个元素都拉平
也说都拆包
不存在说
我这里面c()里面
还有一个什么这个向量里面还有另外一个
子向量的问题
不存在这个问题
大家都是同样的元素
都是同样的元素
所以说会拉平它
这也是一个需要注意的点
这通过c()来创建我们的这个
无论是字符型的 逻辑型的
还是数值型的
创建这个向量的过程
简单演示了一下
当然我们在创建向量的时候
假如我事先已经知道了它的类型
并且知道它的长度的话
比如说它的那个类型是numeric
然后这个长度为8
那这个时候我可以
通过这个vector这个函数来创建它
默认就是
默认值为零
长度为8的
取值都为零的这么一个数值向量
当然你可以通过这个
通过这个numeric
将参数8赋给它也可以
这个时候默认值都为零
毫无疑问
假如我是logical的话
那就是什么
长度为8的一个什么
一个逻辑向量
二者要一致的话
毫无疑问它的默认值多少
都是FALSE对吧
都是FALSE相应为0
这创建向量
假如我知道这个类别和长度
它可以调用这么一些函数
来实现它
在我们实际做数据分析的过程中
还会涉及到另外一类创建向量的过程
就是什么
创建一些有规则的序列
比如说等差数列
创建等差数列的话
可以通过seq()这个函数
它可以接受这么一个参数
比如from=1 to=20
就从1到20
这个数就不超过20
by的话表什么
步长等于2
这个数列第一个元素是1
第二个元素多少
1+2
第三个元素呢 就是1+2+2
就是1-3-5-7-9 一直到多少
一直到19
但是不能是21
为什么
因为已经超过它(20)了
不超过这个上面这个这个房顶
to就相当于天花板
不超过它就可以
然后我们再看这个seq from 20 to 1
我们一看这好像仿佛是什么正好转过来了
前面是1-3-5-7-9-10一直到19
然后后面仿佛就直接转过来
从后往前数
但其实不是
大家注意了
它正好就多少 20-18-16
一直到6-4-2
前面这个是什么
是一个奇数序列
然后后面这个是一个偶数序列
为什么
因为它起始点
大家注意起始点
然后它不超过一个什么
下面一个下边界
对不对
这是一个我们那个通过seq
这么一个函数来创建那个等差数列的过程
当seq的话还可以接受
除了这个from to之外
还有另外一种方式
你可以设定这个by
设定这个步长也可以设置什么
也可以设定这个整个数列的长度
比如说from 1 to20
那就是第一个点是1
最后不超过20
小于等于20
那这个长度为10的话表示什么
总共这个数列总共有10个数
10个数相当于什么
相当于10个端点
对吧
那这个时候我们就把
将它整个分成了九份了
分成九份
毫无疑问这个时候步长是多少呢
就是20-1
19÷9
应该就是二点一几左右
对吧
就所以第一个数是1
第二个数是3.1
第三个是5.2等等
对吧
这是seq
接受的不同的参数
它生成序列的这个过程
当然假如我这个步长为1的话
可以用通过这么一个简单的方式来写
就是1:10
就表示from
某个值to某个值
当然这个步长为1
即可能是1也可能是-1
就比如说1到10的话
毫无疑问什么
1-2-3-4-5-6-7-8-9-10
假如我这样写的话
π到1的话就是3.14到2.14
然后1.14
当然后面再不能写了
为什么
已经超过这个1这个边界了
就不能再小于这个1
我们看下面这个代码
1:10就是1到10减1的话
它结果多少
注意一下运算符的优先级
其实这个冒号它这个优先级要高一点
所以它是先执行这边这个这部分代码
1-2-3-4-5-6-7-8-9-10
那减掉1的话
毫无疑问是个向量化的操作
对吧
就是
1-2-3-4-5-6-7-8-9-10
都减掉1你那就变成了什么
0-1-2-3-4-5-6-7-8-9
长度还是为10
但假如我现在换一种方法
比如说我现在想这样写
1:(10-1)
这个时候的话毫无疑问应该是1到9
应该10-1的话应该先进
先进行这个运算
先进行那就是1到9
长度就为9的一个什么
一个等差数列了
当然我们在
R编代码的时候
其实不需要记
哪些操作符
它的运算级高一点
这个时候其实我们只要用这个小括号
来代表就可以了
用通过使用这个小括号
我们基本上就可以把这个运算
运算优先级这个问题给解决掉
前面是这个规则序列的
我们再看那些随机序列的
随机序列当然可以生成一些随机数
比如说我生成一个服从正态分布的
正态分布
rnorm(10)
这个时候就生成什么
服从正态分布的随机数
总共生成十个
对吧
这是一种方式
当然我们用的
非常多的另外一种随机数是什么
就是这个sample()这个函数
sample()这个函数
比如说我现在交给一个
一个N比如说10交给它
sample(10)的话表示什么
就是1-2-3-4-5-6-7-8-9-10
打乱次序
当然比如说我现在假如交给这个
b u p t a x b
这么一个单个的字符组成了一个向量
然后交给这个sample函数的话
它同样什么
同样也会打乱次序
当然因为它是随机生成的
所以同学们自己在写这代码的时候
运行这个代码的时候
可能跟我的结果是不一样的
跟我的结果不一样
因为它每次随机的结果都不一样
假如我想到随机的结果一样的话
可以怎么样
set.seed()
就是设定随机数种子
一旦设定完之后
接下来这个
涉及到这个产生随机数的
相应的代码的序列
它的结果都应该是一样
也就是说假如你要发论文
假如你要让别人复现你的结果的话
一般来讲要注意一下设定随机数种子
比如说我们现在在sample(10)的话
你先来一个set.seed(2012)
然后sample(10)那毫无疑问
这个结果什么
每次结果应该都是一样的
包括下面这个
因为你这个前面有一个设的点
set.seed(2012)
先执行这个在执行这个
那包括下面这个应该结果也是完全一样
结果也是完全一样的
一旦设定随机数种子之后
接下来有几个
随机数
生成的过程
那它每一次生产结果应该都是一样的
我们还可以这样
比如说我前面通过那个sample
都是通过什么
都是无放回的抽样
sample的还可以做有放回的抽样
比如从1到100里面抽取100个数
就是从一百个数里面抽一百个数
这是有放回的抽样
什么叫有放回的抽样
就是replace设置为什么呢 TRUE
就可以了
这时候我们会发现什么
我们所抽取的结果
有放回抽取的结果
有一部分数据是重复的
然后有多少有
36.8%左右的数是抽不到的
假如抽了好多次之后
我们统计就会发现
从一百个数里面抽一百个
有很多数是抽不到的
这时候我们可以通过什么
比如我通过这个unique()
我把重复的去掉
然后再算一下不重复的数有多少个
目前我们这次抽到的是有62个
62个
就大约有36%左右数抽不到
像这种有放回的抽样
或者说我们后面的机器学习里面一些
重采样技术
其实都会用到的
就是后面这个sample()函数
大家注意一下
包括我们后面再讲
这个比如说做模型算法
做训练的时候
要将数据分为
训练集和测试集
其实一般也用到这个什么
用这个sample()这个函数
这是我们创建向量的几种最基本的方法
通过c() combime这个函数
将已有的一些具体取值变成什么
变成一个向量
然后通过这个seq()生成这个
等差数列
或者通过这个sample()
生成这个随机数列
一旦生成之后
我们看看如何来访问它的子集
访问向量子集的话一般是通过什么
方括号来实现的
大家注意一下
在R里面小括号一般代表什么
函数的调用过程
那方括号
一般就是取它的子集了
那个下标的过程
那大括号也是花括符是什么
一个代码块
代码块
好
要访问向量的子集
通过这个方括号来指定它
具体来讲有四种方法
第一种
通过1到n的正整数来指定它
也就说这个n
这里面的n是指什么
是指向量的长度
也就说你站在哪个位置
然后把你取出来
比如说我现在有一个yw
这么一个数值的向量
然后我方括号
语文后面接一个方括号
c(2, 5)
毫无疑问
这是第二个和第五个位置的元素
就是把这个什么90分以下的
我们怎么样
取出来了
取出来了
取完之后
我们可以看看他和90分究竟差多少
离优秀还差多远
就是分别差3分 分别差5分
yw[c(2, 5)] - 90
这也是一个向量化的运算
当然我们可以看看
比如说重新赋值的话
将这两个同学加六分的话
它得结果多少
这个时候就所有的同学都是什么
都是90分以上的
这是我们对于这个向量的
通过1到n的正整数来
选出某一些元素
大家注意一下
这里面和我们以前学过的可能有些区别了
比如你学C(语言)的时候
它的下标多少
从0开始到n-1
那个时候表什么叫偏移
偏移量
但我们这边是什么
你站在第几位
第一位第二位一直到第n位
将相应位置的元素取出来就可以
我们再看看
假如我这个yw后面接了一个方括号
然后怎么样
我将mean
这个结果毫无疑问就应该是多少
92.17
对吧
92.17
然后我将那个平均值
92.17赋给它的时候
你发现什么
长度为6的yw这个向量
每一个值都变成什么
都变成92.17了
但假如我直接是mean(yw)
然后直接赋给yw的话
大家一看这是什么
这是重新赋值
但因为后面这个是长度为1的向量
那毫无疑问你得结果就多少
就是92.17
所以大家注意这个区别
就是你后面接了方括号的话表示什么
每一个元素
都被赋值为mean(yw)
否则的话
只要把yw这个向量(变量)
重新改写
重新改写成什么
长度为1的什么
一个向量
好
我们再看一下
比如说我现在有一个字符向量
周黎 汤海明 舒江辉
字符的向量
那这个时候我可以什么
c(1,3,2,3)
它表什么
先叫第一个同学
周黎
再叫舒江辉
再叫汤海明
又叫舒江辉
把这同学点名 点名 点名 再点名
我们发现了
1 3 2 3
这个时候我取下标的时候
它可以什么
顺序可以不一致
我先叫第一个
然后再叫第三个
叫完第三个再叫第二个
对吧
同时我一个什么
我还可以重复
就叫完第三个之后
完了再叫一次
对吧
所以大家注意了
我们所谓的子集
其实它的下标是可以重复的
也就是说我取出来的子集可能比它什么
比它原始的这个向量还要长
这就第一种向量的下标那个取的方法
通过1到n的正整数来取
我们再看第二种
第二种我采用了什么
负整数
负整数的话相当于反向选出的过程
就我丢弃掉某些元素
某些位置的元素
比如说yw
还是刚才这个六位同学的成绩
我们将第二个和第五个同学
因为他是90分以下的
我丢弃掉它
不是优秀的先不要
我只是取出来
另外四个为优秀同学的成绩
这个时候怎么办
我应该减号就可以了
-c(2,5)
或者说c(-2,-5)
都可以
当然假如目的是想找出那些
就是想选出那些成绩不是优秀的同学的话
我们最好这样写
哪一些下标 (注意:写代码时慎用which)
就是哪些同学语文成绩小于90
第二个和第五个
我把下标求出来
把它下标取完之后怎么样
我直接把这个下标交给谁
放到方括号里面来
这种写代码的方式基本就避免了硬代码
所谓硬代码就是你本来应该是什么有灵活
有可能变的地方
你把它写死了
比如说我们这边直接写这个c(-2,-5)的话
那假如下一次我这个数据量增加了之后
毫无疑问它可能就不是第二个和第五个了
可能还有什么
2 5 16 17可能都是那个小于90的
那这时候你的代码也得重新改
那毫无疑问你的维护量是很大的
我们为了避免这个硬代码的话
直接怎么样
通过这种方式来写就可以了
可以增加我们代码的可维护性
这是我们的第二种方法
采用这个负整数
咱们再看第三种方法
逻辑下标
同样我们说 比如说有这个
六个同学的姓名
这个字符向量姓名
还有他的语文成绩
现在我们想取出来为
小于90分的同学的语文成绩
把那个小于90分的部分取出来那怎么样
yw < 90
这是一个逻辑下标
因为它长度为几
和这个yw的长度
yw这个数值向量长度应该是一样的
长度也还是为6
然后yw < 90的话
第2个和第5个
这个逻辑向量
它的相应的位置的元素是什么
取值为TRUE
那我就把这第2个和第5个位置的
这个语文成绩取出来了
好
姓名也是一样
比如说究竟哪些同学他的语文成绩是小于90
是汤海明和祁强
汤海明和祁强
那这个时候我们就要考虑了
R究竟是如何智能地识别出来
这个语文是小于90分的同学
它相应的姓名是多少
这时候它怎么智能识别出来的
对吧
仿佛这个R好像特别聪明
对不对
但其实我想说的什么
这里面其实没有任何所谓的识别的过程
它只是一套规则而已
这套规则是什么
咱们看一下
当我这里面 xm[yw < 90] 的时候
你不用管它这个里面的表达式是什么样的
我不管它表达式什么样
表达式可以很简单也很复杂
可以是 yw < 90
也可以是x > 7
等等都可以
我们唯一要求是什么
里面这个逻辑向量
最后这个表达式
它最后返回的长度和我这个
和xm这个
向量的长度应该是一样的
就比如说xm这个向量
现在长度为6
然后里面这个
里面这个逻辑表达式
它返回的长度也为6的一个逻辑向量就可以
注意了
我们所谓逻辑下标
要求是你和我这个什么
和这个姓名xm
这个逻辑向量和我这个姓名xm
本身这个向量的长度应该是一致的
然后逻辑下标它是怎么产生作用的
它为TRUE的部分
为TRUE的部分我都选出来
其它部分就舍弃掉它
对吧
那相当于我只取的什么
汤海明和祁强
所以毫无疑问
这里面没有所谓什么智能识别的过程
它只是一套规则而已
就是一套对应规则
为TRUE的部分取出来
否则的话舍弃掉的
这第三种逻辑下标
这块大家要多花点时间来看
因为第一次接触的时候
逻辑下标相对比较复杂一点
咱们再看最后一种
就是通过这个元素的名称来访问相应的子集
比如说我们现在有xm 有yw
有这么两个向量
现在我可以将什么
因为它每一个 比如周黎的语文是94
汤海明的语文是87
那好
其实我可以什么
我可以将这个姓名
这些姓名
将什么
将它赋给后面这个语文成绩
也就是说对于这个yw这个数值向量来讲
它的每一个元素给它取一个名字
怎么取names(yw)
具体取值就是什么
前面那个姓名
好 一旦取完名之后
我们看一下yw
yw这个向量
你发现毫无疑问这个数值向量还在
但是每个数值上面
数值向量(的元素)上面都有顶帽子
都一个标签
对吧
就是有
周黎 汤海明 舒江辉 翁柯 祁强等等
一旦有姓名的话
那这个时候我要再调用
我来取它的子集的话
我就直接用什么
直接用它的名称就可以了
比如说c()
汤海明 祁强
毫无疑问就把汤海明祁强
对吧
这两个元素取出来了
我们得结果就汤海明87分
祁强85分
这就是向量(下标)的最后一种
通过元素的名称来访问
相应子集
以上就我们四种最基本的方法
第一种 1到n的正整数
第二种 负整数反向选出
第三种通过逻辑值
和它等长那个逻辑向量为TRUE的部分
把它选出来
最后一种就我们刚才讲到的
通过这个名称来访问的
讲完这个向量的子集的访问之后
我们来看一下向量的一些最基本的操作
比如说我们对象进行排序
首先我们定义一个向量
一个数值向量
这个时候的数值向量
我们每一个数值向量
我们都给它取了个名字
就每个元素我都取了个名称
就是2016年
我们北京某些高校的一些录取的分数线
比如说中国科学院大学
它的分数线是671
中央民族大学625
北京大学678
它的本质上是 大家注意了
本质上这个分数线是一个什么
是一个数值向量
是671 625 678 670 680等等
无非是这个数值向量
它每一个元素都有一个名称
都有顶帽子都有个标签
对吧
好
假如我要对它进行排序的话
比如说分数线从低到高怎么排
sort
调用sort()这个数的这个函数就可以了
目前这个学校里面
比如北京化工大学620
北京林业大学621
中央民族大学625等等
好
这是一个sort()的这个函数
可以通过
通过它来进行一个排序
默认的话是从低到高排序
假如你要从高到低排序怎么办
设置一个参数
decreasing
设置为TRUE就可以decreasing = TRUE
除了sort()这个数的这个函数之外
我们在排序的时候还有另外一个函数
非常重要
是什么
order()
这个函数和我们前面这个sort()的函数
区别比较大
order()它指什么意思
大家看一下
我这个分数线还是一样的
还是没变
还是刚的这个数值向量
那好
我一旦将它这个分数线fen_shu_xian
交给这个order()这个函数的话
并且是从高到低排序
你发现它取值多少
5 3 1 4 9 6 7 10 2 11 8
这什么意思
其实是一些下标
比如说第五个
大家看一下
1 2 3 4 5
毫无疑问
第五个是清华大学680
它最高的
因为从高到低排序嘛
然后下一个是什么
第三个 1 2 3
北大排其次
对吧
678分
然后所以它就是
5 3 1 4 9 6 7 10 2 11 8
排最低的是8
毫无疑问就是化工大学这一块
这个时候我们发现order的
它其实得到的是一些什么
是一些下标
按照顺序的一个下标
那好
其实我们可以
和前面我们讲到的向量的
1到n的这个正整数这种方法结合起来
我可以把这个下标直接交给什么
交给这个fen_shu_xian
其实我们就得到了什么
sort()一样的结果
比如说order
交给它之后
并且也是decreasing的话
毫无疑问它结果就是
5 3 1 4 9 6 7 10 2 11 8
然后就把什么
清华北大等等等就做好排序了
就做好一个从高到低的排序
当然这是一个按照这个数值取值大小进行排序
好像另外一种我们用的比较多的
就比如说逆序
就倒过来
比如说语文是
是这么
94 87 92 91 85 92
我现在倒过来读的话
倒过来看
就是
92 85 91 92
那这时候用的什么
rev()因为这个函数
假如我想取
这个向量的最后一个元素
我一数
总有六个
那毫无疑问你可以怎么样
语文
方括号里面取六就可以
但是这还是一个硬代码
这个位置的元素
这个下标可能是会变的
未来可能会变
所以我们不能把它写死
这个时候一旦写死之后
后面代码也是很难维护的
我们可以通过下面这种方式来写
比如说我求出它的长度
长度为N的话
毫无疑问 yw[n]
这应该就是一个相对比较好维护的代码
当然我们推荐是什么
通过这个tail这个函数
tail()这个函数
这是尾部
这个函数
其实我们已经用了好几次了
tail(yw, n = 1)
这个时候就是取出了什么
取出了我最后一个元素
假如我要看倒数
92 85 91
倒数三个数值的话怎么取
其实我可以怎么样
tail
取yw的最后三个元素
91 85 92
然后再怎么样
rev()
这个时候就把那个最后三个元素倒过来
就得到了
这我们下面那个逆序排列
前面我们对这个向量的创建
子集的访问以及一些最基本的操作
比如排序
做一个简要的讲解
但前面这些知识点其实都是什么
都是立足于计算机科学的
因为我们一旦说向量的时候
毫无疑问还在另外一个视角是什么
数学的视角
我们来看一下
我们现在比如说我定义这么几个向量
首先是原点p0
c(x=0, y=0)
毫无疑问这也是一个带名称那个向量
它其实是长度为2的一个数值向量
x = 0 y = 0
第一个元素的名称叫x 第二个元素名称叫y
然后p1
是 c(x = 1, y = 2)
就相当于c(1, 2)
那p2是x取值为2
y的取值为1
假如我们现在把这个向量
映射到我这个平面里面来
映射到几何空间里面去的话
就会发现p0毫无疑问就是原点
p0就是原点
然后 p1=c(1,2)
p2=c(2, 1)
我们看一看这个时候向量的求和
比如说 p1 + p2
它就相当于什么
相应位置的元素分别相加
这也得到我们p3
得到p3
那大家看一下
其实这里面我们一旦映射完之后
其实你发现这里面
平行四边形法则
是还是适用的
就将这个什么
p1移到这边来
起点移到这边来之后
毫无疑问这个终点就是什么 就是p3
对吧
就是p3
同样
我们对这个数乘也是一样的
就比如说
对这个p3乘1.5的话
那就相当于x乘1.5
y也乘1.5
这是变成多少
变成p4了
所以我们这里面的
c() combine的结果
这个向量其实就是我们数学里面的向量
不要把它当成两张皮
这里面什么
求和也好
数乘也好
其实都是完全适用
完全适用
咱们再来看一些操作
比如说我要求它投影向量
投影向量
就是p1在p2上的投影向量
这个时候怎么求
我们根据这个公式来求
根据这个公式
就p1和p2的什么
内积
然后p2的长度平方再乘以什么
再乘p2
也就内积的话很容易求
sum(p1 * p2)
p1乘以p2的话相当于什么
这一个向量化的运算
就是p1的相应位置的元素
乘以p2的相应位置的元素
然后怎么样
sum相加
毫无疑问就是什么求内积
然后下面这个
就是p2乘以p2再sum()
最后再乘一个p2
这个时候就求到什么
p1在p2上面的什么
投影向量
就投影向量
然后我们再看一下
看一个内积
内积我们刚才已经讲了
其实内积的话在代码实现方面非常简单
要求p1和p2的内积的话
就p1乘以p2再sum()就可以
这个内积就非常简单
那为什么
定义这么一个奇奇怪怪的一个运算法则
为了揭示它的物理上的含义
或者说它实际的含义是什么
我们画了一个图
大家看一下
这个时候我其实有一个什么
有一个向量
这相当相当于一个比如说W
一个单位向量
那W^T乘以X
就是这个向量的内积
向量
其实这个平面里面每一个点都对应一个向量
对不对
这个平面里面每一个点都是对应的一个向量
那好
每一个点和我这个W 和我这个向量的内积
我把它映射成什么
相应这个点的颜色
毫无疑问
和这个向量垂直的
它的什么
它的内积都是为零的
也就是为白色
再往这边走
往下走
在同一个方向上走得越来越远的
越远的话它颜色越深
对吧
越远颜色越深
表示什么
内积越大
对吧
这时候就蓝色就越来越深了
反方向上走得越来越远
怎么样
颜色也越来越深
而且负的值
它绝对值也越来越大
对吧
大家再看一下
跟我这条白的直线平行的
往这边走
往这边走
都是什么
其实颜色都是一样的
表明什么
即便我这里面
这个向量
它其实长度不一样
对吧
长度不一样
但是和我这个向量 和我这个目标向量
它的内积其实是什么
其实是完全一样
其实完全一样
这代表什么意思
所谓的内积
其实我们通过这个图看得出来
当跟这个向量本身是垂直的话
毫无疑问内积为零
为什么
投影其实就为零
你在我身上投影的长度就为零
是不是
假如你跟我同心同向的话
你跟我同心同向越强
你在我投影
这个长度越长
那证明什么
证明我们的内积就越大
所以其实所谓的内积
它物理上的含义是什么
就是同心同向性
你在我身上投影有多强
这个投影再乘一个系数
其实就是什么
其实就是内积
其实就是内积
我们其实可以再做一个动画
看一下
比如说我这个单位下面我这个目标向量
其实我一直在转的时候
你发现什么
我们这是顺时针转的
那个一个表的一个针
指针一样
对吧
你就发现什么
凡是跟它垂直的都是一条什么
都是一条白线
然后跟它同向性越强的怎么样
内积越大
然后反向
越强的其实什么
内积也应该说越小绝对值越大
对吧
通过这么一个简单的一个图形
我们可以看得出来
所谓的内积它可以用来表示相似性
可以用来表示同心同向性
当然为了进一步说明这个问题
我们可以再写一段代码
比如说 set.seed(2012)
这个seed的里面具体取值其实没什么讲究
你设置seed的等于1也可以
我们这设为2012
是因为我们这个课
在北邮是2012年开的
所以我就有的时候就直接写了
写成2012了
然后为了复现后面代码
先生成两个随机数的序列
随机的向量
都是服从正态分布的
x是一个长度为100的一个
服从正态分布的随机数列
y也是一样
也是长度为100的随机数列
现在我求二者的内积
x乘以y之后再怎么样
再加起来
它内积多少
-11.13
是吧
那好
现在我将什么
我将x sort()一下
然后将y也sort()一下
这时候都是什么
都是从低到高进行排序
这个时候同心同向性最强是吧
然后它结果多少
128.35
对吧
好
假如我反向的话
比如前面是从低到高排序
后面是decreasing等于TRUE的话
从高到低排序
那这时候是多少
这时候的内积是最小的
-127
通过这些代码也可以看得出来
所谓的内积确实表示这个同心同向性
粗略的讲完了
直观来讲的话
就是比较形象的说法
它其实有一个同心同向性
好
以上我们就从这个计算机
和这个数学两个角度
看了一下我们R里面这个向量
相应的一些操作一些计算
本次课到此结束
谢谢大家
-第1章 气象万千、数以等观
--第1章 作业
-第2章 所谓学习、归类而已
--第2章 作业
-第3章 格言联璧话学习
--第3章 作业
-第4章 源于数学、归于工程
--第4章 作业
-讨论题
-第5章 工欲善其事、必先利其器
--第5章 作业
-第6章 基础编程——用别人的包和函数讲述自己的故事
--6.1 编程环境
--6.4 控制流
--第6章 作业
-第7章 数据对象——面向数据对象学习R语言
--第7章 作业
-第8章 人人都爱tidyverse
--第8章 作业
-第9章 最美不过数据框
--第9章 作业
-第10章 观数以形
--第10章 作业
-第11章 相随相伴、谓之关联
--11.1 导引
--第11章 作业
-第12章 既是世间法、自当有分别
--12.1 导引
--第12章 作业
-第13章 方以类聚、物以群分
--13.1 导引
--第13章 作业
-第14章 庐山烟雨浙江潮
--第14章 作业