本节书摘来自华章出版社《R语言数据分析》一书中的第1章,第1.1节,作者盖尔盖伊·道罗齐(Gergely Daróczi),潘怡 译,更多章节内容可以访问云栖社区“华章计算机”公众号查看。
第1章
你好,数据!
大多数R项目都必须从数据导入到R的会话中开始,由于R语言能够支持多种文件格式和数据库后台,因此可以使用相当多的数据导入方法。本章,我们不会再讨论基础的数据结构,因为你应该已经对它们非常熟悉了。本章的重点将放在大数据集的导入以及处理一些特殊的文件类型。
如果读者希望对标准工具做一个粗略的回顾,复习一下普通类型数据导入的方法,可以参考官方有关CRAN介绍的手册,地址为:http://cran.r-project.org/doc/manuals/R-intro.html#Reading-data-from-f?iles,或者访问Rob Kabacoff的Quick-R站点:http://www.statmethods.net/input/importingdata.html,该网站总结了大多数R任务中将使用的关键字和提示信息列表,更多相关内容,请参考本书附录。
尽管R语言拥有其自己的(序列化)二进制RData及rds文件格式类型,这种文件格式也可以非常方便地被R用户用来存放R对象的元数据信息。但大多数时候,我们还是需要能够处理一些由我们的客户或老板要求使用的其他类型数据。
平面文件是这其中最常见的一类数据文件,在这样的文件中,数据存放在简单的文本文件中,数据值之间通常会以空格、逗号,或者更常见的分号隔开。本章将对R语言提供的几种用于装载这些类型文档的方法展开讨论,并就哪种方法最适合于导入大数据集进行测试。
某些时候,我们也可能仅对一个数据集的子集感兴趣,并不需要对整个数据集进行处理。由于数据存放在数据库时都是以结构化的方式进行预处理的,因此,我们可以只使用简单并且有效的命令就可以查询得到我们需要的子集。本章1.4节将着重探讨三类最常用的数据库系统(MySQL、PostgreSQL和Oracle)与R进行交互的方法。
除了对部分常用工具以及其他一些数据库后台进行一个简要说明外,本章还将展示如何将Excel电子表格导入到R中,这种导入并不需要事先将电子表格文件转换为Excel文本文件或Open/LibreOff?ice格式文件。
当然,本章要讨论的内容绝不仅仅局限于文件格式、数据库连接以及类似一些让人提不起兴趣的内容。不过,请记住数据分析工程师总是首先从导入数据起步,这一部分的工作是不可回避的,必须要保证我们的机器和统计环境在进行实际的分析之前首先先弄清楚数据的结构。
1.1 导入一个大小合适的文本文件
本章的标题也可以换成“你好,大数据!”因为本章主要探讨如何将大数据装载到R会话中。但是,到底什么是大数据呢?究竟在R中处理多大规模的数据量会比较困难呢?合适的规模怎么定义呢?
R原本是为处理单机规模的数据而设计的,因此比较适合数据集规模小于实际可用的RAM大小的情况,但要注意有时候我们必须考虑在做一些计算操作时,程序对内存的需求会增加,例如主成分分析。在本节中,将这类规模的数据集称为大小合适的数据集。
在R中完成从文本导入数据的操作非常简单,可以调用read.table函数来处理任何规模合适的数据集,唯一要考虑的就是数据读写所需的时间。例如,25万行的数据集?可以参见:
注意,我们对本书所有的R命令及其输出都采用特殊格式的文本显示。其中,R命令以符号“>”开始,属于同一命令的不同行之间以“+”连接,与R控制台的处理方式类似。
没错,我们刚刚从hf?lights包中将18.5MB大小的文本文件下载到硬盘上,该文件包括了2011年从休斯顿(Houston)起飞的航班的部分数据:
用hflight包我们能非常方便地处理海量航线数据的子集,该数据集源自美国交通统计局的研究和创新技术局提供的海量航班数据集的子集,原始数据集中包括了自1987年以来,所有US航班的计划及实际出发/到达时间和其他一些我们可能感兴趣的信息。该数据集经常被用于验证机器学习及大数据技术。更多有关该数据集的详细内容,可以参考以下网址来获得有关列的描述以及其他元数据的内容:http://www.transtats.bts.gov/DatabaseInfo.asp?DB_ID=120&Link=0.
我们将使用这个包括了21列数据的数据集作为数据导入的测试平台。例如,使用read.csv测试导入CSV文件的时间。
从某个SSD站点下载这些数据大约需要1.5秒,相对来说耗时还算可以接受。我们可以指定列数据的转换类型而不采用默认的type.convert(参见read.table的文档获得更多详细信息,在SatckOverf?low的搜索结果也表明有关read.csv的问题看起来是大家都很关心也经常提问的内容)来提高速度。
这个结果已经好了很多!但它可信吗?在使用R语言掌握数据分析的道路上,我们还将实践更多可靠的测试——对同一任务重复n次测试,然后再对仿真结果进行汇总。通过这个方法,我们可以得到关于数据的多种观测结果,并将它们用于分析确定结果中的统计的显著差异。microbenchmark包就为类似任务提供了一个非常好的框架:
我们定义了两个函数:函数f为read.csv的默认设置,在函数g中,我们对之前两列数据类型进行了更新以提高执行效率。其中,参数comment.char将通知R不需要在被导入的文件中寻找注释,参数comment.char确定了从文件中导入的行数,以节约导入操作所需的部分时间和空间。将stringAsFactors设置为FALSE也可以提高一点文件导入速度。
使用一些第三方工具可以确定要导入的文本文件的行数,例如Unix上的wc,或使用R.utils包中自带的countLines函数,不过后者速度要稍微慢一点。
回到对结果的分析中,我们可以在图形中来展现中位数以及一些其他相关统计值,这些结果都是默认运行100次所得:
两者之间的差异看起来非常明显(读者也可以通过其他一些统计实验来验证这个结果),仅通过read.table函数的参数调优,我们就将性能提高了50%以上。
规模大于物理内存的数据集
如果从CSV文件中导入的数据集大小超过了机器的物理内存,可以调用一些专为这类应用而设计的用户开发包。例如,sqldf包和ff包都支持基于特定数据类型以chunk到chunk方式装载数据集。前者使用SQLite或者类似SQL的数据库后台,而后者则使用与ffdf类对应的数据框将数据存储到硬盘上。bigmemory包也提供了类似的功能。稍后将介绍相关的样例(可用于测试):
!
请注意bigmemory包的read.big.matrix函数,其参数header默认值为FALSE,因此在读者使用自己的测试数据平台时应首先阅读相关函数的帮助手册,因为部分函数也和read.table一样支持参数调优。更多相关案例,请参考“High-Performance and Parallel Computing with R CRAN Task View”中“Large memory and out-of-memory data”的内容,地址为:http://cran.r-project.org/web/views/HighPerformanceComputing.html。