前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >「Geek-r」数据导入

「Geek-r」数据导入

作者头像
王诗翔呀
发布于 2020-07-03 09:38:00
发布于 2020-07-03 09:38:00
1.4K00
代码可运行
举报
文章被收录于专栏:优雅R优雅R
运行总次数:0
代码可运行

本部分内容是我写的 R book 的数据导入部分,写了好久了。。。断断续续的,只完成了一半的内容吧。已经写的的内容可以通过原文阅读。

在掌握一定的 R 编程技能后,我们开始迈入数据分析的殿堂。大部分数据分析事务的数据都不是通过 R 创建,而是来自于各种数据收集软硬件、渠道,包括 Excel、网络等。本章聚焦于如何将数据导入 R 中以便于开始数据分析。对于本章的内容,读者既可以系统地从头到尾深入阅读学习,也可以根据自己实际工作需要或时间限制选择一些重点或感兴趣内容进行掌握。

本章的重点内容包括符号分隔文件、Excel 文件、JSON 文件以及 R 支持的数据格式 RData 和 RDS,其他格式的数据将放到本章【常见问题与方案】一节作为补充介绍。

3.1 符号分隔文件

符号分隔文件是最最常用的数据文件格式,知道如何导入它是读者的必备技能。这里的符号泛指一切可以用作数据内容分隔的符号,常见的包括逗号(,),制表符(\t),我们常称它们为 CSV 文件和 TSV 文件。

3.1.1 CSV

CSV 文件常以 .csv 作为文件拓展名,比如接下来我们会导入的 mtcars.csv。注意,文件拓展名并不会影响文件本身的内容,它只是用来方便帮助人们快速的了解内容格式,另外支持其他一些程序的自动解读(在你的计算机上,不同的文件拓展名系统软件可以会对它们使用不同的图标,如 Word 文档和 PPT)。

一般规整的数据以行作为观测,列作为记录(变量、域),如一个班级同学的成绩。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
student,chinese,math,english
stu1,99,100,98
stu2,60,50,88

R 内置了 read.table() 函数用于便捷导入各类分隔符的文件。下面我们直接将这个成绩记录信息以文本的形式传入,结果会返回一个数据框:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
stu <- read.table(text = "
student,chinese,math,english
stu1,99,100,98
stu2,60,50,88
", header = TRUE, sep = ",")
stu
#>   student chinese math english
#> 1    stu1      99  100      98
#> 2    stu2      60   50      88
class(stu)
#> [1] "data.frame"

实际上要处理的数据并不会这么的少,一般会以文件的形式存储在计算机磁盘中。下面我们依旧使用 read.table() 函数完成 CSV 文件数据的导入。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
cars <- read.table(file = "data/data-import/mtcars.csv", header = TRUE, sep = ",")

操作完成了,我们检查下头几行:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
head(cars)
#>    mpg cyl disp  hp drat    wt  qsec vs am gear carb
#> 1 21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
#> 2 21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
#> 3 22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
#> 4 21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
#> 5 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
#> 6 18.1   6  225 105 2.76 3.460 20.22  1  0    3    1

除了使用 read.table(),我们还可以使用内置的 read.csv() 函数完成 CSV 文件的读入。与 read.table() 不同的时,我们无需再指定分隔符,因为该函数本身就是为了 CSV 文件设计的。另外函数默认将 header 选项设定为 TRUE,即有列名,所以我们也无需指定它,因而读取操作就被简化了:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
cars2 <- read.csv(file = "data/data-import/mtcars.csv")
head(cars2)
#>    mpg cyl disp  hp drat    wt  qsec vs am gear carb
#> 1 21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
#> 2 21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
#> 3 22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
#> 4 21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
#> 5 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
#> 6 18.1   6  225 105 2.76 3.460 20.22  1  0    3    1

上述的读取操作基于 R 内置的函数实现,无需载入任何其他三方包就可以完成数据的读入,这在针对小型数据(集)或者计算机条件受限时(无法安装和使用三方包)非常有用。在这种常规以符号分隔的文件数据读取方面,我必须提及 2 个三方包:readrdata.table。它们都能以极快的速度读取大内存数据,推荐读者作为常规导入操作的解决方案。

**tidyverse**[1] 是 R 语言大神 Hadley[2](以 ggplot2 作者闻名于世) 组织构建的一整套数据分析生态系统,包括读入、处理、建模与可视化等, **readr**[3] 包是 tidyverse 的一部分,用于完成数据的导入工作。

**data.table**[4] 包以 R 社区最快的数据读取和处理操作而著名,它主要是提供了一个增强版的数据框 data.table

根据 readr 包官方文档介绍,readr 包通常比 data.table 包慢大概 1.2~2 倍左右。不过它们各有特点,readr 包被设计用于更为常规的数据读取操作,而 data.table 的目标则是尽量的快。

为了体现上述两个包和内置函数的差别,这里我们构造一个较大的 CSV 文件进行简单的测试:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
huge_car <- cars[rep(1:32, 10000), ]

把这个数据先保存下来,然后再利用不同的工具进行导入。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
temp_csv <- tempfile(fileext = ".csv")
readr::write_csv(huge_car, path = temp_csv)

现在我们分别使用 system.time() 测试下 R 内置的 read.csv() 函数与 readr 提供的 read_csv() 以及 data.table 提供的 fread() 的读取效率。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
time1 <- system.time(
  z1 <- read.csv(temp_csv)
)
time1
#>  用户  系统  流逝 
#> 0.921 0.025 0.947
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
library(readr)

time2 <- system.time(
  z2 <-  read_csv(temp_csv)
)
time2
#>  用户  系统  流逝 
#> 0.311 0.023 0.346
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
library(data.table)

time3 <- system.time(
  z3 <- fread(temp_csv)
)
time3
#>  用户  系统  流逝 
#> 0.050 0.007 0.056

上面我们使用了 320000 行数据进行测试,在我的计算机上,内置的函数 read.csv() 总共花费了 0.947s,readrread_csv() 花费了 0.346s,而 data.tablefread() 仅用了 0.056s 左右。好的、适合的工具可以帮助我们极大地提升工作效率

如果我们进一步观察几种不同方式导入的数据格式,就会发现它们有些不太相同。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
z1
#>     mpg cyl  disp  hp drat    wt  qsec vs am gear carb
#> 1  21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
#> 2  21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
#> 3  22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
#> 4  21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
#> 5  18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
#> 6  18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
#> 7  14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
#> 8  24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
#> 9  22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
#> 10 19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
#> 11 17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
#> 12 16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3
#> 13 17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3
#> 14 15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3
#> 15 10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4
#> 16 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4
#> 17 14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4
#> 18 32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
#> 19 30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
#> 20 33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
#> 21 21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1
#> 22 15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2
#> 23 15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2
#> 24 13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4
#> 25 19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2
#> 26 27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1
#> 27 26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2
#> 28 30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2
#> 29 15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4
#> 30 19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6
#> 31 15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8
#> 32 21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2
#> 33 21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
#> 34 21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
#> 35 22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
#> 36 21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
#> 37 18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
#> 38 18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
#> 39 14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
#> 40 24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
#> 41 22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
#> 42 19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
#> 43 17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
#> 44 16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3
#> 45 17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3
#> 46 15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3
#> 47 10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4
#> 48 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4
#> 49 14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4
#> 50 32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
#> 51 30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
#> 52 33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
#> 53 21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1
#> 54 15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2
#> 55 15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2
#> 56 13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4
#> 57 19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2
#> 58 27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1
#> 59 26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2
#> 60 30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2
#> 61 15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4
#> 62 19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6
#> 63 15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8
#> 64 21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2
#> 65 21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
#> 66 21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
#> 67 22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
#> 68 21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
#> 69 18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
#> 70 18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
#> 71 14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
#> 72 24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
#> 73 22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
#> 74 19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
#> 75 17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
#> 76 16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3
#> 77 17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3
#> 78 15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3
#> 79 10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4
#> 80 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4
#> 81 14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4
#> 82 32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
#> 83 30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
#> 84 33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
#> 85 21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1
#> 86 15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2
#> 87 15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2
#> 88 13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4
#> 89 19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2
#> 90 27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1
#>  [ reached 'max' / getOption("max.print") -- omitted 319910 rows ]
z2
#> # A tibble: 320,000 x 11
#>      mpg   cyl  disp    hp  drat    wt  qsec    vs
#>    <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#>  1  21       6  160    110  3.9   2.62  16.5     0
#>  2  21       6  160    110  3.9   2.88  17.0     0
#>  3  22.8     4  108     93  3.85  2.32  18.6     1
#>  4  21.4     6  258    110  3.08  3.22  19.4     1
#>  5  18.7     8  360    175  3.15  3.44  17.0     0
#>  6  18.1     6  225    105  2.76  3.46  20.2     1
#>  7  14.3     8  360    245  3.21  3.57  15.8     0
#>  8  24.4     4  147.    62  3.69  3.19  20       1
#>  9  22.8     4  141.    95  3.92  3.15  22.9     1
#> 10  19.2     6  168.   123  3.92  3.44  18.3     1
#> # … with 319,990 more rows, and 3 more variables:
#> #   am <dbl>, gear <dbl>, carb <dbl>
z3
#>          mpg cyl  disp  hp drat    wt  qsec vs am gear
#>      1: 21.0   6 160.0 110 3.90 2.620 16.46  0  1    4
#>      2: 21.0   6 160.0 110 3.90 2.875 17.02  0  1    4
#>      3: 22.8   4 108.0  93 3.85 2.320 18.61  1  1    4
#>      4: 21.4   6 258.0 110 3.08 3.215 19.44  1  0    3
#>      5: 18.7   8 360.0 175 3.15 3.440 17.02  0  0    3
#>     ---                                               
#> 319996: 30.4   4  95.1 113 3.77 1.513 16.90  1  1    5
#> 319997: 15.8   8 351.0 264 4.22 3.170 14.50  0  1    5
#> 319998: 19.7   6 145.0 175 3.62 2.770 15.50  0  1    5
#> 319999: 15.0   8 301.0 335 3.54 3.570 14.60  0  1    5
#> 320000: 21.4   4 121.0 109 4.11 2.780 18.60  1  1    4
#>         carb
#>      1:    4
#>      2:    4
#>      3:    1
#>      4:    1
#>      5:    2
#>     ---     
#> 319996:    2
#> 319997:    4
#> 319998:    6
#> 319999:    8
#> 320000:    2

这个所谓的不同与结构中存储的数据信息无关,而是在不同的设计上。我们检查一下它们的类属性:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class(z1)
#> [1] "data.frame"
class(z2)
#> [1] "spec_tbl_df" "tbl_df"      "tbl"        
#> [4] "data.frame"
class(z3)
#> [1] "data.table" "data.frame"

不难看到这 3 个对象存在共有的类名 data.frame。我们使用内置函数读入数据仅包含该类名,而后两者还存在其他的类名,这是因为后两者继承了 data.frame。简单地说,后两者是增强版的 data.frame,它们赋予了不同于 R 内置数据框的特性,读者可以观察到的最明显的区别就是它们打印信息的方式不同。

通常地说,我们将对象 z2 称为 tibble,因为它是由 **tibble**[5] 包创建的类,是 tidyverse 系列包的数据结构基础,设计者称它为现代的 data.frame,在基础的使用方式上与 data.frame 并无不同,读者可以通过官方文档阅读更为详细的介绍。

对象 z3 则常被称为 data.table,因为它的类名和包名都是 data.table.

tibbledata.table 都有一系列强大高效的数据处理方法和操作,它们将在第 4[6] 章进行介绍。

3.1.2 TSV 与其他 CSV 变体

另一种流行的数据存储格式是 TSV,与 CSV 唯一不同的是 TSV 使用制表符 \t 作为内容的分隔符。TSV 文件除了以 .tsv 作为文件拓展名,也常用 .txt 作为文件拓展名(并不是所有的 .txt 文件都是以制表符分隔)。

通过将 read.table() 函数中的 sep 参数设定为制表符,我们可以轻松完成该格式文件内容的读取:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mt <- read.table("data/data-import/mtcars.tsv", sep = "\t", header = TRUE)
mt
#>     mpg cyl  disp  hp drat    wt  qsec vs am gear carb
#> 1  21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
#> 2  21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
#> 3  22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
#> 4  21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
#> 5  18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
#> 6  18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
#> 7  14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
#> 8  24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
#> 9  22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
#> 10 19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
#> 11 17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
#> 12 16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3
#> 13 17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3
#> 14 15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3
#> 15 10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4
#> 16 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4
#> 17 14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4
#> 18 32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
#> 19 30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
#> 20 33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
#> 21 21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1
#> 22 15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2
#> 23 15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2
#> 24 13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4
#> 25 19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2
#> 26 27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1
#> 27 26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2
#> 28 30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2
#> 29 15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4
#> 30 19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6
#> 31 15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8
#> 32 21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2

readr 包提供了一系列的 read_*() 函数,方便用户将常见数据文件导入为 tibble

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mt2 <- read_tsv("data/data-import/mtcars.tsv")
mt2
#> # A tibble: 32 x 11
#>      mpg   cyl  disp    hp  drat    wt  qsec    vs
#>    <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#>  1  21       6  160    110  3.9   2.62  16.5     0
#>  2  21       6  160    110  3.9   2.88  17.0     0
#>  3  22.8     4  108     93  3.85  2.32  18.6     1
#>  4  21.4     6  258    110  3.08  3.22  19.4     1
#>  5  18.7     8  360    175  3.15  3.44  17.0     0
#>  6  18.1     6  225    105  2.76  3.46  20.2     1
#>  7  14.3     8  360    245  3.21  3.57  15.8     0
#>  8  24.4     4  147.    62  3.69  3.19  20       1
#>  9  22.8     4  141.    95  3.92  3.15  22.9     1
#> 10  19.2     6  168.   123  3.92  3.44  18.3     1
#> # … with 22 more rows, and 3 more variables:
#> #   am <dbl>, gear <dbl>, carb <dbl>

使用 data.table 则更为轻松,因为所有分隔格式的数据都可以通过 fread() 读取完成:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mt3 <- fread("data/data-import/mtcars.tsv")
mt3
#>      mpg cyl  disp  hp drat    wt  qsec vs am gear
#>  1: 21.0   6 160.0 110 3.90 2.620 16.46  0  1    4
#>  2: 21.0   6 160.0 110 3.90 2.875 17.02  0  1    4
#>  3: 22.8   4 108.0  93 3.85 2.320 18.61  1  1    4
#>  4: 21.4   6 258.0 110 3.08 3.215 19.44  1  0    3
#>  5: 18.7   8 360.0 175 3.15 3.440 17.02  0  0    3
#>  6: 18.1   6 225.0 105 2.76 3.460 20.22  1  0    3
#>  7: 14.3   8 360.0 245 3.21 3.570 15.84  0  0    3
#>  8: 24.4   4 146.7  62 3.69 3.190 20.00  1  0    4
#>  9: 22.8   4 140.8  95 3.92 3.150 22.90  1  0    4
#> 10: 19.2   6 167.6 123 3.92 3.440 18.30  1  0    4
#> 11: 17.8   6 167.6 123 3.92 3.440 18.90  1  0    4
#> 12: 16.4   8 275.8 180 3.07 4.070 17.40  0  0    3
#> 13: 17.3   8 275.8 180 3.07 3.730 17.60  0  0    3
#> 14: 15.2   8 275.8 180 3.07 3.780 18.00  0  0    3
#> 15: 10.4   8 472.0 205 2.93 5.250 17.98  0  0    3
#> 16: 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3
#> 17: 14.7   8 440.0 230 3.23 5.345 17.42  0  0    3
#> 18: 32.4   4  78.7  66 4.08 2.200 19.47  1  1    4
#> 19: 30.4   4  75.7  52 4.93 1.615 18.52  1  1    4
#> 20: 33.9   4  71.1  65 4.22 1.835 19.90  1  1    4
#> 21: 21.5   4 120.1  97 3.70 2.465 20.01  1  0    3
#> 22: 15.5   8 318.0 150 2.76 3.520 16.87  0  0    3
#> 23: 15.2   8 304.0 150 3.15 3.435 17.30  0  0    3
#> 24: 13.3   8 350.0 245 3.73 3.840 15.41  0  0    3
#> 25: 19.2   8 400.0 175 3.08 3.845 17.05  0  0    3
#> 26: 27.3   4  79.0  66 4.08 1.935 18.90  1  1    4
#> 27: 26.0   4 120.3  91 4.43 2.140 16.70  0  1    5
#> 28: 30.4   4  95.1 113 3.77 1.513 16.90  1  1    5
#> 29: 15.8   8 351.0 264 4.22 3.170 14.50  0  1    5
#> 30: 19.7   6 145.0 175 3.62 2.770 15.50  0  1    5
#> 31: 15.0   8 301.0 335 3.54 3.570 14.60  0  1    5
#> 32: 21.4   4 121.0 109 4.11 2.780 18.60  1  1    4
#>      mpg cyl  disp  hp drat    wt  qsec vs am gear
#>     carb
#>  1:    4
#>  2:    4
#>  3:    1
#>  4:    1
#>  5:    2
#>  6:    1
#>  7:    4
#>  8:    2
#>  9:    2
#> 10:    4
#> 11:    4
#> 12:    3
#> 13:    3
#> 14:    3
#> 15:    4
#> 16:    4
#> 17:    4
#> 18:    1
#> 19:    2
#> 20:    1
#> 21:    1
#> 22:    2
#> 23:    2
#> 24:    4
#> 25:    2
#> 26:    1
#> 27:    2
#> 28:    2
#> 29:    4
#> 30:    6
#> 31:    8
#> 32:    2
#>     carb

为什么 fread() 没有设置分隔符却可以导入 CSV 和 TSV 文件?其中的巧妙在于该函数的内部会自动检测数据文件内的分隔符号。

通过查看该函数的参数,我们可以看到 sep = "auto",这个参数我们可以人为指定,以适应不同的需求场景。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
args(fread)
#> function (input = "", file = NULL, text = NULL, cmd = NULL, sep = "auto", 
#>     sep2 = "auto", dec = ".", quote = "\"", nrows = Inf, header = "auto", 
#>     na.strings = getOption("datatable.na.strings", "NA"), stringsAsFactors = FALSE, 
#>     verbose = getOption("datatable.verbose", FALSE), skip = "__auto__", 
#>     select = NULL, drop = NULL, colClasses = NULL, integer64 = getOption("datatable.integer64", 
#>         "integer64"), col.names, check.names = FALSE, encoding = "unknown", 
#>     strip.white = TRUE, fill = FALSE, blank.lines.skip = FALSE, 
#>     key = NULL, index = NULL, showProgress = getOption("datatable.showProgress", 
#>         interactive()), data.table = getOption("datatable.fread.datatable", 
#>         TRUE), nThread = getDTthreads(verbose), logical01 = getOption("datatable.logical01", 
#>         FALSE), keepLeadingZeros = getOption("datatable.keepLeadingZeros", 
#>         FALSE), yaml = FALSE, autostart = NA, tmpdir = tempdir()) 
#> NULL

上面展示出 fread() 存在众多的参数设置。R 的易用与友好在于此,众多 R 包提供的函数大多已经为用户恰当地设置好了默认选项,用户无需经过繁琐的操作即可快速获取所需的结果。

在学习了如何导入 TSV 文件后,我们应该能够归纳出 CSV、TSV 本质上是一类数据格式文件。例如,我们也可以使用分号 ;(西方不少国家的逗号分隔文件就是以分号分隔的文件)。我们统一以 CSV 作为代表,将其他类似格式文件称为 CSV 变体。

3.2 Excel

Excel 是知名的微软 Office 套件之一,提供了日常的表格数据处理方案。尽管大多数数据分析人员不会产生和不想处理 Excel 文件,但由于它随着微软系统的流行而被广泛使用,因此读入 Excel 中的数据成为数据处理无法避免的日常工作任务之一。

R 中有诸多拓展包可以导入 Excel 中的数据,其中最为推荐的就是本部分介绍的 **readxl**[7] 包。

使用该包,导入 Excel 中的数据可以像读入 CSV 文件一样简单。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
library(readxl)
mt_excel <- read_excel("data/data-import/mtcars.xlsx")
head(mt_excel)
#> # A tibble: 6 x 11
#>     mpg   cyl  disp    hp  drat    wt  qsec    vs    am
#>   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1  21       6   160   110  3.9   2.62  16.5     0     1
#> 2  21       6   160   110  3.9   2.88  17.0     0     1
#> 3  22.8     4   108    93  3.85  2.32  18.6     1     1
#> 4  21.4     6   258   110  3.08  3.22  19.4     1     0
#> 5  18.7     8   360   175  3.15  3.44  17.0     0     0
#> 6  18.1     6   225   105  2.76  3.46  20.2     1     0
#> # … with 2 more variables: gear <dbl>, carb <dbl>

read_excel() 同时支持 .xlsxlsx 两者文件格式。

Excel 文件支持多个表格(Sheet),这种情况下默认第 1 个 Sheet 的内容会被读入。通过简单的设置,读者也可以轻松导入任意 Sheet 的内容。

下面通过 readxl 包的官方示例展示这一过程。

我们先查看下该包提供的示例数据:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
readxl_example()
#>  [1] "clippy.xls"    "clippy.xlsx"   "datasets.xls" 
#>  [4] "datasets.xlsx" "deaths.xls"    "deaths.xlsx"  
#>  [7] "geometry.xls"  "geometry.xlsx" "type-me.xls"  
#> [10] "type-me.xlsx"

选一个文件并查看其所在的路径:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
readxl_example("datasets.xlsx")
#> [1] "/Users/wsx/R_Library/readxl/extdata/datasets.xlsx"
# 将路径保存备用
excel_path <- readxl_example("datasets.xlsx")

如果将路径传入 excel_sheets() 函数,读者可以获取文件中存在的 Sheets。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
excel_sheets(excel_path)
#> [1] "iris"     "mtcars"   "chickwts" "quakes"

然后依旧是使用 read_excel() 函数,设定想要读入的 Sheet 名字即可。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
iris <- read_excel(excel_path, sheet = "iris")
head(iris)
#> # A tibble: 6 x 5
#>   Sepal.Length Sepal.Width Petal.Length Petal.Width
#>          <dbl>       <dbl>        <dbl>       <dbl>
#> 1          5.1         3.5          1.4         0.2
#> 2          4.9         3            1.4         0.2
#> 3          4.7         3.2          1.3         0.2
#> 4          4.6         3.1          1.5         0.2
#> 5          5           3.6          1.4         0.2
#> 6          5.4         3.9          1.7         0.4
#> # … with 1 more variable: Species <chr>

关于函数的更多用法读者可以通过 ?read_excel() 查看。

有时候人们会在同一个 Excel Sheet 中放置多个表格信息,这种情况无法通过简单地使用 readxl 包读入数据。只要数据是有规律的,读者可以尝试下通过 **tidycells**[8] 包导入数据。

tidycells 包示例数据

图 3.1: tidycells 包示例数据格式

具体的使用请读者参照 README[9] 进行学习。

参考资料

[1]

tidyverse: https://github.com/tidyverse/

[2]

Hadley: https://github.com/hadley

[3]

readr: https://github.com/tidyverse/readr

[4]

data.table: https://github.com/Rdatatable/data.table

[5]

tibble: https://github.com/tidyverse/tibble

[6]

4: https://shixiangwang.gitee.io/geek-r-tutorial/clean.html#clean

[7]

readxl: https://github.com/tidyverse/readxl

[8]

tidycells: https://github.com/r-rudra/tidycells

[9]

README: https://github.com/r-rudra/tidycells/blob/master/README.md

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-05-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 优雅R 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
dplyr排完序,行名没了,有点方!!!
R包dplyr可用于处理R内部或者外部的结构化数据,相较于plyr包,dplyr专注接受dataframe对象, 大幅提高了速度,并且提供了更稳健的数据库接口。%>%来自dplyr包的管道函数,其作用是将前一步的结果直接传参给下一步的函数,从而省略了中间的赋值步骤,可以大量减少内存中的对象,节省内存。
生信交流平台
2020/08/06
4420
R语言:图形
常用的图形,这里给出案例: barplot 条形图、单向量条形图 > attach(mtcars) The following object is masked from package:ggplot2: mpg > names(mtcars) [1] "mpg" "cyl" "disp" "hp" "drat" "wt" [7] "qsec" "vs" "am" "gear" "carb" "manuf" > barplot(table(cy
努力在北京混出人样
2019/02/18
3.1K0
R语言入门 Chapter03 | 列表
这篇文章讲述的是R语言中关于列表的相关知识。希望这篇R语言文章对您有所帮助!如果您有想学习的知识或建议,可以给作者留言~
不温卜火
2020/10/28
3130
R语言入门 Chapter03 | 列表
R语言日常笔记(1)filter函数
在处理数据时,过滤数据是最基本的操作之一。 如果想删除一部分无效或者根本不感兴趣的数据。 dplyr有filter()函数来做这样的过滤。 使用dplyr,可以帮助使用者像使用SQL或者传统BI工具以简单且更直观的方式进行过滤。
用户1359560
2019/07/16
23K0
数据分析大作战,SQL V.S. Python,来看看这些考题你都会吗 ⛵
SQL与Pandas都可以完成大部分数据分析需求。本文用SQL与Pands逐一实现10类核心数据分析需求,轻松进行对比学习:数据选择、限制、统计计数、排序、新字段生成、数据选择、数据分组、统计均值、方差、极差/范围。
ShowMeAI
2022/08/26
3550
数据分析大作战,SQL V.S. Python,来看看这些考题你都会吗 ⛵
dplyr-cli:在Linux Terminal上直接执行dplyr
熟悉R的朋友都会知道, dplyr包是对原始的数据集进行清洗、整理以及变换的有力武器之一。但是其使用会局限于你需要有打开R/R studio或者通过R脚本来执行 dplyr。对于这个问题,今天即将需要介绍的 dplyr-cli就能很好的解决这个问题。
生信菜鸟团
2020/05/19
2.2K0
R语言读CSV、txt文件方式以及read.table read.csv 和readr(大数据读取包)
首先准备测试数据*(mtcars) 分别为CSV.    TXT read.table 默认形式读取CSV(×)与TXT(效果理想) ① > test<-read.table("C:/Users/ad
学到老
2018/03/19
8.4K0
R语言读CSV、txt文件方式以及read.table read.csv 和readr(大数据读取包)
Pandas | 数据排序
函数格式:Series.sort_values(ascending=True, inplace=False)
生信real
2022/12/20
7520
16. R编程(二:基本数据类型及其操作之因子、矩阵、数据框和列表)
使用rbind(),操作同cbind() 加和 colSums() 或 rowSums()
北野茶缸子
2021/12/17
2.9K0
16. R编程(二:基本数据类型及其操作之因子、矩阵、数据框和列表)
R数据科学-1(dplyr)
如今数据分析如火如荼,R与Python大行其道。你还在用Excel整理数据么,你还在用spss整理数据么。
Jamesjin63
2022/10/25
1.8K0
R数据科学-1(dplyr)
R数据科学整洁之道:使用dtplyr处理大文件
有群友问如果文件比较大,读入 R 比较慢怎么办?我告诉他用 data.table 包的 fread 读取。
简说基因
2022/11/11
6210
分组统计你只想到group_by操作吗?
最近在研究excel透视图,想到好像自己在R-分组操作并不是很流畅,顺便学习分享一下。R自带数据集比较多,今天就选择一个我想对了解的mtcars数据集带大家学习一下R语言中的分组计算(操作)。
1480
2019/09/02
1.1K0
R语言数据集合并、数据增减、不等长合并
1、merge(a,b),纯粹地把两个数据集合在一起,没有沟通a、b数据集的by,这样出现的数据很多,相当于a*b条数据;
悟乙己
2019/05/28
13.9K0
「R」ggplot结合点图与箱线图的问题与解决
最近在使用ggplot2对箱线图叠加点图是发现奇怪的现象,只要我改变点的形状,绘图就出问题了。
王诗翔呀
2021/12/13
1.8K0
「R」ggplot结合点图与箱线图的问题与解决
R tips:dplyr编程
dplyr的函数由于使用tidy evaluation(R中的一种非标准执行(NSE)实现方式)的方法,可以使得其具有更好的易用性:变量不需要绝对引用和引号包裹。
生信菜鸟团
2020/07/02
1.3K0
「R」数据可视化8:棒棒图
首先让我们来看几张棒棒糖图。可以发现实际上就是一根柱子加上一个圆,其实类似传统的柱状图。但是它可以给我们更多的信息,因为圆和下面的棒子可以代表同一组数据,也可以代表两组数据。“糖”和“棒子”的颜色也一样,可以表示同一个信息也可以表示不同维度的信息。另外,我们还可以变成双头棒棒糖,在棒子的两端分别展现不同的数据。不喜欢传统的圆形?想要亲手DIY?也没有问题,我们可以把传统的圆形糖换成其他图片(比如漫威),以更加直观的展示信息。我们也可以在圈中标记具体的数值,让读者一目了然。
王诗翔呀
2020/07/06
1.2K0
「R」数据可视化8:棒棒图
「R」分析之前的数据准备
paste函数可以将多个字符型向量连接成一个向量,默认向量的值是用空格分隔的,我们可以通过sep参数指定分隔符号,而collapse参数可以用来指定这些值之间的连接符号。
王诗翔呀
2020/07/03
1.5K0
R语言第二章数据处理⑦dplyr包(2)列处理目录列名
还有另一个选项可以避免连续重新输入列名:one_of()。 您可以预先设置列名,然后在select()语句中通过将它们包装在one_of()中或使用!!运算符来引用它们。
用户1359560
2018/12/28
1.9K0
绘图系列|R-corrplot相关图
初步接触数据集,探索性分析后,经常需要做一个相关分析,得到各变量间的相关系数以及显著性水平。
生信补给站
2020/08/06
1K0
Broom |tidy up a bit,模型,检验结果一键输出!
使用lm/glm/t.test/chisq.test等模型或者检验完成分析后,结果怎么提?
生信补给站
2020/08/06
1K0
相关推荐
dplyr排完序,行名没了,有点方!!!
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档