原文鏈接:
3.1
簡介
一般來說,你需要創建一些新變量或者摘要統計量,還可能對變量進行重命名或對觀測值進行重新排序,以便數據更容易處理。你將在本章中學會如何進行這些甚至更多操作,本章將教會你如何使用?dplyr?包來轉換數據,并介紹一個新的數據集:2013 年從紐約市出發的航班信息。
3.1.1
準備工作
本章將重點討論如何使用 tidyverse 中的另一個核心 R 包—dplyr?包。我們使 用nycflights13?包中的數據來說明 dplyr 包的核心理念,并使用 ggplot2 來幫助我們理解數據。
1BiocManager::install('nycflights13')
2library(nycflights13)
3library(tidyverse)
3.1.2
nycflights13
為了介紹 dplyr 中的基本數據操作,我們需要使用?nycflights13::flights。這個數據框包含了 2013 年從紐約市出發的所有 336 776 次航班的信息。該數據來自于美國交通統計局,可以使用??flights?查看其說明文檔:
1>?flights
2#?A?tibble:?336,776?x?19
3????year?month???day?dep_time?sched_dep_time?dep_delay?arr_time?sched_arr_time?arr_delay
4???????????????????????????????????????????
5?1??2013?????1?????1??????517????????????515?????????2??????830????????????819????????11
6?2??2013?????1?????1??????533????????????529?????????4??????850????????????830????????20
7?3??2013?????1?????1??????542????????????540?????????2??????923????????????850????????33
8?4??2013?????1?????1??????544????????????545????????-1?????1004???????????1022???????-18
9?5??2013?????1?????1??????554????????????600????????-6??????812????????????837???????-25
10?6??2013?????1?????1??????554????????????558????????-4??????740????????????728????????12
11?7??2013?????1?????1??????555????????????600????????-5??????913????????????854????????19
12?8??2013?????1?????1??????557????????????600????????-3??????709????????????723???????-14
13?9??2013?????1?????1??????557????????????600????????-3??????838????????????846????????-8
1410??2013?????1?????1??????558????????????600????????-2??????753????????????745?????????8
15#?...?with?336,766?more?rows,?and?10?more?variables:?carrier?,?flight?,
16#???tailnum?,?origin?,?dest?,?air_time?,?distance?,?hour?,
17#???minute?,?time_hour?
這個數據框的輸出和我們以前用過的其他數據框有一點差別:只顯示了前幾行和適合屏幕寬度的幾列。(要想看到整個數據集,可以使用?View(flights)?在 RStudio查看器中打開數據集。)
列名下面有一行 3 個或 4 個字母的縮寫。它們描述了每個變量的類型。
??int?表示整數型變量。
??dbl?表示雙精度浮點數型變量,或稱實數。
??chr?表示字符向量,或稱字符串。
??dttm?表示日期時間(日期 + 時間)型變量。
還有另外 3 種常用的變量類型,雖然沒有在這個數據集中出現,但很快就會在本書后面遇到。?
??lgl?表示邏輯型變量,是一個僅包括?TRUE?和?FALSE?的向量。
??fctr?表示因子,R 用其來表示具有固定數目的值的分類變量。
??date?表示日期型變量。
3.1.3
dplyr?基礎
本章將學習 5 個?dplyr?核心函數。
? 按值篩選觀測(filter())。
? 對行進行重新排序(arrange()?)。
? 按名稱選取變量(select()?)。
? 使用現有變量的函數創建新變量(mutate()?)。
? 將多個值總結為一個摘要統計量(summarize())。
這些函數都可以和 group_by() 函數聯合起來使用,group_by()?函數可以改變以上每個函數的作用范圍,讓其從在整個數據集上操作變為在每個分組上分別操作。這 6 個函數構成了數據處理語言的基本操作。
3.2
使用filter()?篩選行
filter()?函數可以基于觀測的值篩選出一個觀測子集。第一個參數是數據框名稱,第二個參數以及隨后的參數是用來篩選數據框的表達式。例如,我們可以使用以下代碼篩選出 1月 1 日的所有航班:
1>?filter(flights,?month?==?1,?day?==?1)
2#?A?tibble:?842?x?19
3????year?month???day?dep_time?sched_dep_time?dep_delay?arr_time?sched_arr_time?arr_delay
4???????????????????????????????????????????
5?1??2013?????1?????1??????517????????????515?????????2??????830????????????819????????11
6?2??2013?????1?????1??????533????????????529?????????4??????850????????????830????????20
7?3??2013?????1?????1??????542????????????540?????????2??????923????????????850????????33
8?4??2013?????1?????1??????544????????????545????????-1?????1004???????????1022???????-18
9?5??2013?????1?????1??????554????????????600????????-6??????812????????????837???????-25
10?6??2013?????1?????1??????554????????????558????????-4??????740????????????728????????12
11?7??2013?????1?????1??????555????????????600????????-5??????913????????????854????????19
12?8??2013?????1?????1??????557????????????600????????-3??????709????????????723???????-14
13?9??2013?????1?????1??????557????????????600????????-3??????838????????????846????????-8
1410??2013?????1?????1??????558????????????600????????-2??????753????????????745?????????8
15#?...?with?832?more?rows,?and?10?more?variables:?carrier?,?flight?,?tailnum?,
16#???origin?,?dest?,?air_time?,?distance?,?hour?,?minute?,
17#???time_hour?
如果運行這行代碼,dplyr?就會執行篩選操作,并返回一個新數據框。dplyr?函數從來不修改輸入,因此,如果想要保存函數結果,那么你就需要使用賦值操作符?<-:
1jan1?<-?filter(flights,?month?==?1,?day?==?1)
R 要么輸出結果,要么將結果保存在一個變量中。如果想同時完成這兩種操作,那么你可以用括號將賦值語句括起來:
1>?(dec25?<-?filter(flights,?month?==?12,?day?==?25))
2#?A?tibble:?719?x?19
3????year?month???day?dep_time?sched_dep_time?dep_delay?arr_time?sched_arr_time?arr_delay
4???????????????????????????????????????????
5?1??2013????12????25??????456????????????500????????-4??????649????????????651????????-2
6?2??2013????12????25??????524????????????515?????????9??????805????????????814????????-9
7?3??2013????12????25??????542????????????540?????????2??????832????????????850???????-18
8?4??2013????12????25??????546????????????550????????-4?????1022???????????1027????????-5
9?5??2013????12????25??????556????????????600????????-4??????730????????????745???????-15
10?6??2013????12????25??????557????????????600????????-3??????743????????????752????????-9
11?7??2013????12????25??????557????????????600????????-3??????818????????????831???????-13
12?8??2013????12????25??????559????????????600????????-1??????855????????????856????????-1
13?9??2013????12????25??????559????????????600????????-1??????849????????????855????????-6
1410??2013????12????25??????600????????????600?????????0??????850????????????846?????????4
15#?...?with?709?more?rows,?and?10?more?variables:?carrier?,?flight?,?tailnum?,
16#???origin?,?dest?,?air_time?,?distance?,?hour?,?minute?,
17#???time_hour?
3.2.1
比較運算符
為了有效地進行篩選,你必須知道如何使用比較運算符來選擇觀測。R 提供了一套標準的比較運算符:>、>=、<、<=、!=(不等于)和?==(等于)。當開始使用 R 時,最容易犯的錯誤就是使用 = 而不是 == 來測試是否相等。
在使用 == 進行比較時,你可能還會遇到另一個常見問題:浮點數。下面的結果可能會令你目瞪口呆:
1>?sqrt(2)?^?2?==?2
2[1]?FALSE
3>?#>?[1]?FALSE
4>?1/49?*?49?==?1
5[1]?FALSE
計算機使用的是有限精度運算(顯然無法存儲無限位的數),因此請記住,你看到的每個數都是一個近似值。比較浮點數是否相等時,不能使用 ==,而應該使用?near():
1near(sqrt(2)?^?2,?2)
2#>?[1]?TRUE
3near(1?/?49?*?49,?1)
4#>?[1]?TRUE
3.2.2
邏輯運算符
filter()?中的多個參數是由“與”組合起來的:每個表達式都必須為真才能讓一行觀測包含在輸出中。如果要實現其他類型的組合,你需要使用布爾運算符:&?表示“與”、|?表示“或”、!?表示“非”。下圖給出了布爾運算的完整集合。
以下代碼可以找出 11 月或 12 月出發的所有航班:
1filter(flights,?month?==?11?|?month?==?12)
表達式中的運算順序和語言中的是不一樣的。你不能寫成?filter(flights, month == 11 |12)?這種形式。這種形式的文字翻譯確實是“找出 11 月或 12 月出發的所有航班”,但在代碼中則不是這個意思,代碼中的含義是找出所有出發月份為 11 | 12 的航班。11 | 12 這個邏輯表達式的值為?TRUE,在數字語境中(如本例),TRUE 就是 1,所以這段代碼找出的不是 11 月或 12 月出發的航班,而是 1 月出發的所有航班。
這種問題有一個有用的簡寫形式:x %in% y。這會選取出 x 是 y 中的一個值時的所有行。我們可以使用這種形式重寫上面的代碼:
1nov_dec?<-?filter(flights,?month?%in%?c(11,?12))
有時你可以使用德摩根定律將復雜的篩選條件進行簡化:!(x & y)等價于
!x | !y、!(x |y)等價于?!x & !y。例如,如果想要找出延誤時間(到達或出發)不多于 2 小時的航班,那么使用以下兩種篩選方式均可:
1filter(flights,?!(arr_delay?>?120?|?dep_delay?>?120))
2filter(flights,?arr_delay?<=?120,?dep_delay?<=?120)
3.2.3
缺失值
R?的一個重要特征使得比較運算更加復雜,這個特征就是缺失值,或稱?NA(not available,不可用)。NA?表示未知的值,因此缺失值是“可傳染的”。如果運算中包含了未知值,那么運算結果一般來說也是個未知值:
1NA?>?5
2#>?[1]?NA
310?==?NA
4#>?[1]?NA
5NA?+?10
6#>?[1]?NA
7NA?/?2
8#>?[1]?NA
最令人費解的是以下這個結果:
1NA?==?NA
2#>?[1]?NA
要想理解為什么會這樣,最容易的方式是加入一點背景知識:
1#?令x為Mary的年齡。我們不知道她有多大。
2x?<-?NA
3#?令y為John的年齡。我們不知道他有多大。
4y?<-?NA
5# John和Mary的年齡是相同的嗎?
6x?==?y
7#>?[1]?NA
8#?我們不知道!
如果想要確定一個值是否為缺失值,可以使用?is.na()?函數:
1>?x?<-?NA
2>?is.na(x)
3[1]?TRUE
filter()?只能篩選出條件為?TRUE?的行;它會排除那些條件為?FALSE?和?NA?的行。如果想保留缺失值,可以明確指出:
1>?df?<-?tibble(x?=?c(1,?NA,?3))
2>?filter(df,?x?>?1)
3#?A?tibble:?1?x?1
4??????x
5??
61?????3
7>?filter(df,?is.na(x)?|?x?>?1)
8#?A?tibble:?2?x?1
9??????x
10??
111????NA
122?????3
3.3
使用arrange()排列行
arrange()?函數的工作方式與 filter() 函數非常相似,但前者不是選擇行,而是改變行的順序。它接受一個數據框和一組作為排序依據的列名(或者更復雜的表達式)作為參數。如果列名不只一個,那么就使用后面的列在前面排序的基礎上繼續排序:
1arrange(flights,?year,?month,?day)
1>?arrange(flights,?year,?month,?day)
2#?A?tibble:?336,776?x?19
3????year?month???day?dep_time?sched_dep_time?dep_delay?arr_time?sched_arr_time?arr_delay
4???????????????????????????????????????????
5?1??2013?????1?????1??????517????????????515?????????2??????830????????????819????????11
6?2??2013?????1?????1??????533????????????529?????????4??????850????????????830????????20
7?3??2013?????1?????1??????542????????????540?????????2??????923????????????850????????33
8?4??2013?????1?????1??????544????????????545????????-1?????1004???????????1022???????-18
9?5??2013?????1?????1??????554????????????600????????-6??????812????????????837???????-25
10?6??2013?????1?????1??????554????????????558????????-4??????740????????????728????????12
11?7??2013?????1?????1??????555????????????600????????-5??????913????????????854????????19
12?8??2013?????1?????1??????557????????????600????????-3??????709????????????723???????-14
13?9??2013?????1?????1??????557????????????600????????-3??????838????????????846????????-8
1410??2013?????1?????1??????558????????????600????????-2??????753????????????745?????????8
15#?...?with?336,766?more?rows,?and?10?more?variables:?carrier?,?flight?,
16#???tailnum?,?origin?,?dest?,?air_time?,?distance?,?hour?,
17#???minute?,?time_hour?
使用?desc()?可以按列進行降序排序:
1>?arrange(flights,?desc(arr_delay))
2#?A?tibble:?336,776?x?19
3????year?month???day?dep_time?sched_dep_time?dep_delay?arr_time?sched_arr_time?arr_delay
4???????????????????????????????????????????
5?1??2013?????1?????9??????641????????????900??????1301?????1242???????????1530??????1272
6?2??2013?????6????15?????1432???????????1935??????1137?????1607???????????2120??????1127
7?3??2013?????1????10?????1121???????????1635??????1126?????1239???????????1810??????1109
8?4??2013?????9????20?????1139???????????1845??????1014?????1457???????????2210??????1007
9?5??2013?????7????22??????845???????????1600??????1005?????1044???????????1815???????989
10?6??2013?????4????10?????1100???????????1900???????960?????1342???????????2211???????931
11?7??2013?????3????17?????2321????????????810???????911??????135???????????1020???????915
12?8??2013?????7????22?????2257????????????759???????898??????121???????????1026???????895
13?9??2013????12?????5??????756???????????1700???????896?????1058???????????2020???????878
1410??2013?????5?????3?????1133???????????2055???????878?????1250???????????2215???????875
15#?...?with?336,766?more?rows,?and?10?more?variables:?carrier?,?flight?,
16#???tailnum?,?origin?,?dest?,?air_time?,?distance?,?hour?,
17#???minute?,?time_hour?
缺失值總是排在最后:
1>?df?<-?tibble(x?=?c(5,?2,?NA))
2>?arrange(df,?x)
3#?A?tibble:?3?x?1
4??????x
5??
61?????2
72?????5
83????NA
9>?arrange(df,?desc(x))
10#?A?tibble:?3?x?1
11??????x
12??
131?????5
142?????2
153????NA
— END —
往期 ·?推薦
《R數據科學》學習筆記|Note2:使用ggplot2進行數據可視化(上)