3.1.1 数据的输入
1.分隔符分隔的文本
分隔符分隔的文本以text和csv文件为典型代表。读入此类数据有两种方式:键盘输入、通过data.table()函数或readr包读入。使用键盘输入数据是数据输入最原始的方式,在数据分析中几乎不会用到,适合在R语言的入门学习中使用;data.table()函数属于R原生函数(read.xxx()函数均为原生函数),没有对效率和稳定性加以考虑,不推荐使用。哈德利·威克汉姆(Hadley Wickham)和RStudio团队开发了众多功能强大的R包来替代这些原生函数,在读入分隔符分隔的文本文件时,建议首选readr包。下面分别对这两种方式进行介绍,并重点说明readr包的使用方法。
键盘输入数据有两种方式:在代码中嵌入数据;调用R内置的文本编辑器输入数据。
在代码中嵌入数据,即在创建容器(向量、数据框、列表等)的同时将数据输入。这种方法在第2章提过,在此不再赘述。
调用R内置的文本编辑器,需要首先创建一个空的容器,之后使用edit()函数调用可视化的编辑器输入数据。注意,在使用edit()函数调用编辑器输入数据时,要对变量进行赋值操作data-edit(data)。因为edit()函数是在对象的副本上操作的,所以副本会随着编辑器的关闭而消失。另外,我们还可以使用fix()函数直接编辑变量,无需进行赋值操作。例如:
上述代码的输出结果如图3-1所示。
图3-1 编程结果
我们还可以使用read.table()函数读取带分隔符的文本文件。read.table()函数可以读取表格格式的文件并将其保存为一个数据框,其基本语法如下:其中,file是一个带分隔符的ASCII文本文件;header是一个表明文件首行是否包含变量名的逻辑值(TRUE或FALSE);sep用来指定分隔数据的分隔符;rows.names是一个可选参数,用来指定一个或多个表示行标识符的变量。关于此函数的其他用法,可以通过文档查阅进行了解。
在使用read.table()函数时,有一些需要注意的事项。第一,row.names会将指定的名称作为行名,这一行会失去原有的标签。第二,一些特殊的变量名称会被R自动转换为R默认的格式,如readtable会转换成read.table。在默认情况下,read.table()会把字符变量转换为因子,我们可以使用string AsFactors参数进行设定,也可以使用colClasses参数为每一列指定数据类型。
文件的读取方式决定数据的质量,高质量的读取可以免除一部分后续数据处理的操作。readr包中有许多功能强大的函数,它们可以读取不同格式的文本文件,可以高效迅速地读取数据。其中,最常用的是read_csv()函数,因为csv是数据存储最常见的形式之一。read_csv()的常用代码示例如下:
其中,参数file是文件存储的路径;参数col_names是一个表明文件首行是否包含变量名的逻辑值,我们也可以向它提供一个字符串作为列名;参数col_types可以为每一列指定数据类型;参数na设定了使用哪个或者哪些值来表示文件中的缺失值;skip通过设置参数n来读取、跳过数据的前n行。这些参数满足读入csv数据的大部分需求,如果有其他更加精细的设定,可以查看函数的参考文档。最后一个参数comment可以批量剔除数据,如comment=“#”表示剔除所有以“#”开头的行。
read_csv()函数还有一个重要功能是:它在运行时会打印列的数据类型说明,这使得数据在加载完成之后,我们就能对数据有一个直观的了解。为了方便学习,readr包中提供了不同类型的数据集样例,我们可以使用readr_example()函数获取数据集名称,使用readr_example(filename)获取数据集路径。例如:
readr包中还有一些其他函数可以读取不同类型的文件。例如:read_tsv()函数读取制表符分隔数据;read_lines()函数从文件中逐行读取数据(适合复杂的数据处理);read_fwf()函数按照宽度设定读取的范围。这些函数在参数的设定上与read_csv()函数非常相似,因此,只要掌握了read_csv()函数的使用方法,便可以做到举一反三。
2.Excel数据
在R中读入Excel文件的常用包有两个:readxl包和xlsx包。本书推荐使用readxl包,因为xlsx包依赖较多,而且read.xlsx()函数并不是十分稳定,重复读取文件容易导致电脑内存过载。所以本书将重点介绍readxl包的使用,对于xlsx包只做简要说明。
首先需要声明的是,本书并不建议在R中直接读入Excel数据。我们可以在Excel中导出csv文件,然后在R中读入csv文件。在R中通过xlsx包直接读入Excel数据是一个复杂的过程。使用xlsx包要先安装rJava和xlsxjar包,然后还需要配置Java环境。
目前xlsx包支持的Excel版本有Excel 97/2000/XP/2003/2007。通过xlsx包读入Excel数据的代码示例如下:
其中,file是Excel文件存储的路径;sheetIndex是表的索引的数值;header是逻辑值,表示是否将第一行识别为列名。此外,我们还可以使用read.xlsx2()函数来读取大型表格,因为它在工作过程中调用了Java,所以效率会有所提升。
readxl包是tidyverse包中的一部分,是读入Excel数据的一个R包,由哈德利·威克汉姆(Hadley Wickham)开发,底层调用的是C++程序处理数据。因此,在稳定性和效率上,readxl包非常强大。read_excel()函数的常用代码示例如下:
其中,参数range指定读入数据的区域,默认全部读入。由于其他参数与read_csv()函数几乎相同,此处不再赘述。
readxl包中含有一些例子,我们可以使用readxl_example()函数将它们展示出来,然后使用readxl_example(“filename”)得到该文件的路径,从而通过这些例子进行函数的学习。代码示例如下:
3.pdf数据
在商业数据分析的过程中,可能会遇到对批量pdf文件进行操作的情况。pdf是一种常用的商业文本格式,在R中加载pdf数据,推荐使用readtext包。readtext包是专门用来读取文档数据的包,它可以读取多种类型的文本数据(如csv、html、txt、pdf、doc等),而读取pdf格式文本需要通过pdftools包进行转换。我们主要通过readtext()函数完成pdf文件的读取,readtext()函数的常用代码示例如下:
readtext包同样提供了用于学习的数据集样例,可以通过DATA_DIR获取样例的路径,但是这里的文件名UDHR_chinese需要手动获取。如果文本型文件的后缀名相同,如pdf之类的文件,那么,docvarsfrom参数可默认选择文件名前缀作为处理对象。readtext()函数的第三个参数docvarnames则是对数据集的命名,若不指定名称,则默认将(docvar1,docvar2,…)作为名称。