带你读《R数据科学实战:工具详解与案例分析》之二:数据清理工具
点击查看第一章 第2章 数据清理工具无论是人工还是传感器采集的数据,都或多或少地存在一些错误或者瑕疵。比如说,不同采样人员记录数据方式的不同会导致数据值重复或不准确,录入数据时的失误会导致数据输入错误,传感器断电会造成大段的数据默认,不同国家和地区对时间日期制式的不同标准等,各种各样的原因造成数据无法直接用来分析、可视化的情况非常普遍。一般来讲,在从数据收集到最后报告的整个 过程中,数据清理会占用整个流程80%的时间。如此耗时的原因是数据清理并非一次性工作,数据清理、计算、可视化是一个动态的循环,根据分析需求的不同,需要应用不同的清理思路和方式。例如,对于默认值的处理,在探索性数据分析阶段,一般都会尝试各种不同的处理方式,完全移除、部分移除或替换成其他数值,并参考分析的目的来决定如何清理默认值。本章会向读者分享数据清理的一些基本原则,作为框架来指导数据清理工作,以帮助读者逐步形成一套属于自己的数据清理思路。本章还将重点介绍如何使用tibble、tidyr、lubridate和stringr这4个包来进行数据清理。希望读者在浏览过本章之后,会对以下3点有所了解。1)“脏”数据和“干净”数据的标准是什么。2)数据清理的指导原则。3)可以使用的工具包。 2.1 基本概念 “脏”数据没有任何标准,只要是不能满足分析要求的数据集都将打上“脏”的标签。所以弄清楚与之相对的“干净”数据可以使我们更容易理解数据清理的概念。目前国际上公认的“干净”数据可以总结为如下3点。1)属性相同的变量自成一列。2)单一观测自成一行。3)每个数据值必须独立存在。表2-1中显示的数据不符合第1条原则,因为男、女都属于性别,所以可以归为一个变量,归为一个变量后如表2-2中所示。但表2-2中显示的数据不符合第3条原则,因为体重和年龄两个变量放在了同一列中,虽然用反斜杠分隔后,人类按常识很容易理解,但计算机并不会懂,其只会将两列本来是数字类型的数据当成是字符串来处理。表2-3中展示了一个3条原则都不满足的样本数据集,在完成清理之前,计算机无法对表2-3中的数据进行任何有效的数据分析。 表2-4中列出了清理后的数据集。对单一数据清理的第一个指导原则就是,按照上文介绍的3点将数据集清理成相应的形式。第2个原则需要按照实际需求进行,表2-5中的数据集是将“宽”数据(一般指多个同类或不同类型变量并存)转换成了“长”数据(同类型变量单独成列)。“宽”数据更符合人们日常对Excel格式数据的理解,而“长”数据对计算机来讲则更易进行数据存储和计算,在R环境中,计算“长”数据的速度优于“宽”数据。将表2-4中的数据转换成表2-5的形式只需一个函数gather,相关内容详见2.3节。 数据清理的第三个指导原则同样需要视情况而定,不同来源的数据应单独成表,独立存在。比如,元数据(解释变量名称或数据背景的数据,英文为metadata)与原始数据应同时存在一个文件或一个工作表中(参考第1章不规则数据读取)。简单来说,元数据通常会包含坐标、指标的具体含义等解释性信息,这类信息不应与原始数据本身同时存在一个数据集中,而应单独成为一个数据集,只在需要解释原始数据本身时才调用元数据。 2.2 tibble包—数据集准备 解决问题需要首先了解问题所在,对症下药。tibble包的存在就是为了给数据清理及后续的分析提供一个最佳的起点。tibble既是R包的名字也是数据在R中的一种存储格式。可以将tibble包理解为R中最常见的data.frame(数据框)格式的升级版。像下列代码所示,如果使用read.csv读取数据,那么数据会被存储在data.frame(数据框)格式中。但是当调用read_csv时,数据就会存在三种适用格式:tbl_df、tbl和data.frame。因为tibble和readr包都源自于Hadley的tidy系列,所以使用readr包时自动植入了tibble(以下简称tbl)的数据格式。那么,问题来了,为什么非要使用这个格式呢? 2.2.1 为什么使用tibble tbl格式作为老旧的data.frame升级版,主要包含如下三点优势。1)稳定性更好,可完整保存变量名称及属性。2)更多的信息展示、警示提醒,有利于及时发现错误。3)新的输出方式使得浏览数据时,屏幕的利用率极佳。因为R语言已经诞生了将近20年,很多早期的函数都是围绕data.frame格式写就的,当调用这类函数时,“新兴”的tbl格式可能会出现不兼容的情况,这也是tbl格式目前被发现的唯一缺陷。tbl格式的第一条优势需要读者在使用过程中对比两种格式的差异才会有直观感受,简单来讲就是,传统的data.frame在处理变量名称时,有时会悄悄改动名称以满足自身要求,这往往会给用户带来一些意料之外的错误。请看以下的例子。 两行代码分别使用函数data.frame和tibble创建了一个传统的数据框格式(见表2-6),以及一个tbl格式的数据框(见表2-7)。代码中定义的数据变量名称为“x+y”,但在data.frame格式中被修改成了“x…y”。大部分情况下,这种默认的修改是数据框格式的一种自我保护机制,目的是为了后续计算时引用变量名不会产生歧义。但是这种保护机制同时会与编程数据分析的另一项基本原则发生冲突,即常量输入等于常量输出(这里的常量可以理解为变量名),除非用户主动修改,否则其名称应保持一致。至于如何选择,就需要读者自行决断了。 第1章中提到查看data.frame中的变量类型时,通常需要调用str函数。但是在tbl格式中,无须调用任何函数,直接输入数据集名称即可查看相关信息。默认情况下,tbl格式会根据console窗口的大小,自动调整显示的内容。内容会包含数据格式、列总数、行总数、变量名称和类型,以及无法完全展示部分的变量信息。有一定data.frame使用经验的读者肯定知道,对于不调用str函数直接在console中运行data.frame格式的数据集,R会将小于1000列×1000行的所有内容都显示出来,而且其中还不包括变量属性等信息。tbl格式查看数据集相关信息的示例代码如下: 2.2.2 创建tbl格式 在练习使用tibble时,可以通过函数tibble或tribble来创建新的数据框。tibble函数创建新数据框的方法与baseR中data.frame函数的方法一致。等号左边为变量名称,右边为相应的数据值,不同变量之间以逗号相隔。下面的代码创建了一个包含变量a和b的数据框,变量a包含6个值,分别为数字1到6,变量b为a列中的值乘以2,因此同为6个数值。代表integer(整数),代表double(浮点型)数据类型。创建数据框的代码如下: tribble函数比较适合用来创建小型数据集,可以采用常规excel表中数据分布的格式,直接手动输入数据,变量名称以“~”起始,逗号结束,数据值以逗号分隔。下面的代码即用来生成表2-2的。该函数在特定情况下会显得非常实用,比如,用来解释变量(或指标)和因子水平的元数据一般都会杂乱无章,使用软件清理既费时又费力,但当通过肉眼能够很容易提取到关键信息时,直接使用tribble函数手动生成变量和因子水平对照表会更高效。 2.2.3 as_tibble—转换已有格式的数据集 在转换数据的格式之前,可以使用is_tibble来测试目标对象是否已是tbl格式,该函数只需要对象名称这一个参数即可。可以通过as_tibble函数将对象已有的格式(vector、matrix、list和data.frame等)转换成tbl。表2-8中列出了常见对象格式的转换注解。 下面通过具体的代码来说明使用as_tibble函数将常见的R对象转换成tibble格式的具体方法。(1)as_tibble函数直接将vector格式转换成数据框格式1)随机设置一组向量,保存为y。2)检视向量y。3)调用as_tibble函数直接转换,并将结果显示到console中。实现代码具体如下: […]