整洁数据
在浩如烟海的数据类型中,有一种数据类型特别为统计学家所关注。这一类数据有如下特点:
- 每行是一个个案(case)、个体(individual)、观测点(observation)、分析单位(unit of analysis)
- 每列是一个变量(variable)、特征(feature)
- 每格是一个取值(value),即某个个案的某条特征
这一类数据,有一种说法是整洁数据(tidy data),和其他五花八门的杂乱数据(messy data)相对。
整洁数据的结构非常清晰,通过行和列,可以锁定每个格子数值的含义。
下面是一些整洁数据的示例:
一、starwars 星球大战角色数据(87行,14列)
Luke Skywalker |
172 |
77 |
blond |
fair |
blue |
19.0 |
male |
C-3PO |
167 |
75 |
NA |
gold |
yellow |
112.0 |
none |
R2-D2 |
96 |
32 |
NA |
white, blue |
red |
33.0 |
none |
Darth Vader |
202 |
136 |
none |
white |
yellow |
41.9 |
male |
Leia Organa |
150 |
49 |
brown |
light |
brown |
19.0 |
female |
Owen Lars |
178 |
120 |
brown, grey |
light |
blue |
52.0 |
male |
二、billboard 歌曲榜单数据(79行,317列)
2 Pac |
Baby Don’t Cry (Keep… |
2000-02-26 |
87 |
82 |
72 |
77 |
87 |
2Ge+her |
The Hardest Part Of … |
2000-09-02 |
91 |
87 |
92 |
NA |
NA |
3 Doors Down |
Kryptonite |
2000-04-08 |
81 |
70 |
68 |
67 |
66 |
3 Doors Down |
Loser |
2000-10-21 |
76 |
76 |
72 |
69 |
67 |
504 Boyz |
Wobble Wobble |
2000-04-15 |
57 |
34 |
25 |
17 |
17 |
98^0 |
Give Me Just One Nig… |
2000-08-19 |
51 |
39 |
34 |
26 |
26 |
三、diamonds 钻石数据(53940行,10列)
0.23 |
Ideal |
E |
SI2 |
61.5 |
55 |
326 |
3.95 |
3.98 |
2.43 |
0.21 |
Premium |
E |
SI1 |
59.8 |
61 |
326 |
3.89 |
3.84 |
2.31 |
0.23 |
Good |
E |
VS1 |
56.9 |
65 |
327 |
4.05 |
4.07 |
2.31 |
0.29 |
Premium |
I |
VS2 |
62.4 |
58 |
334 |
4.20 |
4.23 |
2.63 |
0.31 |
Good |
J |
SI2 |
63.3 |
58 |
335 |
4.34 |
4.35 |
2.75 |
0.24 |
Very Good |
J |
VVS2 |
62.8 |
57 |
336 |
3.94 |
3.96 |
2.48 |
tidyverse
本文是对 tidyverse 的入门介绍。
tidyverse (直译为``整洁宇宙’’)整合了一系列主要处理、分析整洁数据的R包(R packages)。每个包里面都有大量的函数。其特点是函数的命名、语法、用法非常整洁统一。
# 加载 tidyverse 包
library(tidyverse)
Warning: package 'ggplot2' was built under R version 4.3.3
Warning: package 'stringr' was built under R version 4.3.2
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr 1.1.2 ✔ readr 2.1.4
✔ forcats 1.0.0 ✔ stringr 1.5.1
✔ ggplot2 3.5.1 ✔ tibble 3.2.1
✔ lubridate 1.9.2 ✔ tidyr 1.3.0
✔ purrr 1.0.1
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ tidyr::extract() masks magrittr::extract()
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag() masks stats::lag()
✖ purrr::set_names() masks magrittr::set_names()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
在载入 tidyverse 时,可能会出现类似上面的一些警告语,它们不会影响 tidyverse 的正常使用,请无须担心。
tidyverse 为整洁数据设计了一种数据格式,叫作 tibble。这个词是 tidy 和 table 的结合,顾名思义,特指整洁数据。它相当于Excel里的表格(整洁的才行)、Stata 里的数据、Python 里的 Pandas 数据框等。
在数据科学中,整洁数据是最主流的数据形式。尽管我们日常生活中,可以看到形形色色的数据呈现形式(比如12306列车时间表、网购的商品列表等),但是它们的底层数据都是很整洁的。
打印 tibble
在接下来的几章,我将以 diamonds 钻石数据为示例数据。
# A tibble: 53,940 × 10
carat cut color clarity depth table price x y z
<dbl> <ord> <ord> <ord> <dbl> <dbl> <int> <dbl> <dbl> <dbl>
1 0.23 Ideal E SI2 61.5 55 326 3.95 3.98 2.43
2 0.21 Premium E SI1 59.8 61 326 3.89 3.84 2.31
3 0.23 Good E VS1 56.9 65 327 4.05 4.07 2.31
4 0.29 Premium I VS2 62.4 58 334 4.2 4.23 2.63
5 0.31 Good J SI2 63.3 58 335 4.34 4.35 2.75
6 0.24 Very Good J VVS2 62.8 57 336 3.94 3.96 2.48
7 0.24 Very Good I VVS1 62.3 57 336 3.95 3.98 2.47
8 0.26 Very Good H SI1 61.9 55 337 4.07 4.11 2.53
9 0.22 Fair E VS2 65.1 61 337 3.87 3.78 2.49
10 0.23 Very Good H VS1 59.4 61 338 4 4.05 2.39
# ℹ 53,930 more rows
在R的界面中,tibble 数据的输出格式会像上面这样。从上到下,
# A tibble: 10 × 10
表示当前 tibble 共有10行、10列
carat cut ...
这一行是变量名
<dbl> <ord> ...
这一行是变量类型,比如
- 数值型(
<dbl>
)
- 整数型(
<int>
)
- 有序类别型(
<ord>
)
1 1.5 Very Good
从这一行开始,都是钻石的具体数据了
如果你的 tibble 比较大,有很多行、很多列,tibble 在打印时会自动帮你隐藏多余的行和列,比方说
# A tibble: 87 × 14
name height mass hair_color skin_color eye_color birth_year sex gender
<chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
1 Luke Sk… 172 77 blond fair blue 19 male mascu…
2 C-3PO 167 75 <NA> gold yellow 112 none mascu…
3 R2-D2 96 32 <NA> white, bl… red 33 none mascu…
4 Darth V… 202 136 none white yellow 41.9 male mascu…
5 Leia Or… 150 49 brown light brown 19 fema… femin…
6 Owen La… 178 120 brown, gr… light blue 52 male mascu…
7 Beru Wh… 165 75 brown light blue 47 fema… femin…
8 R5-D4 97 32 <NA> white, red red NA none mascu…
9 Biggs D… 183 84 black light brown 24 male mascu…
10 Obi-Wan… 182 77 auburn, w… fair blue-gray 57 male mascu…
# ℹ 77 more rows
# ℹ 5 more variables: homeworld <chr>, species <chr>, films <list>,
# vehicles <list>, starships <list>
在这里,
# ℹ 77 more rows
表示省略了77行
# ℹ 5 more variables: homeworld <chr>, ...
表示省略了5个变量,并列出了省略的变量名、变量类型
请注意,这里打印时省略的变量和个案,不影响数据本身的完整。
列的性质
从上面可以看到,同样省略了一些行和列,tibble 打印了变量名、变量类型等信息,却丝毫不介绍省略的其他个案。这是为什么呢?
在整洁数据中,相对于行,列(变量)有一些特殊的性质:
- 每一列都有名称(变量名)
- 每一列只能储存同种类型的数值,不能“混搭”,比方说
- 每一列都可以统计
- A开头姓名的比例(约
5.7%
)
- 身高高于170吗?
代码
# 仅供参考,不需要掌握
starwars %>%
summarise(
percentage = sprintf(
"%.1f%%",
mean(str_detect(name, "^A")) * 100
)
)
# A tibble: 1 × 1
percentage
<chr>
1 5.7%
这里统计了A开头姓名的比例约为5.7%
。
代码
# 仅供参考,不需要掌握
starwars %>%
transmute(
height,
`height > 170` = height > 170
)
# A tibble: 87 × 2
height `height > 170`
<int> <lgl>
1 172 TRUE
2 167 FALSE
3 96 FALSE
4 202 TRUE
5 150 FALSE
6 178 TRUE
7 165 FALSE
8 97 FALSE
9 183 TRUE
10 182 TRUE
# ℹ 77 more rows
这里判断了各个角色的身高有没有高于170,判断结果为TRUE
或FALSE
。
整理成表格如下:
必须起名(具名性) |
不需要 |
一定同类(同质性) |
不一定 |
可以统计(算术性) |
不可以 |
列的类型
列,或者``变量’’,在 R 里面用向量(矢量,vector)来存储。下面介绍一些常见的变量类型:
- 数值型(numeric),包括实数型(double, real)和整数型(integer)
- 逻辑型(logical),包括 TRUE 和 FALSE
- 字符型(character),包括各种长度的文本
- 类别型(factor)、标签型(haven label),通常是数值型变量加上标签
- 日期型(date)、日期时间型(datetime),本质是数值型
- 几何型(geometry),来自 sf 包,包括点、线、面等,用于空间分析和画图
- 其他一维对象
- 二维乃至多维对象,比如一列 tibbles,每个单元格存储一个 tibble