当前课程知识点:R语言数据分析 > 中部:执具 > 第7章 数据对象——面向数据对象学习R语言 > 7.3 矩阵与数组(I)
大家好
欢迎来到《R语言数据分析》课程
今天和大家一块交流一下
矩阵与数组的相关内容
咱们是先回到我们的R里面的
数据对象的地图
在R里面我们将需要重点掌握的数据对象
分成三组六类
在我们前面课程里面
对第一组向量因子进行了简要的交流
从今天开始
我们进入第二组
矩阵与数组的相关内容
通过前面课程我们了解到
就是对于单变量的观测值
无论是它是数值型的
还是我们类别变量
都可以通过向量或者因子进行存储
但是我们绝大部分情况之下
我们实际数据分析任务里面
它其实所观测到的都是对象多个属性
对于这种情况
我们一般来讲
就是通过矩阵或者数据框进行存储
假如我观测到的这些不同的属性
它是同质的 是同一种类型的
我们通过矩阵来进行存储
否则的话
我们通过后面我们要讲的
数据框进行存储
比如说我们现在有六个同学
它分别有语文 数学 外语这三门课的成绩
我们进行了记录
我们当然可以通过三个数值向量进行存储
但是这里边有一个不好的地方是
它不是一个整体
假如现在想要对这些成绩
根据同学的(姓名)拼音的顺序
来进行排序的话
你要对语文 数学 外语分别进行排序
显然是不方便的
我们很难对
数据进行进一步的处理
所以我们需要将它作为一个整体进行存储
这个时候就引入我们今天要讲的矩阵了
具体在R里面怎么实现
假如我想通过矩阵来存储
语文 数学 外语这三科成绩的话
这六个同学三科成绩
它总共应该是18个具体的分数
我将这18个具体的分数放到一个向量里面来
c()一下
然后交给matrix
交给它来创建我们一个
包含六个同学三门课的一个矩阵
我们这边看一下
还有另外一个参数
就是我把它分成三列
第一列是语文
第二列是数学
第三列是外语
这是第一列第二列第三列
大家注意一下
我们整个成绩总共是18个分数
它其实就是一个长度为18的一个数值向量
然后我真正在进行矩阵创建的时候
大家看一下它其实按列优先进行填充
先填充第一列 再填充第二列 再填充第三列
当然我在写的时候是按照
一个矩阵的方式来写的
但实际上它就是一个长度为18的一个数值向量
然后它是按列优先的方式进行填充
默认是这样的
这时候我们就完成了
矩阵的一个创建的一个工作
所以我们看得出来
无论是我们前面讲的向量因子
还是我们正在讲矩阵
它其实都是通过赋值的方式来进行创建的
创建完之后
我们可以对它的相应的一些属性
比如说它的列名
它的行名
分别改为yw sx wy
把这六个同学名字作为行名
我们View()一下
得到我们现在看到结果了
当然还有另外一种情况就是
我数据本来就是站着的
比如第一列
表示语文成绩
第二列表示数学
第三列表示外语成绩
毫无疑问
这里面其实还是
还是长度为18的一个元素
长度为18的一个数值向量
我应该创建的时候
就不再是按列进行优先填充了
应该是按行进行填充
先填充第一行
再填充第二行
再填充第三行 第四行 第五行 第六行
所以我们注意要设定一个参数是
对这种站着的数据
我设定一个参数叫 byrow=TRUE
它默认是FALSE
默认是按列进行优先填充的
但这种情况的话我们就按行
同样我们可以对它的列和
行名进行更改
和我们前面结果其实是一致
一旦完成矩阵创建之后
我们可以看一看
矩阵的一些最基本的属性
比如说
它的行名 它的列名 我们的分别取出来
通过colnames()
可以取它的列名
当然也可以直接通过names()也可以取出来
可以取它列名
还有就是取到行名row.names()
当点去掉也可以rownames()
也是另外一个函数
它的结果也是一样的
有多少行有多少列
我们这是一个6乘以3的一个矩阵
6 就是nrow()
行的行数
那列就是ncolumn
ncol() 一个缩写
当然也可以通过dim()
一次性把它的行数和列数直接取出来
这是我们创建完矩阵的一些最基本的属性
其实对于任何数据对象来讲
它最重要的操作是就访问它的子集
对我们矩阵来讲如何访问它的子集
其实也是通过我们
方括号来进行那个访问
在R里面我们有三种最基本的括符
有小括号 有中括号 有大括号
小括号()
一般通过小括号
来进行函数的调用
方括号[]用来访问它相应的下标
访问它的子集
那大括号呢 花括符{}
一般是一个代码块
和我们前面那个向量因子
它不一样的地方是
因为矩阵是二维的
所以
在方括号里面
需要通过逗号来分开行和列
逗号前面表示行
逗号的后面表示列
比如说我现在取第一行 周黎
他的语文数学外语成绩
那这时候我就逗号前面写1或者写周黎都可以
就我们前面讲的向量里面四种方式都可以
正整数 负整数或者逻辑向量
或者是它的具体的名称都可以
逗号前面表示行
逗号的后面就表示列了
比如说我现在逗号后面
我设1或者是yw
最后就把把第一列给选取出来了
当然我们也可以将行和列同时指定
比如说第一行第一列
这也相当于我们在矩阵里面的
Xij
i = 1
i=1 j=1
毫无疑问就是第一个元素
好 当然我们也可以设定多个
比如说我现在去同时选定周黎同学第一行的
sx和wy成绩
就将第一行的后两个元素取出来了
同样我们可以通过这种方式
得到前面一样的结果
就通过负整数 反向选出
就是说第一列不要它
和我们前面得到结果是完全一样
同学们可以试一下
比如说通过逻辑向量
也可以作为它相应的下标
逻辑向量必须和它的行数
或者它的列数相同
它的长度应该是相同的
然后为TRUE的部分选入
然后为FALSE的部分选出
这是我们访问矩阵
通过逗号的方式来访问它
有了这些访问矩阵的方式之后
其实我们也可以通过相应的下标操作
来很方便的对它的行和列进行排序
比如说
我现在想将
语文和数学
调换个位置怎么调换
那我觉得逗号后面里面写
下标的时候
c(2, 1, 3)
或者说c("sx", "yw", "wy")
将它(下标)顺序一调就可以了
这个时候就得到一个新的矩阵
就将sx和yw成绩这两列进行了一个调换
当然比如说这是列排序
我们也可以对行进行排序
比如说我想针对
数学成绩
按那个数学成绩的高低
来对整个矩阵进行排序
也是可以的
怎么做呢
需要用到order()这个函数
order()
order()这个函数
它我们前面讲了
它主要作用是
按照它的取值的大小将相应的下标取出来
比如说我们目前order()我针对ysw
矩阵里面的sx这一列的成绩
相当于就是这一列这一个数值向量
我作用order的话按照decreasing
按照从高到底的顺序排序的话
得到结果是2 5 4 1 6 3
也就是说第二个是排第一的
然后第五个排第二
然后是第四个 第一个 第六个 第三个
当然这里面有两个重复的
比如82 82
原来在前面还是排在前面
这个时候2 5 4 1 6 3
就是按照数学成绩从高到低的一个下标
我将下标交给矩阵
就放在一个逗号前面的话
那我整个矩阵就是
按照数学成绩从高到低进行重排序
按这个行
所有的行 所有的记录就重新排序了
这是我们对行列进行一个重新的一个排列
在我们具体在数据分析的一些情境里面
我们经常碰到一种情境是
我刚开始采集了一些数据对象的
相应的一些数据记录
观测对象
然后过段时间之后
我又采取了另外一些观察对象相应的数据记录
比如说我先拿到的是
这六个同学的yw sx wy三门课的成绩
第一个同学 第二个同学 第三 第四 第五 第六
然后过段时间之后
我又采集到另外两个同学的yw sx wy
也是叫穆伶俐 韦永杰
也是这三门课的成绩
我有了新的记录之后
这应该怎么样
我应把相应的记录合并在一起
把历史记录和新的记录合并在一起
这时候怎么合并呢
大家一看我这yw sx wy都是都是对着的
其实我只要像叠罗汉一样把它叠起来就可以
那怎么叠呢
我们通过R里面rbind
r代表row表示按行进行叠加
就是叠罗汉一样叠在一起
前面参数第一个参数是上面上半部分矩阵
第二个参数是下半部矩阵 叠在一起
当然除了这种情境
就是观测到新的记录之外
还有另外一种情景
我刚开始是观测到一部分的属性
比如yw sx wy的成绩我拿到了
过段时间之后
我拿到 ls 和 zz 成绩
比如另外两门科目的那个老师
把相应的成绩也拿过来了
那这时候我应该要把它的相应的记录合并在一起
比如说这是新的 zz 和 ls 的成绩
比如 zz 有八个同学
然后 ls 有八个同学的成绩
我要合并的话就不再是叠罗汉了
而是应该像比如说我们书柜里面的书一样
刚开始有三本书然后又有两本书
并排放在一起
那这时候用的应该用cbind()
c代表column
就表示按列进行排列 [合并]
这就我们在R里面最简单的两种
也是经常碰到的按行和按列进行
数据记录或者相应的属性的一个合并
新旧的一个历史记录合并的过程
当然同学们可能会说到
你这里面合并的时候
正好就是比如按列进行合并的话
就刚开始的这三门成绩和后面这两门课的成绩
它学生顺序都是一样的
这个时候才能直接cbind
那假如顺序不一样的话怎么办
就用到另外一些函数
比如说merge
或者是采用tidyverse包里面的join
其实我们在数据库里面涉及到一些表的连接
不管内连接 还是左连接右连接
其实都是在R里面都有实现
感兴趣同学可以看一看这相应的函数
这是我们关于矩阵合并的一些操作
我们再看看一旦合并完之后
得到一个新的一个矩阵
就包含yw sx wy zz ls
总共八个同学五门课的成绩
一旦拿矩阵之后
我们比如说作为一个老师来讲
他可能首先要想对每个同学总分我先求一下
这就是一个典型的分组操作
我把每个同学这五门课
每个同学它总分多少求出来
其实我们可以调用R里面一个函数叫rowSums()
你看按行进行求和
就是每一行就是一组
然后每一组向量我都求和sum()
当然除了对每个同学的成绩进行求和之外
还有可能另外一个情境是
就我对每一门课求个平均分
这时候怎么做
这时候我们要需要调用另外一个函数是
就是colMeans()
colMeans = column means
按列求平均分
这是两个常用的按行做一个操作
或者按列进行一个操作
当然前面这是调用不同的函数
在R里面其实一个通用的接口是apply
我们刚刚说了成绩表示我们刚才拿到了
八个同学8乘以5的一个矩阵
我针对这对cjb数据的每一行
我进行一个操作sum
把每一行的成绩求出来求和
然后后面比如我apply 针对cjb数据
它的每一列 我作用一个操作 作用一个函数
是mean 对每一列求平均分
所以我们看得出来apply的话
它接受三个参数
第一个是作用对象
第二个我是按行还是按列进行操作
当然目前我们讲的矩阵的话
它是二维的 要不按行 要不按列
假如我们后面再讲数组的话
apply第二个参数的话
要取3或者4以上了
那高维的了
那第三个参数就是它究竟要做哪个操作
sum mean
包括比如说我们求它的标准差
mean是表示一个集中的趋势
sd标准差是表示一个分散的程度
当然这些都是我们R里面已有的
已有的一些那个函数
我们也可以自定义一些函数
也来apply它
也是可以的
比如说
我们自定义一个变异系数
变异系数这么一个函数
它其实就是
标准差除以均值
也就是一个去量纲的一个分散的程度
同样可以apply对成绩表的每一列
求它的那个变异系数
这也是可以的
当然我们也可以将这一个函数体
直接交给apply
作为它的第三个参数也是可以
也就是采用匿名函数的方式也可以
同样能得到yw sx wy zz ls这五门课的
每门课的一个变异系数
前面我们讲的apply它其实代表一种
R里面数据处理的一种模式
它分三个步骤
split-apply-combine
前面其实我们已经提到了
就是先分组 然后对每一组进行某个操作
然后对操作结果进行combine合并在一起
比如说我们按行做sum操作完之后
将它每个同学的总分combine在一起
变成一个数值向量
就这么一种split-apply-combine数据处理模式
在我们后续的课程里面
无论是认识数据也好
还是后面我们做的一些其它一些数据处理操作
经常会套用这个模式
当然涉及到apply函数族
比如说目前我们讲的apply
或者后面有可能涉及到的
sapply
tapply
lapply 等等
就整个apply其实都是一个分组操作这一种动作
当然后面我们在讲tidyverse包里面的时候
也会涉及
也会涉及到我们相应的它的分组操作
分组做一些统计
先分组然后再summarize
做一些统计
前面我们讲了一下矩阵里面一些最基本的内容
矩阵的创建
矩阵一些下标的访问
以及矩阵的一些分组操作
进一步的内容
我们接下来课程继续讲解
本次课到此结束
谢谢大家
-第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章 作业