《R数据科学》第9章-用dplyr处理关系数据

  • 1. 简介

  • 2. 数据准备:

  • 3. 键

  • 4. 合并连接

  • 5. 筛选连接

  • 6. 连接中的问题

  • 7. 集合操作

1. 简介

通常一张数据表不足以说明问题,需要多个在多个数据表中建立联系,那么怎么做呢?

基本思想:

在两个表之间建立关系。也就是说,每种关系只与两张表有关。

基本操作:

通过三类操作来处理关系数据。

  • 合并连接:向数据框中加入新变量,新变量的值是另一个数据框中的匹配观测。【主要作用于列】

  • 筛选连接:根据是否匹配另一个数据框中的观测,筛选数据框中的观测。【主要作用于行】

  • 集合操作:将观测作为集合元素来处理。

2. 数据准备:

nycflights13 包中的5个tibble

  • flights:2013年从纽约市出发的所有336776次航班信息。19个变量(year,month,day,dep_time实际出发时间,sched_dep_time预计出发时间,dep_delay出发延误时间,arr_time实际到达时间,sched_arr_time预计到达时间,arr_delay到达延误时间,carrier航空公司,flight航班,tailnum机尾编号,origin起始点,dest目的地,air_time空中停留时间,distance距离,hour预计起飞时间-小时,minute预计起飞时间-分钟,time_hour时间)。

  • airlines:根据航空公司的缩写码查到公司全名。共16个航空公司,2个变量(carrier缩写,name全称)

  • airports:每个机场的信息,通过 faa 机场编码进行标识。共1396个机场,7个变量(faa机场编码,name机场名,lat纬度, lon经度,alt高度,tz GMT时差,dst夏令时区,tzone IANA时区)

  • planes:每架飞机的信息,通过 tailnum 进行标识。共3322个机场,9个变量(tailnum机尾编号,year生产日期,type机型,manufacturer制造商,model,engines引擎数,seats座位数,speed,engine)

  • weather:纽约机场(起点机场)每小时的天气状况。共26130个小时,15个变量(origin机场所在地,year,month,day,hour,temp温度,dewp露点,humid湿度,wind_dir风向,wind_speed风速,wind_gust,precip降水,pressure气压,visib能见度,time_hour时间)

不同数据表之间的关系:

  • flights 与 planes 通过单变量 tailnum 相连;

  • flights 与 airlines 通过变量 carrier 相连;

  • flights 与 airports 通过两种方式相连(变量 origin 和 dest);

  • flights 与 weather 通过变量 origin(位置)以及 year、month、day 和 hour(时间)相连。

3. 键

键的定义:

键是能唯一标识观测的变量(或变量集合)。

要点:
  • 能唯一标识观测:在所有观测(行)中,键(一列或几列的集合)对应的值仅出现一次;类似于一个数据表中的行号。

# 验证是否是主键,即是否能唯一标识观测,用代码表示如下
# 方法:对主键进行 count() 操作,然后查看是否有 n 大于 1 的记录
> planes%>%
+ count(tailnum)%>%
+ filter(n>1)
# A tibble: 0 x 2
# ... with 2 variables: tailnum <chr>, n <int>
# 可见,tailnum是planes表的主键
# 补充:count()函数
功能:分组计数观测
语法:count(x, ..., wt = NULL, sort = FALSE, name = NULL)
参数说明:
- x 数据框
- ... 要分组的变量
- wt 默认计数每组的行数,默认时不写
- sort 若为TRUE,按计数结果降序排列
- name 输出中新列的名称,默认为n(省略即为默认),如果已有一个名为n的列,会出错。

  • 可以是一个变量(如:每架飞机都可以由 tailnum 唯一标识),也可以是多个变量的集合(如:要想标识 weather 中的观测,需要 5 个变量:year、month、 day、 hour 和 origin)。

键的作用:

用于连接每对数据表。

键的类型:

  • 主键:唯一标识其所在数据表中的观测。例如, planes表中的tailnum 是一个主键,因为其可以唯一标识 planes 表中的每架飞机。

  • 外键:唯一标识另一个数据表中的观测。例如, flights表的中的tailnum 是一个外键,因为其出现在 flights 表中,并可以将每次航班与唯一一架飞机匹配。

  • 一个变量既可以是主键,也可以是外键。例如, origin 是 weather 表主键的一部分,同时 也是 airports 表的外键。

  • 如果一张表没有 主键,需要使用 mutate() 函数和 row_number() 函数为表加上一个主键(如:行号),成为代理键。

# 向 flights 添加一个代理键
flights %>%
arrange(year, month, day, sched_dep_time, carrier, flight) %>%
mutate(flight_id = row_number()) %>%
glimpse()

4. 合并连接

本质:

添加新列(变量),或组合表格

原理:

将一个表格中的变量通过键匹配到另一个表格中

结果:

新表列数=两个表的列数之和-主键列数。新表行数:根据连接方式而定。

4种连接方式:

函数:*_join(x,y,by = NULL)
参数说明:
x,y 两个数据框
by 由要连接的变量(键)组成的字符向量
- 默认:by = NULL,*_join()将执行一个自然连接,使用x和y的所有共同变量。如,匹配flihjts表和weather表时使用的就是其公共变量: year、 month、 day、 hour 和 origin。
flights2 %>%
left_join(weather)
- 两个表中都有某一变量,但意义不同。用字符向量 by = "x"。结果中的同名变量添加一个后缀(.x和.y),以消除歧义。
# flights 和 planes 表中都有 year 变量,但意义不同,因此只通过 tailnum进行连接:
flights2 %>%
left_join(planes, by = "tailnum")
- 同一变量在两个表中的叫法不同。用命名字符向量 by = c("a" = "b"),将匹配 x 表中的 a 变量和 y 表中的 b 变量。输出结果中使用的是 x 表中的变量。
# 每次航班都有起点机场(origin)和终点机场(dest),而airports表中只有机场信息(机场用faa表示,不存在起点或终点的说法),所以需要指定使用哪个机场进行连接
flights2 %>%
left_join(airports, c("dest" = "faa"))
- 要使用多个变量连接,用变量集合by = c("a", "b")将匹配x$a到y$a, x$b到y$b。

  • 内连接inner_join():保留同时存在于两个表中的观测(取交集)。

  • 外连接-左连接left_join():保留 x 中的所有观测。默认是左连接。

  • 外连接-右连接right_join():保留 y 中的所有观测

  • 外连接-全连接full_join():保留 x 和 y 中的所有观测。

说明:

  • 如果没有匹配的键的话,其值用 NA 来填充

当键不唯一时会怎么样?

会得到所有可能的组合。

其他实现方式

base::merge() 函数可以实现所有 4 种合并连接操作。

dplyr 连接操作的优点:①可以更加清晰地表达出代码的意图;②速度明显更快,而且不会弄乱行的顺序。

5. 筛选连接

本质:

筛选行。

类型:

(1) 半连接 semi_join(x, y):

结果:保留 x 表中与 y 表中的观测相匹配的所有观测。(保留x与y中共有的行)

应用:对数据表进行筛选或摘要统计后,如果想要使用表中原来的行来匹配筛选或摘要结果,那么半连接是非常有用的。

# 找出最受欢迎的前 10 个目的地
top_dest <- flights %>%
count(dest, sort = TRUE) %>%
head(10)
top_dest

# 找出飞往这些目的地的所有航班
# 可以自己构造一个筛选器,但这种方法很难扩展到多个变量
flights %>%
filter(dest %in% top_dest$dest)
# 用半连接,可以像合并连接一样连接两个表,但不添加新列,而是保留 x表中那些可以匹配 y 表的行
flights %>%
semi_join(top_dest)

(2)反连接 anti_join(x, y):

结果:丢弃 x 表中与 y 表中的观测相匹配的所有观测(保留仅x中有的行)

应用:用于诊断连接中的不匹配。

# flights 中是否有很多行在 planes 中没有匹配记录:
flights %>%
anti_join(planes, by = "tailnum") %>%
count(tailnum, sort = TRUE)

6. 连接中的问题

为了在使用自己的数据时可以顺畅地进行各种连接,需要注意以下几点。

(1) 首先,需要找出每个表中可以作为主键的变量。一般应该基于对数据的理解来确定主键,在确定主键时需要考虑其实际意义。

(2) 确保主键中的每个变量都没有缺失值。如果有缺失值,那么这个变量就不能标识观测!

(3) 检查外键是否与另一张表的主键相匹配。最好的方法是使用 anti_join()。

7. 集合操作

所有集合操作都是作用于整行 的,比较的是每个变量的值。

作用:可以将一个复杂的筛选操作分解为多个简单部分。

集合操作需要 x 和 y 具有相同的变量,并将观测按照集合来处理。

  • intersect(x, y):返回既在 x 表,又在 y 表中的观测。

  • union(x, y):返回 x 表或 y 表中的唯一观测。

  • setdiff(x, y):返回在 x 表,但不在 y 表中的观测。

(0)

相关推荐

  • 使用模拟运算表计算多个结果

    概述 在Microsoft Excel中,数据表是一套命令(称为What-If分析工具)的一部分. 构造和分析数据表时,将执行"如果分析". 如果分析是更改单元格中的值以查看这些更 ...

  • SPSS如何合并数据?

    我们在处理数据的时候,并不是所有的数据都在一个文件中,如果要将一份或者多份数据通过复制黏贴的方式显得过于麻烦,SPSS就有合并数据的功能,一起来看看吧! 首先打开一个数据表,我们想将另一个数据表添加到 ...

  • 数据库设计规范

    数据库设计(Database Design)是指对于一个给定的应用环境,构造最优的数据库模式,建立数据库及其应用系统,使之能够有效地存储数据,满足各种用户的应用需求(信息要求和处理要求). 一.数据库 ...

  • 4家数据科学公司:如何深度挖掘微生物组数据

    这是<肠道产业>第 569 篇文章 编者按: 微软公司的联合创始人比尔·盖茨坚定地认为,了解微生物组"在未来 20 年里,不亚于我们在健康领域所做的任何其他事情".而麦 ...

  • 《R数据科学》第3章——dplyr是什么

    写在前面 dplyr是R语言中为数不多的,也是最好用的数据清洗R包,这也是hendly团队的核心产品,承载着在数据到绘图或者分析过程的桥梁.其中包含的函数超过100条,值得我们花费很长的时间一步步学习 ...

  • 《R数据科学》第10章-用stringr处理字符串

    《R数据科学》第10章-用stringr处理字符串

  • 《R数据科学》第1章-ggplot2图层与绘图大法-全

    《R数据科学》第1章-ggplot2图层与绘图大法-全

  • 《R数据科学》第2 4 6章-工作流

    第2章 工作流:基础 1. 代码基础 2. 对象名称 3. 函数调用 第4章 工作流:脚本 1. RStudio 脚本编辑器 2. 运行代码 3. RStudio自动诊断 第6章 工作流:项目 1. ...

  • 《R数据科学》第11章-用forcats处理因子

    《R数据科学》第11章-用forcats处理因子

  • 《R数据科学》课后练习题:第三章(2)

    (1)虽然现在的deep_time和sched_dep_time变量方便阅读,但不适合计算,因为他们实际上并不是连续型数值.将他们转换成一种更方便的表示形式,即从午夜开始的分钟数. flight_ne ...

  • 九章云极DataCanvas方磊:数据科学赋能组织实现未来智能

    一年一度的IDC DX Summit 数字化转型大会聚焦 "数字竞技,转战新常态",邀请各行业领域头部企业创始人和高管发表新见解,九章云极DataCanvas董事长方磊博士站在行业 ...

  • Python和R哪个适合数据科学?

    python和R都是当下比较流行的编程语言,拥有强大的生态系统和社区,受到大家的追捧和喜欢,那么在数据科学方面,python和R有何区别?我们来看看吧. 大多数深度学习研究都使用python完成的,因 ...