• 合併連接:向數據框中加入新變量,新變量的值是另一個數據框中的匹配觀測。
• 篩選連接:根據是否匹配另一個數據框中的觀測,篩選數據框中的觀測。
• 集合操作:將觀測作為集合元素來處理
除了flight外,還有另外四個相關數據框。分別描述航空公司、機場、飛機、天氣。
我喜歡以標準表格的形式觀察每個數據框。
library(tidyverse)
library(nycflights13)
View(airlines)
View(airports)
View(planes)
View(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)
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
(這個沒有)
簡化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)])
取交集,未匹配到的行會被丟棄。
(2)外連接*letf_join左連接:保留第一個數據框的所有觀測。(最常用)
right_join右連接:保留第二個數據框中的所有觀測
full_join全連接:保留兩個數據框中的所有觀測。
連接時會得到所有的組合,通常意味著出現錯誤。
(4)定義鍵列連接時,會自動尋找兩個數據框中共有的列作為鍵來進行匹配(自然連接),也可自行指定鍵列
flights2 %>%
left_join(weather)
flights2 %>%
left_join(planes, by = "tailnum")
當對應的列名不同時必須明確指出,例如:airportsfaa與flightsorigin和flights$dest都可匹配,且列名不同,需要用by = c("a" = "b")定義
flights2 %>%
left_join(airports, c("dest" = "faa"))
flights2 %>%
left_join(airports, c("origin" = "faa"))
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)
intersect(x, y)
返回既在x 表,又在y 表中的觀測。
union(x, y)
返回x 表或y 表中的唯一觀測。
setdiff(x, y)
返回在x 表,但不在y 表中的觀測。
集合跟連接的區別是:
用於求集合的列名全都相同,求集合不改變列數,改變行數。
用於做連接的列名只有部分一到幾列相同,做連接增加列數。