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)。
表1-14 数据导入函数read_excel主要参数英文对照
首先还是需要加载readxl包。尽管Hadley从2017年开始就一直在网络上宣传这个包已经属于tidyverse的一部分,但用户还是必须手动单独加载这个包。加载readxl包代码如下:
> library(readxl)
readxl包自带示范文件,使用函数readxl_example可以查看文件名字,以及获取文件路径,代码如下:
> readxl_example() [1] "clippy.xls" "clippy.xlsx" "datasets.xls" "datasets.xlsx" [5] "deaths.xls" "deaths.xlsx" "geometry.xls" "geometry.xlsx" [9] "type-me.xls" "type-me.xlsx"
获取示例文件的路径,可以先复制readxl_example函数运行后的结果,然后将其粘贴到read_excel函数的path参数中。下面的代码演示函数嵌套的方法,这种嵌套的代码书写方式能够在一定程度上简化代码和减少命名中间产物的频率。不过嵌套过多会使可读性变差,一般推荐只嵌套两层。将读取后的数据保存在iris中,执行str函数之后将会发现除了经典的data.frame之外,数据集还有另外两种类别,tbl_df和tbl,这两种类别的具体含义会在2.1节中详细介绍。函数嵌套的示例代码如下:
> iris <- read_excel(path = readxl_example(path = "datasets.xlsx")) > str(iris) ## Classes 'tbl_df', 'tbl' and 'data.frame': 150 obs. of 5 variables: ## $ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ... ## $ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ... ## $ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ... ## $ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ... ## $ Species : chr "setosa" "setosa" "setosa" "setosa" ...
之所以命名为iris,是因为这个范例Excel文件中的第一个工作表就是该经典数据集。函数excel_sheets可用于查询同一个文件中的工作表名称,其实现代码具体如下:
> excel_sheets(path = readxl_example(path = "datasets.xlsx")) ## [1] "iris" "mtcars" "chickwts" "quakes"
在datasets.xlsx中一共存在四个工作表,其中包含了四个最经典的R语言练习数据集。在此,希望读者可以自行浏览这几个数据集,对数据集的格式、变量名称等情况有一定程度的了解,在后续的章节中,笔者还会引用这几个数据集。
增加参数sheet或range可以读取指定工作表中的数据。这里需要注意的是,表1-14中提到了参数优先级的问题。对于一般常见的练习数据集,sheet参数指定的工作表已足够胜任。读者只需要记住range参数可以用来处理特殊情况,也就是说,当设置sheet后依然对读取到的数据不满意的情况可以考虑使用range。
下面的代码演示了sheet的两种传参方式:位置序号和名称。推荐读者采用后者。因为工作表被意外拖拽导致位置调换的情况常有发生,而位置意外发生调换之后读取的数据也会不同,这就增加了代码崩溃的风险。如果使用名称,则会降低发生错误的几率。示例代码如下:
> mtcars <- read_excel(path = readxl_example(path = "datasets.xlsx"),sheet = 2) > mtcars <- read_excel(path = readxl_example(path = "datasets.xlsx"),sheet = "mtcars")
对于后面的参数,读者可以根据表1-14中的解释,按照1.1节中的方法,每次增加一个参数,来逐步掌握每一个参数的功能,这里不再赘述。