当前课程知识点:R语言数据分析 > 中部:执具 > 第7章 数据对象——面向数据对象学习R语言 > 7.6 列表与数据框(II)
大家好
欢迎来到《R语言数据分析》课程
咱们今天继续和大家交流
列表与数据框的相关内容
还是回到我们R里面这个数据对象地图
在R里面我们前面讲到了
重点掌握的数据对象
总共有三组六类
在前面课程里面已经简单的和大家交流了一下
前五种
今天我们进入到最后一种
也是最核心的一种
我们可以看得出来
最核心的部分在哪
在这个右下角
也就是我们今天讲的数据框
可以毫不夸张的讲
我们R语言
假如我们通过R语言来做数据分析的话
我们大部分时间都是什么
都是在把既有的数据转换成(用于建模的)数据框
我们都知道其实做数据分析的时候
数据预处理应该花的时间是占绝大部分的
后面做建模做评估
其实相对时间还是少一点儿
对我们R语言的数据分析人员而言
往往来讲
我们无论我们之前拿到数据是什么类型
最后要做数据探索
做数据建模的话
大部分情况之下
我们都要把它转换成什么
转化成数据框
比如说我们后面要做ggplot2绘图
这个时候我要把我原来的数据转换成数据框
比如说我要后面做分类与回归树的建模
比如说要做聚类等等
其实我在建模之前
我需要准备好的数据以哪种方式存在
还是数据框的方式存在
(无论)原始的数据是哪种类型存在
是关系表示我们互联网爬取的数据
最后我们要做这个数据建模的时候
基本都得转化成这种二维的
类似于关系表的结构
在R里面
其实就是什么
就是数据框
我们说数据框应该是最美好的数据对象
在R语言里面六种数据对象里面
用得最多的也是最美好的
我们后面专门有一个章节讲什么
讲《最美不过数据框》
我们后面会结合这个算法建模的过程
来讲这个数据框
今天我们先讲一讲数据框的最基本的操作
讲到数据框最基本上操作的话
有一句话是需要注意的
形式上是矩阵 本质上是列表
我们在后面相应的数据操作里面都会
反反复复提到这个概念
形式上是矩阵
本质上是列表
所谓形式上是矩阵什么意思
其实它和这个数据框的所存在的方式和我们
一般看到的比如数据库里面的这个关系表
或者说我们看到的excel表里面
这种二维的结构是差不多的
每一列都是什么
都是一个变量
都是一个属性
或者说是一个特征
也就是说数据空间的一个维度
然后每一行
是一个观测
对某个对象的一个观测
它是观测值 是记录
也可以说它是
是n维数据空间里面的一个点
这里面我们重点要说一下这个行和列的概念
就是我们以前在理解
比如说在学关系数据库的时候
或者在看这个excel表的时候
它一行就是一行
一列就是一列
但是假如我们一旦开始做数据分析的时候
虽然我这个数据框还是以这种方式存在
但是对这个行和列的理解
我们得更深一步 得更进一步
所以我们这边就把这个列和行
我们单拎出来再讲一下
所谓的列它其实就是
就是属性
就是观测对象的属性
比如说有姓名有性别
有不同科目的成绩
这个都属于属性
一般来讲
我们刚开始拿到的所观测到的都是
这个不同观测对象的属性
它本身的一个记录
当然我们也有另外一个相关的概念的特征
假如从特征工程的角度讲
就是由这个属性空间变换成
特征空间的话
(特征)就是经过加工的一个属性
当然在很多情情况之下
我们对于属性和特征也不做区分
相应的这个列其实在数据库里面
它就是字段
我们在统计上讲它就是一个变量
但我们更希望理解成
一个维度
它是数据空间的一个维度
所谓的行是什么呢
它就是属性的向量
或者说是一个特征向量
它是一个实例 是一个样例
是一个观测 是一个元组
是一个记录 等等
我们在不同的数据分析
数据挖掘机器学习的书里面会看到不同的概念
但你发现它其实基本都可以对应到
我们数据框里面的行和列这里面来
这个行也是一样
重点掌握是要把它视为数据空间的一个数据点
这个时候其实可以行和列就结合起来了
因为列张成了(数据空间)
列是不同的维度
然后行
就相当于是不同维度张成的数据空间的每一个点
一行就是一个数据点
我们来看一下
这其实就是我们
在后续的课程里面会用到一份数据
就是某高中的一个成绩表的数据
不同的学生的名称
然后有班级有性别
语文 数学 外语 等等等等
九门课的一个成绩
还有他最后选择文理分科的一个情况
假如我们的问题是
根据这个性别
根据他的各科的成绩来判断
他倾向于选择文科的理科的话
那好
这个时候我们就需要注意了
其实前面的这个性别
包括一直到后面的这个九门课的成绩
这个到前面十列就张成什么
10维的数据空间
然后每一行或者说每一个同学
他相应的这个取值
就是这个10维数据空间的每一个点
然后后面这个文理分科是
这个数据空间里面相应的数据点
每个数据点上面的它头上的标签
所以假如我们一旦
从这个角度来理解这个数据框的话
后面的
在做分类 在做聚类 在做建模的时候
我们就很自然能过渡过去了
也就整个这个在我们脑海里面
也能把它想象得相对比较直观 比较形象
好 这是我们关于这个数据框的行和列
我们需要加深它的理解
咱们再看看在R里面
具体如何来创建这个数据框
比如说我们现在有这个六个同学的
姓名xm 性别xb
语文yw 数学sx 外语wy
这么总共[五]个属性
我们可以看得出来
xm是一个字符向量
然后xb是一个因子
然后yw sx wy
它分别是三门课的得分
毫无疑问
我们前面在讲这个矩阵的时候讲到
假如我这个要将yw sx wy这个同质
并且等长的这个数据把它合成一个整体的话
我们可以通过矩阵来把它存储
但是因为我们这边既有这几门课的成绩
又有xm xb
它是类型是不一样的
这时候怎么办
这时候还要把它捏成一个整体的话
就只能采用data.frame
用这个数据框的方式来存储
它是非同质的类型不一样
好 这个创建的方式我们前面讲了
data.frame这个数据框它本质上列表
所以它和列表创建的方式是完全一样的
比如说这个第一个组成部分
就是第一列是xm
第二列是xb
第三列是yw
第四列sx
第五列怎么样 是wy
通过这个data.frame这个函数调用完之后怎么样
再通过赋值的方式就创建了一个cjb
这么一个数据框了
创建完这个数据框之后
我们来看一看这个数据框最基本的操作
因为数据框我们刚才讲它本质上是列表
所以假如我要访问这个数据框的子集
访问它的某一列的话
其实它作为这个列表来讲
它每个组成部分就是相应的列
注意不是它相应的行
而是相应的列
假如我要访问它的那个不同的列的话
可以怎么访问
就我们前面讲的这个列表里面三种方式
对这个数据框来讲都是适用
采用这个美元符号$
采用这个双重的方括号里面放这个正整数
或者放在名称都可以
但一般来讲后面两种
在这个数据框里面虽然是合法的
可以这样使用
但是我们一般用得相对比较少
在具体使用这个数据框的时候
假如要访问它的子集
要么是采用$这个符号
要么采用这个矩阵的方式来进行操作
假如要用方括号的话
一般不用这个双重方括号
一般用单重的 单层方括号就可以
我们刚才讲到了它形式上是矩阵
本质上的列表
所以你可以用列表的方式来访问它
也可以通过矩阵的方式来访问它
所谓矩阵的方式 毫无疑问就是什么
方括号里面通过逗号隔开它的行和列
逗号前面是行 逗号的后面的是列
咱们看一下
比如说我要取出第一行
这个时候就是xm xb yw sx wy
周黎 女 94分 82分 96分
这一看 它其实就是我们拿到的第一行
当然这个第一行
毫无疑问它本质上还是个列表
或者说它还是一个数据框
假如我取第一列的话
毫无疑问它就是一个字符向量的
假如取第二列就是一个因子
第三列是一个数值向量
当然我们可以取同时取某些行某些列
比如说第一行第三行
它第一个和第三个同学
他的姓名和数学成绩
第一个和第三个同学
xm和sx成绩
周黎 舒江辉 82 79
当然也可以通过其他一些方式
凡是我们矩阵里面
用到的这种那个取下标的方式
对于这个数据框来讲都是适用的
比如说
对这个行和列来讲都可以通过四种方式
第一是它这个正整数
第二种是负整数
正整数是选定某些行某些列
然后负整数
是选出某些行某些列
那第三种是逻辑向量
为TRUE的部分选入
为FALSE的部分舍弃掉
然后第四种
就是这个名称
这四种都是可以的
这就是我们这个数据框里面
取这个子集的一个最基本的方式
我们来看看 除了这个访问这个数据框之外
假如我对其中的一些那个组成部分
进行修改的话
怎么修改
我们前面讲这个列表
假如我要增加一个组成部分的话
我直接赋值就可以
比如说我要增加一列政治课 zz 的成绩
我将一个数值向量
只要赋给这个cjb$zz就可以了
政治就可以了
假如我想把这个政治删掉
将这个NULL赋给它
这就删除某一列了
当然这是作为列表的方式
我们这样操作的
我们前面讲到它是形式上的矩阵
也可以按照矩阵的方式来操作
比如说我可以将成绩表再和一个新的一列
进行 cbind()
我将它并排放在一起
捏成一个整体
就是一个新的
包含这个历史这一列的一个成绩表
这就是我们假如要对数据框增加或者删除
某些列的话
可以通过这些方式来进行
以上就是我们关于这个数据框的一些
最基本的操作
访问它的子集
然后对它的一些组成部分进行修改
一般来讲
我们在做具体数据分析项目的时候
很少说是将我的数据直接在代码里面敲进去
更多的是读取已有采集到的数据
咱们看怎么操作的
比如说我们现在这个课程里面
需要用到这个成绩表的数据
我们是已经托管到这个github里面
我们先将这个网址先记下来
然后怎么样
我通过这个read.csv()这个函数
直接从远程读取这个数据
读到哪来
读到我这个内存里面来
放到cjb这个变量里面去
读完之后我们View()一下
就发现
它就一下就读到我们这个RStudio里面来了
读到RStudio里面来
这里面需要补充说明一下
我们用的是csv格式进行存储
大家可能觉得这个csv格式不是那么高大上
但实际上
我们绝大部分的数据交互
都是通过纯文本的方式进行的
一般来讲
我们拿了一份实际的数据的时候
我们得看一看这个数据长什么样子
比如说我在控制台里面
我一次一屏显示不下成绩表里面所有记录
我们这份数据总共有700多行
一次性显示不下的话怎么办
我可以先调用head()这个函数
先看看前几行
默认的话它是前6行
当然也可以调这个tail()
最后几行
当然这个n也可以设置
默认也是6行
也是最后6行
但你可以设置一下
比如n=3
显示最后三行
我们通过这个head()和这个tail()函数
我们可以看出因为先看一看其中的一部分
就是最前面的几行记录什么样的
最后面的几行记录是什么样
除了这个看实际的记录之外
我们需要重点说一下这个函数str()
str()这个函数它并不表示这个string的意思
它并不表示这个字符的意思
而表示structure
它是表示结构
我查看我这个数据的结构
比如说我们现在看这个成绩表这个结构的话
你发现它是一个data.frame
里面有总共多少行
有775行记录
然后有13个变量
也就是说它是个775乘以13
这么一个二维表的形式
接下来我们可以看得出来
它因为它是一个本质上是一个列表
所以还是用这个美元符号$来连接的
第一列
xm
第二列bj
xb yw sx wy 等等
我们可以看得出来
第一列来讲它是一个字符向量
然后像前面几个字符向量前面几个取值
列出来了
然后第二个bj 是一个整型
当然毫无疑问
这个时候我们需要做一个类型转换
我们读完之后发现bj应该
我们本质上应该将它存储为因子
包括这个xb也是
它虽然读取的时候是一个字符
其实我们最后应该把它转换成因子
通过这个str()这个函数可以看得出来
整个这个数据的结构
它有多少行有多少列
然后不同的列
它的那个具体的类型是
这个看得比较清楚
除了这个str()这个函数之外
我们还有另外一个函数也经常用
就是summary()
summary()什么意思
一看这个函数的话
顾名思义就是我对它进行
摘要 进行统计汇总
它对不同的类型有采取不同的方式来汇总它
比如说像那个字符型的
看看它总有多长
它的类型
班级我们刚才看到了
它是一个什么
默认的时候它是一个整型
所以它会把最小的最大值包括这个
第一分位数中位数
平均值第三分位数取出来
当然这些是没有意义的
我们后面要做一个类型转换
性别的话
因为它是字符型的话
它只是统计一下这个字符(向量)的长度
对于我们这个数值型(变量)来讲
比如说它取最小值 第一分位数 中位数 平均值
第三分位数 最大值
通过这一些值的显示
我们可以看得出来整个这个数据的分布情况
比如说语文成绩最低是0分
第一分位数是85分
中位数是88分
然后平均分也是87分
第三分位数91分
就是最高分是多少
96分
可以看得出来
这个700多个同学
语文成绩怎么样
相对是比较偏高
我们前面讲到了类似于这些那个班级也好
性别也好
我们其实是需要做一些处理的
我们后面再讲具体如何处理它
一旦我们将这个成绩表读进来之后
我们可以看一下它的一些最基本的属性
比如说看看names
通过names()函数
我们看看它每一列的名称
通过这个colnames列名
这两个其实是一样的
然后要查它有多少行
通过这个nrow()
多少列ncol()都可以
好 我们前面讲到这个对这个bj xb
包括后面我们讲的wlfk
其实都要做一个类型转换
怎么转换
做类型转换的时候
其实还是赋值
其实就是相当于对这一列进行修改
我们前面讲到了
在R里面要创建也好
要修改也好
其实都是
都是通过赋值的方式来进行的
一旦赋完值之后
我们重新再调用这个str这个函数
你发现这个时候bj xb就变成
就由之前的这个字符型的这个向量
就变成了因子了
同样我们要重新再来一次summary()
重新再来一次summary
我们再看看摘要的情况
这个时候我们需要说明一下
在做数据分析的时候
其实这个反反复复的过程是经常的
就并不是说我就是按部就班
第一步第二步第三步这样线性往前走
它觉得不是很多时候都需要迭代
它其实不是
很多时候都需要迭代
我们发现了这个bj xb有问题之后
要做重新类型转换
转换完之后我们也再次来个summary()
我们可以看一下和之前的结果
这上面这几行是之前的结果
然后一旦我做完这个类型转换之后
它就下面的结果了
这时候我们发现
班级性别作为因子来讲
它是怎么统计的
它就不是说仅仅统计它的长度了
而是什么
它不同的取值水平
性别比如说既可以是男也变成女
性别为男生有369个
为女生的406个
基本上男女是比较均衡的
但女生稍微多一点点
然后可以再看一下
不同的班级里面学生数量是多少
也就是说我们对因子来讲
它是计算它的不同的取值水平
分别在这里面取值有多少个
我们查看完了这些最基本的信息之后
我们比如说可以对这个成绩表
我可以按照总分进行排序
我们看怎么做
我先怎么样
我先将总分求出来
大家看有个非常熟悉的函数apply
对吧 apply
我们前面讲到apply的时候是在讲矩阵
我们讲了这个数据框
它其实形式上是矩阵本质上的列表
所以你可以把它当矩阵来处理
所以这个时候apply将成绩表的第4到第12行
也就是这九门课的成绩这一部分取出来
取完之后这是一个子集对不对
也是775乘以9的一个数据框
对这么一个二维的结构
我对它的按行进行应用一个函数
apply一个函数
应用这个sum
就表将它每一个行的总分求出来
就是每个同学的总分 九门课总分求出来
求出来之后怎么样
我赋给cjb$zcj
表示什么意思
我新增加了一列zcj
我可以对这个总成绩我可以调order这个函数
我取出来
比如说我按照这个从高到低的顺序
将它下标给取出来
一旦取完这个下标之后可以怎么样
我再将它放到方括号里面来
作为cjb的下标
这个时候的成绩表
就是按照这个总成绩
从高到低进行排序的一个成绩表了
我们看得出来
对这个成绩表这么一个数据框
假如进行排序的话
其实R里面其实非常简单
就通过这个order()的这个函数就可以实现它
前面我们讲了一下
这个数据框的一些最基本的操作
在实际数据分析项目里面
我们讲到绝大部分情况下要建模的话都是
基于这个数据框的
但是要建模的话
一般要将数据框分成训练集和测试集
那我们看看在R里面如何实现它
假如将这个数据集分为训练集和测试集的话
我们看这代码
首先第一行代码
set.seed
set.seed(2012)
这个时候就是设定一个随机数的种子
接下来第二行代码
我们取出来成绩表
它总共有多少条记录
总共有多少条记录
接下来
其实就是选出随机选出
这个训练集的下标的过程
咱们看看这个代码
sample() 调用这个函数
从1到我们这个记录是总共775行
从1到775这个等差数列里面
也就是原始的1-2-3-4-5-6-7-8-9-10-……
一直到775
这么一个序列 这个下标的序列
从那个下标系列里面选出多少
我们看一下百分之多少
百分之70
这个记录数乘以0.7
毫无疑问70%
这个floor
floor当然不是表示地板的意思
floor表示什么意思
它其实我们还有一个叫ceiling的函数
ceiling话就表示天花板就表示向上取整
然后floor表示地板就表示向下取整
那假如是四舍五入的话怎么办
round
这时候相当于什么
相当于775里面乘以0.7
500多条记录作为我的那个训练集
训练集的下标
当然我们的floor只是为了取整而已
向下取整
当然这个这种写法是相对逻辑比较清楚的
也可以简写一下
sample()这个函数前面接收775
后面是就775乘以0.7
你可以不用写1到775
直接写这个775就可以
就表示从这个1到775里面怎么来抽取
抽取多少个
抽取后面这个 百分之七十
抽取542个
这个时候其实也默认做了一个向下取整
这时候我们看得出来训练集的长度是542
当然这里我们稍微补充一下
为什么我们在做训练集和测试集划分的时候
训练集是选70%呢
也没有一个绝对的理由
一般来讲训练集是多一点
我们一般讲机器学习不是一个举一反三的过程
而是举三反一的过程
我们一般来讲就是三七开就可以
30%做测试集
70%做训练集
好 我们一旦拿到了这个训练集的下标
毫无疑问测试集下标什么样
我也从这个原始记录里面将这个训练集的下标
剔除掉 就是测试集的下标
当然也可以通过下面这种方式来做
就setdiff()
这表示什么意思呢
表示一个集合的操作
毫无疑问
我们看这个函数的名称setdiff
表示两个集合
比如说它接受两个参数
一个A一个B
比如说这是A这是B
那好这两个集合
前面这个参数是A
后面这个参数B的话
它返回结果就是在A里面
但是不在B里面它的元素
相当于这部分
当然对于我们这个问题来讲
它相对比较特殊
因为我这个A是全部的集合
然后B是其中一个训练集的集合
然后A减B的话相当这一部分
可能外面这一部分作为测试集
当然我们关于集合的其他操作
你可以用问号查这个帮助文档 ?setdiff
它会把集合的其他的一些操作
比如说并集交集相应的函数都给列出来
那这个时候我们通过调这个setdiff就得到
就得到什么
相应的测试集的下标也得到了
一旦得到下标之后
毫无疑问
我们可以通过下标的操作
取出相应的训练集相应的记录出来
我们看一下
我们这个训练集的记录
这个训练集怎么取
就是成绩表用这个我这个训练集的下标
测试集的话怎么办
有两种方式
一种是直接减掉
反选 反向选择
就将那个训练的相应的这个记录去掉了
另外一种方式
直接将那个测试集的下标交给它
这其实就完成了
我们这个训练集和测试集划分的过程
接下来就可以基于
这个上面这个训练集我进行训练
然后通过测试集来评估这个模型的指标了
当然需要提一下就是
下面这种方式
这种写法是错的
虽然看起来也非常直观
我先从这个记录里面选出70%做训练集
然后又从这里面选出30%做测试集
这种方式是错的 为什么呢
因为你随机抽取的时候
这两个抽取里面可能有一部分重叠的
我们一般来讲在划分训练集和测试集的时候
要求训练集和测试集它没有交集
交集为空集∅
当然我们在做具体数据分析项目的时候
我们为了理解这个
测试集和训练集的生成的过程
可以自己写这代码
但假如你在一些工业或者商业级的应用中
其实我们可以直接调用一些
比如说caret这些包里面的相应的
划分训练集测试集一些函数
这样的话就更加便捷点了
我们也不需要重复造这个轮子
以上就是我们关于数据框的最基本的内容
讲了一下数据框那个最基本的理念
尤其是对其中的行和列
我们做了一个相对比较详细的介绍
在此基础上
我们也将这个数据框如何创建
以及一些最基本的操作
如何来访问它
如何对其中的一些部分进行修改
包括我们如何查看的数据框的结构
以及我们结合这个算法建模
如何划分训练集和测试集
相关的内容作了一个简要介绍
以上就关于我们数据框的最基本的内容
本次课到此结束
谢谢
-第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章 作业