文本是数据分析师接触最多的一种数据,本文讲解如何使用R对其进行读写,使用readr这个包:
install.packages("readr")
readr提供许多工具函数用于读取不同类型的文件:
read_csv()
读取逗号分隔的文件;read_csv2()
读取分号分隔的文件;read_tsv()
读取\t
分隔的文件;read_delim()
读取任意分隔符分隔的文件。read_fwf()
读取固定宽度的文件,指定宽度的方法包括三种,一是fwf_empty()
,获取一个或多个空格形成的空白位置,并用其拆分列,这种模式被封装为另一个函数read_table()
;二是fwf_widths()
,指定每个字段的宽度;三是fwf_positions()
,提供两个vector
,分别指定每个字段的起始位置和结束位置。read_log()
读取Apache风格的日志,更高级的功能可以使用webreadr包。本文只讲解read_csv()
方法,其余方法类似。
read_csv()
的第一个参数是文件路径,另有几个常用的选项:
skip=n
:跳过前n行;comment="#"
:忽略以#开头的所有行;col_names = FALSE
:告诉readr文件不包含列名;na="NA"
:告诉readr文件中的NA字符串代表空值绝大多数情况下,上面的这些知识就足够用来读取文本了。readr提供的这些工具比R内置的read.table()
系列函数效率要高十几倍。如果文件还是太大,读的还是太慢,可以移步data.table包,试一下fread()
函数。
如果读取文件遇到了问题,那就需要这些知识帮助你正确地读入文件。
首先,我们要知道data.frame
是按列存储的,每一列是一个向量。readr的底层原理是:读取文件的前1000行,对1000行的每一列去推断它最可能的类型。所以以下情况就会出错:假设一列数据是numeric
类型,但是前1000行是整数,所以被错误地判断为integer
类型,导致这列后续的值读取出错;又或者这一列的前1000行是缺失值,会被错误地判断为character
类型,导致这列后续的值虽然被读入,但类型不对。你可以使用下面的选项推测类型时修改读取的行数:
guess_max = 1001
:读取前1001行推断每列类型。每一列数据最开始都被当做是字符串,readr一共有以下几类解析器,试图将其解析为对应的格式:
parse_logical()
和parse_integer()
parse_double()
parse_character()
:主要得处理编码问题parse_factor()
parse_datetime()
、parse_date()
和parse_time()
:针对日期时间处理调用read_csv()
失败后会返回解析失败的几行数据,用problems()
可以观察所有的出错结果。根据观察结果,你可以使用以下选项人工指定每一列的类型:
col_types = cols(x = col_integer(), y = col_character())
:指定x为整数类型,指定y为字符串类型。col_types = cols(.default = col_character())
:让未声明类型的每一列都按照字符串类型读取。上述的每个parse_xyz()
对应一个col_xyz()
类型。
readr提供两个函数将数据写入到磁盘:write_csv()
和write_tsv()
。在写出过程中,字符串的编码使用UTF-8,日期时间格式按照ISO8601输出。
如果希望输出的csv文件提供给Excel,请使用write_excel_csv()
,这个函数将在文件的开头写入一些标记,让Excel知道文件是使用UTF-8编码。
输出文本的常用选项有:
x=df
:要输出的data.frame
数据;path=file_name
:保存的文件路径;na="."
:代表空值的字符串输出;append=FALSE
:是否追加模式。除了输出文本,readr还支持输出二进制格式。RDS是R自定义的一种二进制编码格式,通过write_rds()
和read_rds()
可以完成这种格式文件的读写。