抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

除数据转换之外,数据关系的处理也是数据分析处理的重要一环。同样地,在 tidyverse 包中,实现该步骤的内容也是 dplyr 包 。

表关系

表关系按关系对象可以分为表内关系和表间关系两种。表内关系简单地说就是各行之间的元素关系和各列之间的元素关系,而表间关系相对就要复杂得多。而通常情况下,实际应用中使用的数据集经常以多张表按一定组织形式进行存储。存在于多个表中的这种数据也被统称为关系数据

表间关系最为简单基础的关系是两张表之间的关系,而处理两张表之间的关系数据的基本操作有:

  • 合并连接:向数据框中加入新变量,新变量的值是另一个数据框中的匹配观测
  • 筛选连接:根据与另一个数据框中的观测匹配与否,筛选数据框中的观测
  • 集合操作:将观测作为集合元素进行处理

说明中的数据框在统计概念上是指数据表,在 tidyverse 包中一般是指 tibble

用于链接每对数据表的变量称为。键是能唯一标识观测的变量(或变量集合)。当某一变量列的数据互不相同时,特定的变量值就能够确定特定的观测行。当某一变量列的数据有重复元素出现时,那么只根据该变量列的特定变量值可能无法确定某个特定观测行,因此就需要多个变量列(即变量集合)来确定观测行。键的类型主要有两种:

  • 主键:唯一标识其所在数据表中的观测,“一对多”、“一对一”型关系中“一”端表的标识变量
  • 外键:唯一标识另一个数据表中的观测,“一对多”型关系中”多“端表的标识变量

一个变量既可能是主键,也可能是外键;也可能不是键,还可能既是主键也是外键。

如果一张表中不含有主键或很难找到主键,可以使用 mutate() 函数和 row_number() 函数为数据表添加一个主键,这个主键也被称为代理键

通过数据表中的主键和另一张数据表与之对应的外键便可以构成关系。关系通常是一对多的。

主键中最好确保没有 NA 值

表关系操作

合并连接

合并连接可以将两个表格中的变量组合起来,先通过两个表格的键匹配观测,然后将一个表格中的变量复制到另一个表格中。

用以下的 xymn 四个数据表进行简要说明:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
x <- tribble(
~key_x, ~val_x,
1, "alpha",
2, "beta",
3, "gamma",
)

y <- tribble(
~key_y, ~val_y,
1, "a",
2, "b",
7, "g",
)

m <- tribble(
~key_m, ~val_m,
1, "x_i",
2, "y_i",
2, "y_j",
3, "z_i",
3, "z_j",
3, "z_k",
4, "O",
)

n <- tribble(
~key_n, ~val_n,
1, "rho",
2, "theta_a",
2, "theta_b",
3, "phi",
4, "pi",
4, "e",
)

合并连接分为两种:内连接外连接

内连接

内连接是将两个表中对应键相等的观测相连接,并生成一个新数据框。基本语法为:inner_join(x, y, by = NULL) 。其中 xy 是两个数据框,参数 by 为匹配键名,值以字符向量的形式给出。

*_join 系列函数的 by 参数的接受格式为字符向量,形式有键对向量、键名向量等,具体地,有以下几种格式:

x 和 y 的匹配示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
> x
#> # A tibble: 3 x 2
#> key_x val_x
#> <dbl> <chr>
#> 1 1 alpha
#> 2 2 beta
#> 3 3 gamma
> y
#> # A tibble: 3 x 2
#> key_y val_y
#> <dbl> <chr>
#> 1 1 a
#> 2 2 b
#> 3 7 g
> inner_join(x, y, by = c("key_x" = "key_y"))
#> # A tibble: 2 x 3
#> key_x val_x val_y
#> <dbl> <chr> <chr>
#> 1 1 alpha a
#> 2 2 beta b

如果主键和外键的变量名相同(例如都为 key),那么可以直接使用 “key” 代替 “key_x” = “key_y” 。如果匹配的变量名不止一对,那么可以在 “key_x” = “key_y” 后附加上对应的键对或键名,并用逗号隔开以形成向量元素。当需要匹配的变量只有一对时,也可以直接使用字符对象而不是字符向量

由于内连接会将没有匹配的行丢弃,进而造成观测丢失,因此不太适合在数据处理中使用。

外连接

和内连接相似,外连接也是将两个表中对应键相等的观测相连接。但外连接会将未匹配的观测的对应变量值用 NA 填充。外连接有三种类型:

  • 左连接:保留 x 中的所有观测,对应函数为 left_join()
  • 右连接:保留 y 中的所有观测,对应函数为 right_join()
  • 全连接:保留 x 和 y 中的所有观测,对应函数为 full_join()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
> left_join(x, y, by = c("key_x" = "key_y"))
#> # A tibble: 3 x 3
#> key_x val_x val_y
#> <dbl> <chr> <chr>
#> 1 1 alpha a
#> 2 2 beta b
#> 3 3 gamma NA
> right_join(x, y, by = c("key_x" = "key_y"))
#> # A tibble: 3 x 3
#> key_x val_x val_y
#> <dbl> <chr> <chr>
#> 1 1 alpha a
#> 2 2 beta b
#> 3 7 NA g
> full_join(x, y, by = c("key_x" = "key_y"))
#> # A tibble: 4 x 3
#> key_x val_x val_y
#> <dbl> <chr> <chr>
#> 1 1 alpha a
#> 2 2 beta b
#> 3 3 gamma NA
#> 4 7 NA g

重复键

当键中的值不唯一时,就会造成重复键的状况。重复键的匹配机制遵循笛卡尔积,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
> inner_join(m, n, by = c("key_m" = "key_n"))
#> # A tibble: 10 x 3
#> key_m val_m val_n
#> <dbl> <chr> <chr>
#> 1 1 x_i rho
#> 2 2 y_i theta_a
#> 3 2 y_i theta_b
#> 4 2 y_j theta_a
#> 5 2 y_j theta_b
#> 6 3 z_i phi
#> 7 3 z_j phi
#> 8 3 z_k phi
#> 9 4 O pi
#> 10 4 O e

重复键在缺失值方面和非重复键一致

筛选连接

筛选连接和合并连接在匹配观测的方式上相同,但前者作用于观测,后者作用于变量。筛选连接有两种类型:半连接反连接

  • 半连接的基本语法为:semi_join(x, y) ,作用是保留 x 表中与 y 表中的观测相匹配的所有观测
  • 反连接的基本语法为: anti_join(x, y) ,作用是丢弃 x 表中与 y 表中的观测相匹配的所有观测

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
> x
#> # A tibble: 3 x 2
#> key_x val_x
#> <dbl> <chr>
#> 1 1 alpha
#> 2 2 beta
#> 3 3 gamma
> y
#> # A tibble: 3 x 2
#> key_y val_y
#> <dbl> <chr>
#> 1 1 a
#> 2 2 b
#> 3 7 g
> semi_join(x, y, by = c("key_x" = "key_y"))
#> # A tibble: 2 x 2
#> key_x val_x
#> <dbl> <chr>
#> 1 1 alpha
#> 2 2 beta
> anti_join(x, y, by = c("key_x" = "key_y"))
#> # A tibble: 1 x 2
#> key_x val_x
#> <dbl> <chr>
#> 1 3 gamma

半连接和反连接中的“所有观测”包含 x 表中的重复键对应观测

反连接经常用于诊断维度表的维度缺失或事实表中的事实错误

集合操作

对于有且仅有相同变量列的两表还可以使用集合操作,表中的每个观测都可以理解为集合中的每个元素(虽然表中的观测可以重复而数学上集合的元素必须互异)。集合操作主要有以下三种:

  • :基本格式为 intersect(x, y) ,返回既在 x 表又在 y 表中的观测
  • :基本格式为 union(x, y) ,返回存在于 x 表或 y 表中的全部非重复观测
  • :基本格式为 intersect(x, y) ,返回存在于 x 表但不存在于 y 表中的观测

例如,对于下面的数据表:

1
2
3
4
5
6
7
8
9
10
11
12
square <- tribble(
~x, ~y,
1, 1,
2, 4,
3, 9
)
cube <- tribble(
~x, ~y,
1, 1,
2, 8,
3, 27
)

对应的集合操作为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
> intersect(square, cube)
# A tibble: 1 x 2
x y
<dbl> <dbl>
1 1 1
> union(square, cube)
# A tibble: 5 x 2
x y
<dbl> <dbl>
1 1 1
2 2 4
3 3 9
4 2 8
5 3 27
> setdiff(square, cube)
# A tibble: 2 x 2
x y
<dbl> <dbl>
1 2 4
2 3 9

集合操作除了可以应用于数据框,还可以用于向量等对象

评论



This is a picture without description

This is a picture without description This is a picture without description This is a picture without description