带你读《R数据科学实战:工具详解与案例分析》之一:数据导入工具

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 本书共11章,前6章主要介绍和讨论使用R语言的一般流程以及常用的R包;第7~11章,包含了5个实战案例,通过与前6章的内容相结合,展示如何使用这些R包。复现书中的代码需要读者对.Rproj有一定的了解,建议读者参阅网络教程学会使用.Rproj。使用.Rproj的原因在于其可以将每一次数据分析或练习都视为一个独立的项目(不必调用setwd函数重置工作路径),这样做不但可以减少代码出错的几率,而且还能更利于进行数据管理。

数据科学与工程技术丛书
点击查看第二章
R数据科学实战:工具详解与案例分析

image.png

刘 健 邬书豪 著

第1章

数据导入工具
无论数据分析的目的是什么,将数据导入R中的过程都是不可或缺的。毕竟巧妇难为无米之炊。所以本章主要介绍如何选择合适的包,将不同类型的数据文件导入R中。学习完本章的内容之后,读者将会获得以下技能。

image.png

1)掌握与数据文件类型相对应的R语言数据读取函数。
2)了解常用数据类型读取所需的R程序包。
3)了解不同R包中相似函数的优缺点。
4)清楚常用数据读取函数的参数设置。
5)能够处理规则及不规则原始数据文件的读取和初步检视。
在描述和讲解如何使用R语言各个包的基本方法的同时,本章还会介绍一些笔者曾经踩过的“坑”,以及从中学到的一些小知识点或技巧,希望能让读者在学习过程中避免重蹈覆辙。

1.1 utils—数据读取基本功

utils包是R语言的基础包之一。这个包最重要的任务其实并不是进行数据导入,而是为编程和开发R包提供非常实用的工具函数。使用utils包来进行数据导入和初步的数据探索也许仅仅只是利用了utils包不到1%的功能,但这1%却足以让你在学习R语言时事半功倍。

1.1.1 read.csv/csv2—逗号分隔数据读取

.csv可能是目前最常见的平面文件类型了。它代表的是comma-separated values,简单来讲就是,文件里每一个单独的数据值都是用逗号进行分隔的。.csv只是text file(文本文件)的一种,文本文件在微软的Windows操作系统中常以拓展名为.txt的形式呈现。文本文件可以使用各种符号来分隔数据值,例如常见的tab和“;”(分号),或者其他任意符号。即便是以.csv为拓展名的文件也并非一定是以逗号进行分隔的,相关内容在本章后面的函数演示部分会有介绍。文件的拓展名并非必须,熟悉Linux系统的读者可能接触过很多无拓展名的文件。处理无拓展名的文本文件数据时,最简单的办法就是使用data.table包中的fread函数(相关内容请参见第6章)。
utils里的read.csv/csv2是专门用于设置快速读取逗号分隔(read.csv)或是分号分隔(read.csv2)。也就是说,在事先了解数据值分隔符号的情况下,这两个函数对分隔符和其他一些参数的默认设置会使数据导入的部分更加简单和快捷。有一点需要特别注意,即这两个函数对小数点的处理:前者默认的小数点是“.”,后者默认的小数点是“,”。这只是因为不同国家技术人员对数据值分隔符的见解或者好恶不同而造成的。
万里长征第一步,我们先来看read.csv最简单的使用方式,代码如下:
image.png

此行代码可以解读为使用read.csv从工作空间读取文件flights.csv,然后将数据集保存到flights中,其他所有参数都使用默认值。因为flights.csv文件已经在R的工作路径里,所以此处免去了设置work directory。这里希望读者能够自行探索使用.rproj(R项目—将每一次数据分析的过程都看作一个独立的项目)来对每一个独立的数据分析工作进行分类和归集。该方法不仅免去了设置路径的麻烦,也减少了因原始数据文件太多而可能导致的各种隐患。
小知识
函数在执行的时候可以依照其默认设置的参数位置来执行,也就是说,用户无须指定每一个参数的名称,只需按照位置顺序来设定参数值即可。比如,read.csv中的file参数名就可以省略,只要第一位是读取文档的目标路径和文件名就可以。
数据文件被读取到R工作环境中的第一步通常为调用str函数来对该数据对象进行初步检视,下面的代码列出了该函数最简单的使用方式。
image.png

str函数可用于检视读取数据结构、变量名称等。这里同样也只指定了一个非默认参数,其他参数全部都为默认值。str的输出结果由5个主要部分组成,具体说明如下。
1)data.frame代表数据集在R中的呈现格式,这里指的是数据框格式,读者可以将其设想为常见的Excel格式。
2)6 obs. of 6 variables代表这个数据集有6个变量,每个变量分别有6个观测值。
3)$ carrier与其余带有“$”符号的函数均指变量名称。
4)变量名称冒号后面的Factor和int代表的是变量类型。这里分别是指因子型Factor和整数型int数据。另外还有字符型chr、逻辑型logi、浮点型dbl(带有小数点的数字)、复杂型complex等。因子型变量的后面还列出了各个变量的因子水平,也就是拥有多少个不同的因子。比如,出发地origin后的3 levels就是表示其有3个因子水平。只是出发地是否属于因子类型的数据还有待商榷,而read.csv默认将所有的字符型数据都读成了因子型。
5)数据中的实际观测值。str函数在默认情况下会显示10行数据。使用str函数浏览导入的数据集可以让用户确定读取的数据是否正确、数据中是否有默认的部分、变量的种类等信息,进而确定下一步进行数据处理的方向。其他用来检视数据集的函数还有head、tail、view等,另外,Rstudio中的Environment部分也可以用于查看目前工作环境中的数据框或其他类型的数据集。
前文提到过,.csv并非一定是以逗号进行分隔。如果遇到以非逗号分隔数据值的情况,加之未指定分隔符(例如,运行read.csv读取以Tab分隔的文件),就会出现下面的情况:
image.png

小技巧
指定(assgin)符号“<-”的快捷键是“alt”加“-”(短划线)。Rstudio快捷键参照表可以通过“alt+K”来查看详细内容。
由代码可知,read.csv函数将所有数据都读取到了一列中。因为按照默认的参数设置,函数会寻找逗号作为分隔列的标准,若找不到逗号,则只好将所有变量都放在一列中。指定分隔符参数可以解决这个问题。将t(tab在R中的表达方式)指定给sep参数后再次运行read.csv读取以Tab分隔的csv文件,代码如下:
image.png

根据实际情况不同,字符型数据有时会是因子,有时不会。如果使用read.csv默认的读取方式,那么字符型全因子化会对后续的处理分析带来很多麻烦。所以最好是将字符因子化关掉。stringsAsFactors参数就是这个开关,示例代码如下:
image.png

1.1.2 read.delim/delim2—特定分隔符数据读取

read.delim/delim2这两个函数是专门用来处理以tab分隔数据的文件的,delim可用来读取小数点是“.”的数据,delim2则用来处理小数点是“,”的数据,所以这两个函数与read.csv/csv2唯一不同的就只是参数sep = "t"。聪明的你很可能已经想到了如果使用这两个函数的默认设置来读取以逗号分隔的数据会发生什么。函数的默认参数会在原始数据中不断地寻找tab分隔符,找不到的话就会如同1.1.1节里面演示的那样,将所有变量都挤在一列里。read.delim/delim2的示例代码如下:
image.png

无论是read.csv还是read.delim,帮助文档中的参数格式都是相同的。从上面的代码结果中可以看出,read.delim执行的其实,是函数read.table。其实,这4个函数(read.csv/read.csv2/read.delim/read.delim2)都只是它们的母函数read.table的变形罢了。这样做的原因有可能是因为在RStudio出生之前,read.csv/delim比read.table更容易记住,也有可能只是Henrik Bengtsson(utils包的笔者)觉得这样做很酷。具体是什么原因已经不再重要,会用这些函数才是第一要务。

1.1.3 read.table—任意分隔符数据读取

read.table函数会将文件读成数据框的格式,将分隔符作为区分变量的依据,把不同的变量放置在不同的列中,每一行的数据都会对应相应的变量名称进行排放。表1-1简要列出了read.table函数中主要参数的中英文对照。

image.png

以上这些参数已足以应付读取日常练习所用的规整的数据文件,例如,教授布置的统计作业中的原始数据集,各种传感器输出的.csv文件等。下面的代码及运行结果演示非常简单,使用read.table读取1.1.1节中的第一个数据集,实现思路是每次只增加一个read.table函数中的参数。代码如下:
image.png

表1-2展示了所有参数均为默认设置的部分结果。

image.png

小提示
上面的演示代码中使用了head函数,该函数可以按照人们习惯的方式将数据框按照自上而下的方式显示出来,而不是像str函数那样从左向右展示。一般在做初步数据检视的时候,推荐两个函数都运行,作为互补。head方便与原始数据文档进行比对,而str则可以显示所保存的数据框属性、变量类型等信息。
因为函数默认的分隔符是空白(注意不是空格),所以应有的6个变量都被读在一列中。且默认的header参数是假,所以数据变量被默认分配了一个新的变量名V1,并且应为变量名称的这一行变成了观测值的第一行。将header设置为TRUE后的代码如下:
image.png

表1-3中显示的是部分结果。

image.png

指定header参数为真,分隔符sep参数为“,”后,变量名称才得以读取成应有的样子(如表1-4所示)。
image.png

image.png

表1-4所示的数据框终于呈现了该有的样子。需要注意的,是因为字符数据因子化的参数还是默认设置,因此变量carrier、tailnum、origin、dest还是因子型。在实际练习或使用时,建议指定stringAsFactors = FALSE。
以上读取的数据集都是规整的数据集,即每一行数据都有相同的观测值。不过在实际生活中,原始数据难免会存在空白行、空白值、默认值,或者某一行数据存在多余观测值却没有与之对应的变量名称,抑或元数据和原始数据在同一个文件中等各种问题。这里暂且称这些问题数据集为不规则数据集,简单说就是,实际列的个数多于列名的个数。read.table函数为这些问题准备了相应的参数。
1.空白行
表1-1中介绍过read.table对于空白行的默认处理是跳过,这可以满足大部分常见数据的情况。不过在某些特殊情况下,例如,一个数据文件中同时存在两个或两个以上的数据集,那么保留空白行可能会有助于后续的数据处理。表1-5演示的就是一个比较特殊的例子。空白行的上部是元数据,也即解释数据的数据,这里演示的是航空公司的缩写和全名的对照。空白行的下部是数据的主体部分,航班号、起始地缩写、起飞时间。这里保留空白行可有助于区分数据的不同部分。

image.png

保留空白行的代码如下所示:
image.png

指定空白行保留的参数后,数据被成功读进R(表1-6)。

image.png

如此一来,不同的数据集就可以很容易地进行切割并归集到新的数据集中。可是,另外一个问题又出现了,函数按照第一部分的两列变量将后续的所有数据也都写入了两列。这是因为read.table会扫描文件中前五行的数据(包括变量名称)并以此为标准来确定变量数,airlines.csv中开始的五行数据都只有两列,所以后续的数据也都强制读取成两列。如果数据的第2~5行中存在任何一行拥有多于前面一行或几行的数据值,那么函数就会报错提示第一行没有相应数量的值。这种情况可以根据实际数据文件内容,用两种方式来处理,具体如下。
1)如果文件中开始的部分是暂时不需要的元数据,那么可以使用skip函数跳过相应的行数,只读取感兴趣的数据。
2)如果文件内容是一个整体,只是若干行数据具有额外的观测值。那么可以通过调整参数col.names或fill和header进行处理。
第一种情况比较容易,读者可以自行测试,在此略过。第二种情况需要知道数据中观测值个数的最大值,以用来补齐变量个数。因为已经知道airlines文件的第二部分拥有6个变量,所以下面就来演示如何将6个变量名称指定成新的变量名(表1-7),代码如下:
image.png

演示结果如表1-7所示。

image.png

小技巧:
另外一个获取不规则数据集中所需变量个数的方法是利用报错信息。当不指定col.names参数,且原始数据的第2~5行中任一行有多于第一行的数据时,read.table会报错提示Error in scan(file = file, what = what, sep = sep, quote = quote, dec = dec, : line 1 did not have X elements, X即所需要的手动指定的变量个数。
这里使用paste0来创建新的变量名称。paste0可以理解为胶水函数,用于将需要的字符串粘合在一起。这里演示的意思是创建6个以V开头,从V1到V6的字符串作为变量名。这种处理方式足以应付平时练习用的小型数据集(比如,只有几行到几十行数据的数据集)。但是在处理实际工作中成百上千行的数据时,这种手动指定变量个数的方法就显得笨拙而低效了。下面的代码演示了如何实现自动检测数据集所需的变量数:
image.png

部分结果展示如表1-8所示。

image.png

count.fields/max/seq_len这三个函数的配合使用实现了如下功能。
count.fields用于自动检测数据集中每一行数据的观测值个数,max用于找出count.fields输入结果中的最大值,seq_len用于以最大值为参照生成1到最大值的整数序列,胶水函数paste0用于定义变量名称。
因为R基于向量计算的特性,因此这种函数之间简单的配合使用很常见也很有效。所以希望小伙伴们在以后的练习或实际工作中,多思考,尽量使用这样的组合来提高代码的效率、简洁性和可重复性。
使用参数fill和header也可以读取不规则数据集。需要注意的是,采用这种方法是有前提条件的,即原始数据第2~5行实际列的个数应大于列名。代码如下:
image.png

上述代码的演示结果如表1-9所示。

image.png

2.默认值、空白
一个数据集里出现默认值(NA)或空白(“”)的情况十分常见,两者之间的区别需要根据不同的实际情况来确定。理论上来讲,默认值仍是数据观测值的一种,虽然在原始数据中其可能与空白一样没有显示,但是它可以通过其他手段来进行补齐。而空白有可能并不是数据,比如在上面的演示中,V3至V6列,1~5行都是空白,这些空白不属于任何实际数据变量,是真正的空白,因而不能说这些空白是默认值。默认值和空白的处理完全可以独立成书,因为相关内容已经超出了本书的范围,所以这里不再过多讨论。下面只演示在导入数据的过程中,如何进行简单的默认值、空白预处理,代码如下:
image.png

表1-10中展示了处理后的部分数据值。

image.png

第七列中的数据在指定将空白替换成“NA”之后,原有的空白位置被写入了“NA”,也就是说第七列的空白属于数据的一部分。根据实际情况,也可以将多余的数据部分或全部替换成“NA”(如表1-11所示),以方便后续的处理及分析,代码如下:
image.png

替换结果如表1-11所示。

image.png
image.png

当数据集行数较多,无法轻易地鉴别出某一列到底有多少个观测值需要赋值为“NA”的时候,可以配合unique函数进行处理。处理的思路是先将数据读取到R中,然后使用unique函数找到指定列中的非重复观测值,选取指定观测值并保存到一个向量内,然后将向量指定给na.strings参数来进行替换,代码如下:
image.png

替换结果如表1-12所示。

image.png

第一次读取数据是为了获得需要替换的观测值,第二次读取则是将需要替换成“NA”的观测值指定给相应参数。因为replace是一个字符串向量,所以可以使用“[”按位置选择其中的值,当然也可以不选择任何值,直接全部替换。
小知识
“[”是baseR中Extract的一种,在R的使用过程中,这是必须掌握和理解的函数之一。

1.2 readr—进阶数据读取

'readr'包是R语言世界级大神之一Hadley Wickham 主导开发的一个数据读取包。相较于'utils' 包里的读取函数,'readr'包主要拥有3点优势,具体如下。
1)更快。就平均读取速度而言,'readr'包里的'read_csv'一般要比'read.csv'快三到十倍不等。
2)默认设置更简洁。默认情况下,'readr'包会自动解析每列的数据类型,并显示解析结果,这样可以更加直观地看到读取后的数据类型是否符合预期,而且无须设置'stringAsFactors'。
3)对数据类型的解析更准确。'utils'包中提供的'read.table'函数在甄别一列数据的属性时,只会对起始5行的观测值类型进行评估,并以此决定该列全部数据的类型。而'readr'中的函数默认评估1000行的观测值后再决定数据的类型。
'readr'包中常用的数据读取函数包括'read_delim'、'read_fwf'、'read_lines'、'read_log'和'read_table'。其中'read_delim'属于常见数据读取'read_csv/read_csv2/read_tsv'的母函数,所以也可以直接调用子函数。
read_delim
常用分隔符文件的读取函数'read_csv/read_csv2/read_tsv'分别对应于'utils'中的'read.csv/read.csv2/read.delim'。Hadley与其他成员开发的这个包更像是对'baseR'中与数据读取有关函数的一个优化,使其更加规范、稳定和可再现。表1-13中列出了read_delim参数的英文名称、功能的中文描述及部分传参注释。其中,比较重要的几个参数依次为'file''delim'(如使用'read_csv'等则无须设置)、'skip'、'col_name'和'col_types'。之所以说它们比较重要,是因为笔者发现适当调整参数设置可以让后续的数据处理事半功倍。

image.png
image.png

参数'file'的重要性不言而喻,无默认值,必须设置。第二位参数'delim'视情况可有可无,在使用具体的子函数'read_csv/read_csv2/read_tsv'时就无须设置。不过,使用母函数'read_delim'时是没有默认值的。
当一个.csv数据中前面有很多空白行时,skip参数可以直接跳过空白行来读取数据。具体设置非常简单,skip = 3即表示跳过前三行数据,从第四行开始读取。这个参数并非只用于跳过空白行,也可以用来读取原始数据的一部分,配合n_max使用可以做到随心所欲地读取任一部分数据。
另外一个重要的参数是col_names。对原始数据中的变量名称不满意,可以使用该参数自定义变量名称。这个参数可以理解为将read.table 中的参数header和col.names 的功能融合在一起,相关内容请参见1.1.3节。
变量属性对后续计算会有很大影响,所以col_types参数的重要性也不容忽视。虽然Hadley等已经将这个参数的功能优化得非常智能了,但他还是会建议用户应尽量依据个人需求来定义变量属性,因为意外总是存在的。
下面的代码展示了read_csv解析变量属性正常、读取正常的情况。运行函数之后,报告会在console中显示每一列数据都被解析成了何种属性,因此非常容易甄别哪一列数据类型不是期望的类型。在某些特殊情况下,比如原始文件分隔符号不统一的情况,这时自动解析功能会无法识别某一列或多列变量的属性,进而显示parsing failures(剖析失败)的报告。用户可以通过problems函数来查看具体的信息,从而确定原始数据中的哪一部分数据出现了问题。
image.png

1.3 utils vs readr—你喜欢哪个?

就实际应用而言,笔者建议读者在考虑原始数据文件格式的前提下,根据个人需求或喜好来选择使用utils或readr这两个包中的数据读取函数。在R语言的世界里,没有最好的函数,只有最适合的函数。在处理单一或个位数数据文件的情况下,read.csv和read_csv都可以很好地完成任务。流程图1-1也许可以帮到有函数选择困难症的读者。

image.png

之所以设置文件个数和文件大小的前提,是因为在面对批量、大容量平面文档格式的数据时,这两个函数并非最合适的选择。data.table包中的fread函数更能满足在读取数据时对速度和准确度都有要求的读者,具体请参见第6章。

1.4 readxl—Excel文件读取

readxl是微软Excel文件读取的必备R包,是Hadley Wickham、Jennifer Bryan以及其他6名成员合作完成的经典程序包之一。值得一提的是,该包的开发者之一兼实际维护者Jennifer Bryan(网络上多称她为Jenny Bryan),可以称得上是与Hadley齐名且为数不多的女性R语言神级人物。可能是因为其身为大学教授,因此她总能够用很生动有趣的方式将复杂的问题简化成通俗易懂的知识传递给“小白”,强烈建议有英文基础的读者能够搜集一些她的主题演讲或者书籍。在后续第5章 purrr包的讨论中,笔者也会引用她的经典例子。
更新后的readxl包中虽然也还是只有5个函数,不过功能却比以前的版本更强大了。对于起初的版本,数据会被读取成常见的data.frame格式,而对于现在的版本,读取后的数据集格式则为tibble,可以理解为提升版的data.frame(具体详见2.1节)。readxl包括两个探测性函数excel_format和excel_sheets,一个引用例子的函数readxl_example,新加入的读取特定单元格的函数cell-specification以及最重要的read_excel函数。本节将着重讨论read_excel的参数设置及用法技巧(见表1-14)。

image.png

首先还是需要加载readxl包。尽管Hadley从2017年开始就一直在网络上宣传这个包已经属于tidyverse的一部分,但用户还是必须手动单独加载这个包。加载readxl包代码如下:
image.png

readxl包自带示范文件,使用函数readxl_example可以查看文件名字,以及获取文件路径,代码如下:
image.png

获取示例文件的路径,可以先复制readxl_example函数运行后的结果,然后将其粘贴到read_excel函数的path参数中。下面的代码演示函数嵌套的方法,这种嵌套的代码书写方式能够在一定程度上简化代码和减少命名中间产物的频率。不过嵌套过多会使可读性变差,一般推荐只嵌套两层。将读取后的数据保存在iris中,执行str函数之后将会发现除了经典的data.frame之外,数据集还有另外两种类别,tbl_df和tbl,这两种类别的具体含义会在2.1 节中详细介绍。函数嵌套的示例代码如下:
image.png

之所以命名为iris,是因为这个范例Excel文件中的第一个工作表就是该经典数据集。函数excel_sheets可用于查询同一个文件中的工作表名称,其实现代码具体如下:
image.png

在datasets.xlsx中一共存在4个工作表,其中包含了4个最经典的R语言练习数据集。在此,希望读者可以自行浏览这几个数据集,对数据集的格式、变量名称等情况有一定程度的了解,在后续的章节中,笔者还会引用这几个数据集。
增加参数sheet或range可以读取指定工作表中的数据。这里需要注意的是,表1-14中提到了参数优先级的问题。对于一般常见的练习数据集,sheet参数指定的工作表已足够胜任。读者只需要记住range参数可以用来处理特殊情况,也就是说,当设置sheet后依然对读取到的数据不满意的情况可以考虑使用range。
下面的代码演示了sheet的两种传参方式:位置序号和名称。推荐读者采用后者。因为工作表被意外拖拽导致位置调换的情况常有发生,而位置意外发生调换之后读取的数据也会不同,这就增加了代码崩溃的风险。如果使用名称,则会降低发生错误的几率。示例代码如下:
image.png

对于后面的参数,读者可以根据表1-14中的解释,按照1.1节中的方法,每次增加一个参数,来逐步掌握每一个参数的功能,这里不再赘述。

1.5 DBI—数据库数据查询、下载

在使用R语言和数据库进行交互之前,读者们需要明确一个问题—是否有必要使用R来处理数据。简单的数据处理任务,比如数据查询、筛选和简单运算,相应的数据库语言应该是比R语言更好的选择。不过当你对数据库语言并不熟悉,而且需要R语言强大的统计分析和绘图环境来处理数据库中的数据时,DBI包绝对是一条捷径。因为Hadley大神再一次拯救了“小白”。有了DBI包,不需要了解数据库交互中各个环节繁琐的理论知识和技巧,只需要明白如何通过DBI包来建立数据库连接、查询和读取数据即可。不过,这个包也并非万能钥匙,想要无障碍地与数据库进行交互,以下6点是必备的前提。
1)已知数据库的类型,例如,MySQL、PostgreSQL。
2)已经安装了相应数据库类型的R包。
3)数据库服务器地址。
4)数据库名称。
5)接入数据库的权限、账号和密码。
6)已安装dplyr包用来本地化数据库中的数据。
使用R与数据库进行交互的一般流程为:建立连接→发送查询请求→获取相关数据。下面,我们用PostgreSQL的数据库作为代码示例。首先加载三个必备程序包,其中,DBI和PostgreSQL将用来建立与数据库的连接以及发送请求。dplyr则是用来将数据库中的数据保存到本地。加载代码具体如下:
image.png

不同类型的数据库可能需要调整dbConnect中的参数,具体调整方法读者可以参见帮助文档。数据库服务器地址、名称、权限等信息需要输入到单引号中,请一定留意是否有空格符号不小心被复制或者因误操作输入其中。如果担心密码泄露的话,则可以使用RStudio中自带的密码弹窗功能。dbListTables函数可以用来查询数据库中的详细内容,并以字符串向量的格式返回,如果数据库中无内容,则会返回空值。调整dbConnect参数的示例代码如下:
image.png

优化后的tbl函数可以直接调取已经建立连接的数据库中的指定数据,并保存为tibble格式的数据集(参见第2章)。下面的代码中,逗号后面的参数也可以用“Table1”或“Table2”来表示:
image.png

数据库交互的有关内容完全可以独立成书,这里我们只介绍了最简单的基本用法,以使大家对如何使用R来查询数据库有个最基本的印象。

1.6 pdftools—PDF文件

学术期刊、网络杂志和电子书籍一般都会以PDF格式的文件呈现。一般的计量型数据分析很少会遇到读取PDF文件的情况,不过在进行文本挖掘(Text Mining)和主题模型(Topic Modelling)预测中,pdftools包绝对是必备R包之一。该包只有两个母函数,一个用来从PDF中提取数据(此处的数据包括数字型和文字型数据),另一个则用来将文件渲染成PDF格式。本节我们只讨论第一个母函数—pdf_info。
pdf_info函数下面一共包含6个子函数,功能各不相同,详见表1-15。但是6个子函数的参数完全一致,分别是pdf、opw和upw,详见表1-16。

image.png
image.png

image.png

由于篇幅有限,下面的代码只截取了部分结果进行解释。这里所用的PDF文档是pdftools包的帮助文档,读者可以自行到R官网上搜索下载。帮助文档是开放PDF文件,无须提供密码。读取文档代码如下:
image.png

当使用pdf_text提取文档内容时,全部内容都被提取为一个字符串向量,每页的内容都被单独放置于一个字符串中。帮助文档的PDF格式一共包含5页,所以这里会得到一个长度为5的字符串向量。有两种方式可用于查看提取的文本:可以直接将结果显示在console中(通过执行print(text)或直接运行text),也可以通过“[ ]”来指定显示某一页的内容。空白的位置都会以空格的字符格式显示,“rn”代表换行符号。提取文档内容的代码如下:
image.png
image.png

该文档无附件,所以会显示一个空列表:
image.png

文档中一共包含了6种字体,pdf_fonts会给出字体的名称、类型、是否嵌入文档中这三类信息,具体如下:
image.png

目录读取的子函数会将所读取的内容返回到一个列表中,如果直接将该列表显示在console中很可能会让人感觉不知所云,读者可以自行实践。最好的办法是将读取的内容使用jsonlite包转换成json列表的格式进行显示,以帮助理解文档的架构。jsonlite包的相关内容详见1.7节。jsonlite包转换成json列表的示例代码如下:
image.png
image.png

1.7 jsonlite—JSON文件

JavaScript Object Notation(JSON)通常是作为不同语言之间互相交流信息的文件,JSON文件不但节省存储空间,其简洁明了的形式也很容易理解。jsonlite包既能够完整地将JSON格式的文件完整地解析和读取到R语言中来,也可以将任何常见的R对象(object)输出成JSON格式。在1.6节中,toJSON函数可用来将PDF文档目录转换成JSON格式,以便于理解各层级之间的关系。
读取JSON文件的fromJSON函数共包含6个参数,通常情况下,除了指定文件路径之外,其他参数使用默认设置即可。表1-17中列出了该函数的参数及功能描述。

image.png

首先以JSON常见的数组形式创建一个字符串向量,保存为example。中括号代表数组的起始,双引号中代表值,值与值之间以逗号进行分隔,然后再用单引号将这一数组格式保存到字符串向量中。因为example中的数组是按照JSON格式输入的,所以直接使用fromJSON函数即可。在默认的参数设置下,可以得到一个包含4个值的R对象—字符串向量。运行fromJSON前后的这两个字符串向量,虽然名字一样,但内容完全不同,感兴趣的读者可以单独运行example来对比其区别所在。formJSON示例代码如下:
image.png

当参数simplifyVector被指定为假时,返回结果为一个包含4个元素的列表。4个元素即代表共有4个值,每一个值都以列表的形式返回。当JSON格式的原始数据文件有多重嵌套时,可以通过设置参数来查看数据结构和正确读取数据。不过,一般情况下还是建议读者使用非嵌套数据来练习和使用R语言与JSON格式数据进行交互,待有一定了解后再提高难度。返回结果如下:
image.png

1.8 foreign package统计软件数据

在世界范围内,开源的数据分析工具正在逐步取代传统数据分析软件,例如SAS、SPSS。在这一过程中,foreign包可以让我们无缝连接以传统分析软件格式保存的数据。该包也是集读取和写入于一体。因为开源统计分析软件在世界范围内不可逆转的上升势头,传统分析软件的使用频率越来越低,其数据格式也渐渐被边缘化,本节只列出读取相应拓展名所需的函数(表1-18)以备读者不时之需,而不会做进一步的代码演示。
image.png
image.png

1.9 本章小结

本章我们着重讨论了常见的平面文件和Excel文件的读取,包括在处理规则数据及不规则数据时函数和参数的选择。同时,本章还介绍了其他文件格式的读取,以及相应函数的参数设置。图1-2总结了本章讨论过的主要程序包,希望读者在日常练习和工作中遇到不同格式的文件时,能够瞬间反应出读取该格式所需的包及对应的函数。
第2章将会帮助读者点亮数据分析中的第二个关键步骤—数据清理。

image.png

相关文章
|
数据格式 数据挖掘 存储
带你读《R数据科学实战:工具详解与案例分析》之二:数据清理工具
本书共11章,前6章主要介绍和讨论使用R语言的一般流程以及常用的R包;第7~11章,包含了5个实战案例,通过与前6章的内容相结合,展示如何使用这些R包。复现书中的代码需要读者对.Rproj有一定的了解,建议读者参阅网络教程学会使用.Rproj。使用.Rproj的原因在于其可以将每一次数据分析或练习都视为一个独立的项目(不必调用setwd函数重置工作路径),这样做不但可以减少代码出错的几率,而且还能更利于进行数据管理。
|
数据采集 数据挖掘
《数据分析实战:基于EXCEL和SPSS系列工具的实践》一3.1 数据采集的几条重要原则
本节书摘来华章计算机《数据分析实战:基于EXCEL和SPSS系列工具的实践》一书中的第3章 ,第3.1节,纪贺元 著 更多章节内容可以访问云栖社区“华章计算机”公众号查看。 3.1 数据采集的几条重要原则 3.1.1 要足够“复杂” 先说一个跟客户接触的例子。
1534 0