小洁详解《R数据科学》--第九章 dplyr处理关系
1.简介
• 合并连接:向数据框中加入新变量,新变量的值是另一个数据框中的匹配观测。
• 筛选连接:根据是否匹配另一个数据框中的观测,筛选数据框中的观测。
• 集合操作:将观测作为集合元素来处理
2. nycflights13
除了flight外,还有另外四个相关数据框。分别描述航空公司、机场、飞机、天气。
我喜欢以标准表格的形式观察每个数据框。
library(tidyverse)
library(nycflights13)
View(airlines)
View(airports)
View(planes)
View(weather)
airlines
airports
planes
weather
关系
- flights 与 planes 通过单变量 tailnum 相连;
- flights 与 airlines 通过变量 carrier 相连;
- flights 与 airports 通过 origin 和 dest、faa相连;
- flights 与 weather 通过变量 origin(位置)以及 year、month、day 和 hour(时间)相连
3.键
用于连接每对数据表的变量称为键。键是能唯一标识观测的变量(或变量集合)。
主键:唯一标识其所在数据表中的观测。例如,planes$tailnum
是一个主键,因为其可
以唯一标识planes 表中的每架飞机。
外键:唯一标识另一个数据表中的观测。例如,flights$tailnum
是一个外键,因为其
出现在flights 表中,并可以将每次航班与唯一一架飞机匹配。
验证主键能否真正唯一标识每个观测。
(这句话的意思相当于检测这个主键能否起到和行号一样的作用,强调唯一)
planes %>%
count(tailnum) %>%
filter(n > 1)
#> # A tibble: 0 × 2
#> # ... with 2 variables: tailnum <chr>, n <int>
#这种方法其实等同于答案中提到的
planes %>%
group_by(tailnum) %>%
filter(n() > 1) %>%
nrow() #统计行数
对主键进行分组计数,再筛选出现次数>1的行,结果是0则说明找到的主键正确。
练习
(1) 向flights 添加一个代理键。
flights %>%
arrange(year, month, day, sched_dep_time, carrier, flight) %>%
mutate(flight_id = row_number()) %>%
glimpse() #瞅一瞅
核心操作就是mutate(flight_id = row_number()),答案先进行了一个排序,是赋予行号一定的意义。
(2) 找出以下各数据集中的键。
a. Lahman::Batting
install.packages("Lahman")
library(Lahman)
Lahman::Batting %>%
group_by(playerID, yearID, stint) %>%
filter(n() > 1) %>%
nrow()
#或
Lahman::Batting %>%
count(playerID, yearID, stint) %>%
filter(n > 1)
以此为例,如果直接使用产生报错,是因为你没有安装对应的包。双冒号前面是包名,后面是数据框名,这两种方法任选其一,挨个筛选和组合你猜测的主键。
b. babynames::babynames
year, sex, name
c. nasaweather::atmos
lat, long, year, month
d. fueleconomy::vehicles
id
e. ggplot2::diamonds
(这个没有)
4.合并连接
简化flights-》flights2
flights2 <- flights %>%
select(year:day, hour, origin, dest, tailnum, carrier)
View(flights2)
将航空公司全名加入flights2-》flights3
flight3<-flights2 %>%
select(-origin, -dest) %>%
left_join(airlines, by = "carrier")
View(flights3)
#等同于
flights2 %>%
select(-origin, -dest) %>%
mutate(name = airlines$name[match(carrier, airlines$carrier)])#R取子集
注意:left_join和其他的dplyr操作一样,不改变原来的数据框,如果不给它赋值,就只是在控制台展示一下,雁过无痕。所以在这里我给它赋值为flights3。
(1)内连接innerjoin
取交集,未匹配到的行会被丢弃。
(2)外连接
*letf_join左连接:保留第一个数据框的所有观测。(最常用)
right_join右连接:保留第二个数据框中的所有观测
full_join全连接:保留两个数据框中的所有观测。
中文书籍这里有问题,韦恩图的颜色被弱化了。看这里
(3)重复键
连接时会得到所有的组合,通常意味着出现错误。
(4)定义键列
连接时,会自动寻找两个数据框中共有的列作为键来进行匹配(自然连接),也可自行指定键列
flights2 %>%
left_join(weather)
flights2 %>%
left_join(planes, by = "tailnum")
当对应的列名不同时必须明确指出,例如:airportsorigin和flights$dest都可匹配,且列名不同,需要用by = c("a" = "b")
定义
flights2 %>%
left_join(airports, c("dest" = "faa"))
flights2 %>%
left_join(airports, c("origin" = "faa"))
5.筛选连接
semi_join(x, y)
半连接:保留x 表中与y 表中的观测相匹配的所有观测。
anti_join(x, y)
反连接:丢弃x 表中与y 表中的观测相匹配的所有观测。
筛选最受欢迎的10个目的地(在dest列出现次数最多的10个)
(top_dest <- flights %>%
count(dest, sort = TRUE) %>%
head(10))
找出飞往这些目的地的所有航班
flights %>%
filter(dest %in% top_dest$dest)
用到了%in%取子集操作。
6.问题
(1)找出主键
(2)主键不能有缺失值
(3)检查外键是否与另一张表的主键相匹配(anti_join)
7.集合
intersect(x, y)
返回既在x 表,又在y 表中的观测。
union(x, y)
返回x 表或y 表中的唯一观测。
setdiff(x, y)
返回在x 表,但不在y 表中的观测。
集合跟连接的区别是:
用于求集合的列名全都相同,求集合不改变列数,改变行数。
用于做连接的列名只有部分一到几列相同,做连接增加列数。
总结
第9章dplyr处理关系.png 微信公众号生信星球同步更新我的文章友情链接:
生信技能树公益视频合辑:学习顺序是linux,r,软件安装,geo,小技巧,ngs组学!
B站链接:https://m.bilibili.com/space/338686099
YouTube链接:https://m.youtube.com/channel/UC67sImqK7V8tSWHMG8azIVA/playlists
生信工程师入门最佳指南:https://mp.weixin.qq.com/s/vaX4ttaLIa19MefD86WfUA
学徒培养:https://mp.weixin.qq.com/s/3jw3_PgZXYd7FomxEMxFmw