R數(shù)據(jù)科學(xué)筆記:2

第二章 工作流:基礎(chǔ)

2.1 代碼基礎(chǔ)

首先,我們可以將R當(dāng)做計(jì)算器使用

> 1 / 200 * 30
[1] 0.15
> (59 + 73 + 2) / 3
[1] 44.66667
> sin(pi / 2)
[1] 1

使用<- 來(lái)創(chuàng)建新對(duì)象:

x <- 3 * 4

創(chuàng)建對(duì)象的所有R 語(yǔ)句(即賦值語(yǔ)句)都有同樣的形式:

object_name <- value

在閱讀這行代碼時(shí),你可以在腦海中默念“某個(gè)對(duì)象名得到了某個(gè)值”。如果你覺(jué)得“<-”太繁瑣你可以使用RStudio 快捷鍵:Alt+-(Alt 加上減號(hào))。

2.2 對(duì)象名稱(chēng)

對(duì)象名稱(chēng)必須以字母開(kāi)頭,并且只能包含字母、數(shù)字、_ 和.。如果想讓對(duì)象名稱(chēng)具有描述性,那么就應(yīng)該在使用多個(gè)單詞時(shí)遵循某種命名慣例。我推薦使用snake_case 命名法,也就是使用小寫(xiě)單詞,并用_ 分隔:

i_use_snake_case
otherPeopleUseCamelCase
some.people.use.periods
And_aFew.People_RENOUNCEconvention

可以通過(guò)輸入對(duì)象名稱(chēng)來(lái)查看這個(gè)對(duì)象:

> x
[1] 12

再進(jìn)行一次賦值:

r_rocks <- 2 ^ 3
## 查看一下這個(gè)對(duì)象
r_rock
#> Error: object 'r_rock' not found
R_rocks
#> Error: object 'R_rocks' not found

2.3 函數(shù)調(diào)用

R中有大量?jī)?nèi)置函數(shù)。調(diào)用方式如下:

function_name(arg1 = val1, arg2 = val2, ...)

我們嘗試使用seq() 函數(shù),輸入?yún)?shù)1, 10:

> seq(1,10)
 [1]  1  2  3  4  5  6  7  8  9 10

輸入以下代碼,你會(huì)發(fā)現(xiàn)RStudio 也會(huì)自動(dòng)完成一對(duì)雙引號(hào)以方便輸入:

x <- "hello world"

引號(hào)和括號(hào)必須一直成對(duì)出現(xiàn)。RStudio 會(huì)盡力幫助我們,但還是有出錯(cuò)并導(dǎo)致不匹配的可能。如果出現(xiàn)不匹配,R 會(huì)顯示一個(gè)+ 號(hào):

> x <- "hello
+ 

+號(hào)表明R 在等待繼續(xù)輸入;它認(rèn)為你還沒(méi)有完成輸入。這通常意味著你漏掉了一個(gè)" 或者)。

如果進(jìn)行了一次賦值,R 不會(huì)顯示出賦值結(jié)果。你最好立刻檢查一下:

> y <- seq(1, 10, length.out = 5)
> y
[1]  1.00  3.25  5.50  7.75 10.00
## 或者采取簡(jiǎn)化方式
> (y <- seq(1, 10, length.out = 5))
[1]  1.00  3.25  5.50  7.75 10.00

第三章 使用dplyr進(jìn)行數(shù)據(jù)轉(zhuǎn)換

3.1 簡(jiǎn)介

本章將用dplyr 包來(lái)轉(zhuǎn)換數(shù)據(jù),并介紹一個(gè)新的數(shù)據(jù)集:2013 年從紐約市出發(fā)的航班信息。

3.1.1 準(zhǔn)備工作

本章將重點(diǎn)討論如何使用tidyverse 中的另一個(gè)核心R 包——dplyr 包。我們使用nycflights13 包中的數(shù)據(jù)來(lái)說(shuō)明dplyr 包的核心理念,并使用ggplot2 來(lái)幫助我們理解數(shù)據(jù)。

3.1.2 nycflights13

使用nycflights13::flights。這個(gè)數(shù)據(jù)框包含了2013 年從紐約市出發(fā)的所有336 776 次航班的信息。該數(shù)據(jù)來(lái)自于美國(guó)交通統(tǒng)計(jì)局,可以使用?flights 查看其說(shuō)明文檔:

> flights
# A tibble: 336,776 x 19
    year month   day dep_time sched_dep_time dep_delay
   <int> <int> <int>    <int>          <int>     <dbl>
 1  2013     1     1      517            515         2
 2  2013     1     1      533            529         4
 3  2013     1     1      542            540         2
 4  2013     1     1      544            545        -1
 5  2013     1     1      554            600        -6
 6  2013     1     1      554            558        -4
 7  2013     1     1      555            600        -5
 8  2013     1     1      557            600        -3
 9  2013     1     1      557            600        -3
10  2013     1     1      558            600        -2
# ... with 336,766 more rows, and 13 more variables:
#   arr_time <int>, sched_arr_time <int>, arr_delay <dbl>,
#   carrier <chr>, flight <int>, tailnum <chr>, origin <chr>,
#   dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
#   minute <dbl>, time_hour <dttm>

列名下面有一行3 個(gè)或4 個(gè)字母的縮寫(xiě)。它們描述了每個(gè)變量的類(lèi)型。

? int 表示整數(shù)型變量。
? dbl 表示雙精度浮點(diǎn)數(shù)型變量,或稱(chēng)實(shí)數(shù)。
? chr 表示字符向量,或稱(chēng)字符串。
? dttm 表示日期時(shí)間(日期+ 時(shí)間)型變量。

還有另外3 種常用的變量類(lèi)型,雖然沒(méi)有在這個(gè)數(shù)據(jù)集中出現(xiàn),但很快就會(huì)在本書(shū)后面遇到。
? lgl 表示邏輯型變量,是一個(gè)僅包括TRUE 和FALSE 的向量。
? fctr 表示因子,R 用其來(lái)表示具有固定數(shù)目的值的分類(lèi)變量。
? date 表示日期型變量。

3.1.3 dplyr基礎(chǔ)

5 個(gè)dplyr 核心函數(shù):

? 按值篩選觀測(cè)(filter())。
? 對(duì)行進(jìn)行重新排序(arrange())。
? 按名稱(chēng)選取變量(select())。
? 使用現(xiàn)有變量的函數(shù)創(chuàng)建新變量(mutate())。
? 將多個(gè)值總結(jié)為一個(gè)摘要統(tǒng)計(jì)量(summarize())。

這些函數(shù)都可以和group_by() 函數(shù)聯(lián)合起來(lái)使用,group_by() 函數(shù)可以改變以上每個(gè)函數(shù)的作用范圍,讓其從在整個(gè)數(shù)據(jù)集上操作變?yōu)樵诿總€(gè)分組上分別操作。這6 個(gè)函數(shù)構(gòu)成了數(shù)據(jù)處理語(yǔ)言的基本操作。

前面5 個(gè)函數(shù)的工作方式都是相同的。
(1) 第一個(gè)參數(shù)是一個(gè)數(shù)據(jù)框。
(2) 隨后的參數(shù)使用變量名稱(chēng)(不帶引號(hào))描述了在數(shù)據(jù)框上進(jìn)行的操作。
(3) 輸出結(jié)果是一個(gè)新數(shù)據(jù)框。
利用以上這些屬性可以很輕松地將多個(gè)簡(jiǎn)單步驟鏈接起來(lái),從而得到非常復(fù)雜的結(jié)果。接下來(lái)我們將深入了解,看看如何使用這些操作。

3.2 使用filter()篩選行

filter() 函數(shù)可以基于觀測(cè)的值篩選出一個(gè)觀測(cè)子集。第一個(gè)參數(shù)是數(shù)據(jù)框名稱(chēng),第二個(gè)參數(shù)以及隨后的參數(shù)是用來(lái)篩選數(shù)據(jù)框的表達(dá)式。例如,我們可以使用以下代碼篩選出1月1 日的所有航班:

> jan1 <-filter(flights, month == 1, day == 1)
> jan1
# A tibble: 842 x 19
    year month   day dep_time sched_dep_time dep_delay
   <int> <int> <int>    <int>          <int>     <dbl>
 1  2013     1     1      517            515         2
 2  2013     1     1      533            529         4
 3  2013     1     1      542            540         2
 4  2013     1     1      544            545        -1
 5  2013     1     1      554            600        -6
 6  2013     1     1      554            558        -4
 7  2013     1     1      555            600        -5
 8  2013     1     1      557            600        -3
 9  2013     1     1      557            600        -3
10  2013     1     1      558            600        -2
# ... with 832 more rows, and 13 more variables:
#   arr_time <int>, sched_arr_time <int>, arr_delay <dbl>,
#   carrier <chr>, flight <int>, tailnum <chr>, origin <chr>,
#   dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
#   minute <dbl>, time_hour <dttm>

3.2.1 比較運(yùn)算符

R 提供了一套標(biāo)準(zhǔn)的比較運(yùn)算符:>、>=、<、<=、!=(不等于)和==(等于)。當(dāng)開(kāi)始使用R 時(shí),最容易犯的錯(cuò)誤就是使用= 而不是 == 來(lái)測(cè)試是否相等。

在使用== 進(jìn)行比較時(shí),你可能還會(huì)遇到另一個(gè)常見(jiàn)問(wèn)題:浮點(diǎn)數(shù)。

> sqrt(2)^2==2
[1] FALSE
> 1/49*49==1
[1] FALSE

3.2.2 邏輯運(yùn)算符

filter() 中的多個(gè)參數(shù)是由“與”組合起來(lái)的:每個(gè)表達(dá)式都必須為真才能讓一行觀測(cè)包
含在輸出中。如果要實(shí)現(xiàn)其他類(lèi)型的組合,你需要使用布爾運(yùn)算符:& 表示“與”、| 表示
“或”、! 表示“非”。



以下代碼可以找出11 月或12 月出發(fā)的所有航班:

filter(flights, month == 11 | month == 12)

不能寫(xiě)成filter(flights, month == 11 |12) 這種形式。這種形式的文字翻譯確實(shí)是“找出11 月或12 月出發(fā)的所有航班”,但在代碼中則不是這個(gè)意思,代碼中的含義是找出所有出發(fā)月份為11 | 12 的航班。11 | 12 這個(gè)邏輯表達(dá)式的值為T(mén)RUE,在數(shù)字語(yǔ)境中(如本例),TRUE 就是1,所以這段代碼找出的不是11 月或12 月出發(fā)的航班,而是1 月出發(fā)的所有航班。

這種問(wèn)題有一個(gè)有用的簡(jiǎn)寫(xiě)形式:x %in% y。這會(huì)選取出x 是y 中的一個(gè)值時(shí)的所有行。
我們可以使用這種形式重寫(xiě)上面的代碼:

nov_dec <- filter(flights, month %in% c(11, 12))

可以使用德摩根定律將復(fù)雜的篩選條件進(jìn)行簡(jiǎn)化:!(x & y) 等價(jià)于!x | !y、!(x |y) 等價(jià)于!x & !y。例如,如果想要找出延誤時(shí)間(到達(dá)或出發(fā))不多于2 小時(shí)的航班,那么使用以下兩種篩選方式均可:

filter(flights, !(arr_delay > 120 | dep_delay > 120))
filter(flights, arr_delay <= 120, dep_delay <= 120)

filter() 函數(shù)中使用的是復(fù)雜的、包含多個(gè)部分的表達(dá)式,就需要考慮用一個(gè)明確的變量來(lái)代替它。這樣檢查代碼會(huì)容易很多。我們很快就會(huì)介紹如何創(chuàng)建新變量。

3.2.3 缺失值

R 的一個(gè)重要特征使得比較運(yùn)算更加復(fù)雜,這個(gè)特征就是缺失值,或稱(chēng)NA(not available,不可用)。如果運(yùn)算中包含了未知值,那么運(yùn)算結(jié)果一般來(lái)說(shuō)也是個(gè)未知值:

> NA + 10
[1] NA
> NA / 2
[1] NA

如果想要確定一個(gè)值是否為缺失值,可以使用is.na() 函數(shù):

> x <- NA
> is.na(x)
[1] TRUE

filter() 只能篩選出條件為T(mén)RUE 的行;它會(huì)排除那些條件為FALSE 和NA 的行。如果想保留缺失值,可以明確指出:

> df <- tibble(x = c(1, NA, 3))
> filter(df, x > 1)
# A tibble: 1 x 1
      x
  <dbl>
1     3
> filter(df, is.na(x) | x > 1)
# A tibble: 2 x 1
      x
  <dbl>
1    NA
2     3

3.3 使用arrange()排列行

arrange() 函數(shù)的工作方式與filter() 函數(shù)非常相似,但前者不是選擇行,而是改變行的順序。它接受一個(gè)數(shù)據(jù)框和一組作為排序依據(jù)的列名(或者更復(fù)雜的表達(dá)式)作為參數(shù)。如果列名不只一個(gè),那么就使用后面的列在前面排序的基礎(chǔ)上繼續(xù)排序:

> arrange(flights, year, month, day)
# A tibble: 336,776 x 19
    year month   day dep_time sched_dep_time dep_delay
   <int> <int> <int>    <int>          <int>     <dbl>
 1  2013     1     1      517            515         2
 2  2013     1     1      533            529         4
 3  2013     1     1      542            540         2
 4  2013     1     1      544            545        -1
 5  2013     1     1      554            600        -6
 6  2013     1     1      554            558        -4
 7  2013     1     1      555            600        -5
 8  2013     1     1      557            600        -3
 9  2013     1     1      557            600        -3
10  2013     1     1      558            600        -2
# ... with 336,766 more rows, and 13 more variables:
#   arr_time <int>, sched_arr_time <int>, arr_delay <dbl>,
#   carrier <chr>, flight <int>, tailnum <chr>, origin <chr>,
#   dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
#   minute <dbl>, time_hour <dttm>

使用desc() 可以按列進(jìn)行降序排序:

> arrange(flights, desc(arr_delay))
# A tibble: 336,776 x 19
    year month   day dep_time sched_dep_time dep_delay
   <int> <int> <int>    <int>          <int>     <dbl>
 1  2013     1     9      641            900      1301
 2  2013     6    15     1432           1935      1137
 3  2013     1    10     1121           1635      1126
 4  2013     9    20     1139           1845      1014
 5  2013     7    22      845           1600      1005
 6  2013     4    10     1100           1900       960
 7  2013     3    17     2321            810       911
 8  2013     7    22     2257            759       898
 9  2013    12     5      756           1700       896
10  2013     5     3     1133           2055       878
# ... with 336,766 more rows, and 13 more variables:
#   arr_time <int>, sched_arr_time <int>, arr_delay <dbl>,
#   carrier <chr>, flight <int>, tailnum <chr>, origin <chr>,
#   dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
#   minute <dbl>, time_hour <dttm>

缺失值總是排在最后:

> df <- tibble(x = c(5, 2, NA))
> arrange(df, x)
# A tibble: 3 x 1
      x
  <dbl>
1     2
2     5
3    NA

3.4 使用select()選擇列

如今,數(shù)據(jù)集有幾百甚至幾千個(gè)變量已經(jīng)司空見(jiàn)慣。這種情況下,如何找出真正感興趣的那些變量經(jīng)常是我們面臨的第一個(gè)挑戰(zhàn)。通過(guò)基于變量名的操作,select() 函數(shù)可以讓你快速生成一個(gè)有用的變量子集。

# 按名稱(chēng)選擇列
> select(flights, year, month, day)
# A tibble: 336,776 x 3
    year month   day
   <int> <int> <int>
 1  2013     1     1
 2  2013     1     1
 3  2013     1     1
 4  2013     1     1
 5  2013     1     1
 6  2013     1     1
 7  2013     1     1
 8  2013     1     1
 9  2013     1     1
10  2013     1     1
# ... with 336,766 more rows
# 選擇“year”和“day”之間的所有列
> select(flights, year:day)
# A tibble: 336,776 x 3
    year month   day
   <int> <int> <int>
 1  2013     1     1
 2  2013     1     1
 3  2013     1     1
 4  2013     1     1
 5  2013     1     1
 6  2013     1     1
 7  2013     1     1
 8  2013     1     1
 9  2013     1     1
10  2013     1     1
# ... with 336,766 more rows
# 選擇不在“year”和“day”之間的列
> select(flights, -(year:day))
# A tibble: 336,776 x 16
   dep_time sched_dep_time dep_delay arr_time sched_arr_time
      <int>          <int>     <dbl>    <int>          <int>
 1      517            515         2      830            819
 2      533            529         4      850            830
 3      542            540         2      923            850
 4      544            545        -1     1004           1022
 5      554            600        -6      812            837
 6      554            558        -4      740            728
 7      555            600        -5      913            854
 8      557            600        -3      709            723
 9      557            600        -3      838            846
10      558            600        -2      753            745
# ... with 336,766 more rows, and 11 more variables:
#   arr_delay <dbl>, carrier <chr>, flight <int>,
#   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>,
#   distance <dbl>, hour <dbl>, minute <dbl>,
#   time_hour <dttm>

還可以在select () 函數(shù)中使用一些輔助函數(shù)。
? starts_with("abc"):匹配以“abc”開(kāi)頭的名稱(chēng)。
? ends_with("xyz"):匹配以“xyz”結(jié)尾的名稱(chēng)。
? contains("ijk"):匹配包含“ijk”的名稱(chēng)。
? matches("(.)\1"):選擇匹配正則表達(dá)式的那些變量。這個(gè)正則表達(dá)式會(huì)匹配名稱(chēng)中有重復(fù)字符的變量。你將在第10 章中學(xué)習(xí)到更多關(guān)于正則表達(dá)式的知識(shí)。
? num_range("x", 1:3):匹配x1、x2 和x3。

使用select() 函數(shù)的變體rename() 函數(shù)來(lái)重命名變量,以保留所有未明確提及的變量:

> rename(flights, tail_num = tailnum)
# A tibble: 336,776 x 19
    year month   day dep_time sched_dep_time dep_delay
   <int> <int> <int>    <int>          <int>     <dbl>
 1  2013     1     1      517            515         2
 2  2013     1     1      533            529         4
 3  2013     1     1      542            540         2
 4  2013     1     1      544            545        -1
 5  2013     1     1      554            600        -6
 6  2013     1     1      554            558        -4
 7  2013     1     1      555            600        -5
 8  2013     1     1      557            600        -3
 9  2013     1     1      557            600        -3
10  2013     1     1      558            600        -2
# ... with 336,766 more rows, and 13 more variables:
#   arr_time <int>, sched_arr_time <int>, arr_delay <dbl>,
#   carrier <chr>, flight <int>, tail_num <chr>,
#   origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
#   hour <dbl>, minute <dbl>, time_hour <dttm>

另一種用法是將select() 函數(shù)和everything() 輔助函數(shù)結(jié)合起來(lái)使用。當(dāng)想要將幾個(gè)變量移到數(shù)據(jù)框開(kāi)頭時(shí),這種用法非常奏效

> select(flights, time_hour, air_time, everything())
# A tibble: 336,776 x 19
   time_hour           air_time  year month   day dep_time
   <dttm>                 <dbl> <int> <int> <int>    <int>
 1 2013-01-01 05:00:00      227  2013     1     1      517
 2 2013-01-01 05:00:00      227  2013     1     1      533
 3 2013-01-01 05:00:00      160  2013     1     1      542
 4 2013-01-01 05:00:00      183  2013     1     1      544
 5 2013-01-01 06:00:00      116  2013     1     1      554
 6 2013-01-01 05:00:00      150  2013     1     1      554
 7 2013-01-01 06:00:00      158  2013     1     1      555
 8 2013-01-01 06:00:00       53  2013     1     1      557
 9 2013-01-01 06:00:00      140  2013     1     1      557
10 2013-01-01 06:00:00      138  2013     1     1      558
# ... with 336,766 more rows, and 13 more variables:
#   sched_dep_time <int>, dep_delay <dbl>, arr_time <int>,
#   sched_arr_time <int>, arr_delay <dbl>, carrier <chr>,
#   flight <int>, tailnum <chr>, origin <chr>, dest <chr>,
#   distance <dbl>, hour <dbl>, minute <dbl>

3.5 使用mutate()添加新變量

除了選擇現(xiàn)有的列,我們還經(jīng)常需要添加新列,新列是現(xiàn)有列的函數(shù)。這就是mutate() 函數(shù)的作用。

mutate() 總是將新列添加在數(shù)據(jù)集的最后,因此我們需要先創(chuàng)建一個(gè)更狹窄的數(shù)據(jù)集,以便能夠看到新變量。記住,當(dāng)使用RStudio 時(shí),查看所有列的最簡(jiǎn)單的方法就是使用View()函數(shù):

flights_sml <- select(flights,
                      year:day,
                      ends_with("delay"),
                      distance,
                      air_time
)
mutate(flights_sml,
       gain = arr_delay - dep_delay,
       speed = distance / air_time * 60
)
# A tibble: 336,776 x 9
    year month   day dep_delay arr_delay distance air_time
   <int> <int> <int>     <dbl>     <dbl>    <dbl>    <dbl>
 1  2013     1     1         2        11     1400      227
 2  2013     1     1         4        20     1416      227
 3  2013     1     1         2        33     1089      160
 4  2013     1     1        -1       -18     1576      183
 5  2013     1     1        -6       -25      762      116
 6  2013     1     1        -4        12      719      150
 7  2013     1     1        -5        19     1065      158
 8  2013     1     1        -3       -14      229       53
 9  2013     1     1        -3        -8      944      140
10  2013     1     1        -2         8      733      138
# ... with 336,766 more rows, and 2 more variables:
#   gain <dbl>, speed <dbl>

一旦創(chuàng)建,新列就可以立即使用:

> mutate(flights_sml,
+        gain = arr_delay - dep_delay,
+        hours = air_time / 60,
+        gain_per_hour = gain / hours
+ )
# A tibble: 336,776 x 10
    year month   day dep_delay arr_delay distance air_time
   <int> <int> <int>     <dbl>     <dbl>    <dbl>    <dbl>
 1  2013     1     1         2        11     1400      227
 2  2013     1     1         4        20     1416      227
 3  2013     1     1         2        33     1089      160
 4  2013     1     1        -1       -18     1576      183
 5  2013     1     1        -6       -25      762      116
 6  2013     1     1        -4        12      719      150
 7  2013     1     1        -5        19     1065      158
 8  2013     1     1        -3       -14      229       53
 9  2013     1     1        -3        -8      944      140
10  2013     1     1        -2         8      733      138
# ... with 336,766 more rows, and 3 more variables:
#   gain <dbl>, hours <dbl>, gain_per_hour <dbl>

如果只想保留新變量,可以使用transmute() 函數(shù):

> transmute(flights,
+           gain = arr_delay - dep_delay,
+           hours = air_time / 60,
+           gain_per_hour = gain / hours
+ )
# A tibble: 336,776 x 3
    gain hours gain_per_hour
   <dbl> <dbl>         <dbl>
 1     9 3.78           2.38
 2    16 3.78           4.23
 3    31 2.67          11.6 
 4   -17 3.05          -5.57
 5   -19 1.93          -9.83
 6    16 2.5            6.4 
 7    24 2.63           9.11
 8   -11 0.883        -12.5 
 9    -5 2.33          -2.14
10    10 2.3            4.35
# ... with 336,766 more rows

3.5.1 常用創(chuàng)建函數(shù)

創(chuàng)建新變量的多種函數(shù)可供你同mutate() 一同使用。最重要的一點(diǎn)是,這種函數(shù)必須是向量化的:它必須接受一個(gè)向量作為輸入,并返回一個(gè)向量作為輸出,而且輸入向量與輸出向量具有同樣數(shù)目的分量。我們無(wú)法列出所有可能用到的創(chuàng)建函數(shù),但可以介紹一下那些比較常用的。

算術(shù)運(yùn)算符:+、-、、/、^*

它們都是向量化的,使用所謂的“循環(huán)法則”。如果一個(gè)參數(shù)比另一個(gè)參數(shù)短,那么前者會(huì)自動(dòng)擴(kuò)展到同樣的長(zhǎng)度。當(dāng)某個(gè)參數(shù)是單個(gè)數(shù)值時(shí),這種方式是最有效的:air_time / 60、hours * 60 + minute 等。
算術(shù)運(yùn)算符的另一用途是與我們后面將很快學(xué)到的聚集函數(shù)結(jié)合起來(lái)使用。例如,x /sum(x) 可以計(jì)算出各個(gè)分量在總數(shù)中的比例,y – mean(y) 可以計(jì)算出分量與均值之間的差值。

模運(yùn)算符:%/% 和%%
%/%(整數(shù)除法)和%%(求余)滿(mǎn)足x == y * (x %/% y) + (x %% y)。模運(yùn)算非常好用,因?yàn)樗梢圆鸱终麛?shù)。例如,在航班數(shù)據(jù)集中,你可以根據(jù)dep_time 計(jì)算出hour和minute:

> transmute(flights,
+           dep_time,
+           hour = dep_time %/% 100,
+           minute = dep_time %% 100
+ )
# A tibble: 336,776 x 3
   dep_time  hour minute
      <int> <dbl>  <dbl>
 1      517     5     17
 2      533     5     33
 3      542     5     42
 4      544     5     44
 5      554     5     54
 6      554     5     54
 7      555     5     55
 8      557     5     57
 9      557     5     57
10      558     5     58
# ... with 336,766 more rows

對(duì)數(shù)函數(shù):log()、log2() 和log10()

? 在處理取值范圍橫跨多個(gè)數(shù)量級(jí)的數(shù)據(jù)時(shí),對(duì)數(shù)是特別有用的一種轉(zhuǎn)換方式。它還可以將乘法轉(zhuǎn)換成加法,我們將在本書(shū)的第四部分中介紹這個(gè)功能。
? 其他條件相同的情況下,我推薦使用log2() 函數(shù),因?yàn)楹苋菀讓?duì)其進(jìn)行解釋?zhuān)簩?duì)數(shù)標(biāo)度的數(shù)值增加1 個(gè)單位,意味著初始數(shù)值加倍;減少1 個(gè)單位,則意味著初始數(shù)值減半。

偏移函數(shù)

? lead() 和lag

() 函數(shù)可以返回一個(gè)序列的領(lǐng)先值和滯后值。它們可以計(jì)算出序列的移動(dòng)差值(如x – lag(x))或發(fā)現(xiàn)序列何時(shí)發(fā)生了變化(x != lag(x))。它們與group_by()組合使用時(shí)特別有用,你很快就會(huì)學(xué)到group_by() 這個(gè)函數(shù):

> (x <- 1:10)
 [1]  1  2  3  4  5  6  7  8  9 10
> lag(x)
 [1] NA  1  2  3  4  5  6  7  8  9
> lead(x)
 [1]  2  3  4  5  6  7  8  9 10 NA

**累加和滾動(dòng)聚合 **

R 提供了計(jì)算累加和、累加積、累加最小值和累加最大值的函數(shù):cumsum()、cumprod()、commin() 和cummax();dplyr 還提供了cummean() 函數(shù)以計(jì)算累加均值。

> x
 [1]  1  2  3  4  5  6  7  8  9 10
> cumsum(x)
 [1]  1  3  6 10 15 21 28 36 45 55
> cummean(x)
 [1] 1.000000 1.000000 1.333333 1.750000 2.200000 2.666667
 [7] 3.142857 3.625000 4.111111 4.600000

邏輯比較:<、<=、>、>= 和!=

如果需要進(jìn)行一系列復(fù)雜的邏輯運(yùn)算,那么最好將中間結(jié)果保存在新變量中,這樣就可以檢查是否每一步都符合預(yù)期。

排秩

排秩函數(shù)有很多,但你應(yīng)該從min_rank() 函數(shù)開(kāi)始,它可以完成最常用的排秩任務(wù)(如第一、第二、第三、第四)。默認(rèn)的排秩方式是,最小的值獲得最前面的名次,使用desc(x) 可以讓最大的值獲得最前面的名次

> y <- c(1, 2, 2, NA, 3, 4)
> min_rank(y)
[1]  1  2  2 NA  4  5
> min_rank(desc(y))
[1]  5  3  3 NA  2  1

如果min_rank() 無(wú)法滿(mǎn)足需要,那么可以看一下其變體row_number()、dense_rank()、percent_rank()、cume_dist() 和ntile()。

> row_number(y)
[1]  1  2  3 NA  4  5
> dense_rank(y)
[1]  1  2  2 NA  3  4
> percent_rank(y)
[1] 0.00 0.25 0.25   NA 0.75 1.00
> cume_dist(y)
[1] 0.2 0.6 0.6  NA 0.8 1.0

3.6 使用summarize()進(jìn)行分組摘要

最后一個(gè)核心函數(shù)是summarize(),它可以將數(shù)據(jù)框折疊成一行。group_by() 可以將分析單位從整個(gè)數(shù)據(jù)集更改為單個(gè)分組。接下來(lái),在分組后的數(shù)據(jù)框上使用dplyr 函數(shù)時(shí),它們會(huì)自動(dòng)地應(yīng)用到每個(gè)分組。例如,如果對(duì)按日期分組的一個(gè)數(shù)據(jù)框應(yīng)用與上面完全相同的代碼,那么我們就可以得到每日平均延誤時(shí)間:

> by_day <- group_by(flights, year, month, day)
> summarize(by_day, delay = mean(dep_delay, na.rm = TRUE))
`summarise()` regrouping output by 'year', 'month' (override with `.groups` argument)
# A tibble: 365 x 4
# Groups:   year, month [12]
    year month   day delay
   <int> <int> <int> <dbl>
 1  2013     1     1 11.5 
 2  2013     1     2 13.9 
 3  2013     1     3 11.0 
 4  2013     1     4  8.95
 5  2013     1     5  5.73
 6  2013     1     6  7.15
 7  2013     1     7  5.42
 8  2013     1     8  2.55
 9  2013     1     9  2.28
10  2013     1    10  2.84
# ... with 355 more rows

3.6.1 使用管道組合多種操作

假設(shè)我們想要研究每個(gè)目的地的距離和平均延誤時(shí)間之間的關(guān)系。使用已經(jīng)了解的dplyr
包功能,你可能會(huì)寫(xiě)出以下代碼:

by_dest <- group_by(flights, dest)
delay <- summarize(by_dest,
count = n(),
dist = mean(distance, na.rm = TRUE),
delay = mean(arr_delay, na.rm = TRUE)
)
delay <- filter(delay, count > 20, dest != "HNL")

這樣做不得不對(duì)每個(gè)中間數(shù)據(jù)框命名,會(huì)影響我們的分析速度。解決這個(gè)問(wèn)題的另一種方法是使用管道,%>%

delays <- flights %>%
group_by(dest) %>%
summarize(
count = n(),
dist = mean(distance, na.rm = TRUE),
delay = mean(arr_delay, na.rm = TRUE)
) %>%
filter(count > 20, dest != "HNL")

使用這種方法時(shí),x %>% f(y) 會(huì)轉(zhuǎn)換為f(x, y),x %>% f(y) %>% g(z) 會(huì)轉(zhuǎn)換為g(f(x,y), z),以此類(lèi)推。你可以使用管道重寫(xiě)多種操作,將其變?yōu)槟軌驈淖蟮接一驈纳系较麻喿x。

3.6.2 缺失值

在前面使用了參數(shù)na.rm,如果沒(méi)有設(shè)置這個(gè)參數(shù),會(huì)發(fā)生什么情況呢?

>by_day <- group_by(flights, year, month, day)
>summarize(by_day, delay = mean(dep_delay))
## 使用管道
> flights %>%
+   group_by(year, month, day) %>%
+   summarize(mean = mean(dep_delay))
`summarise()` regrouping output by 'year', 'month' (override with `.groups` argument)
# A tibble: 365 x 4
# Groups:   year, month [12]
    year month   day  mean
   <int> <int> <int> <dbl>
 1  2013     1     1    NA
 2  2013     1     2    NA
 3  2013     1     3    NA
 4  2013     1     4    NA
 5  2013     1     5    NA
 6  2013     1     6    NA
 7  2013     1     7    NA
 8  2013     1     8    NA
 9  2013     1     9    NA
10  2013     1    10    NA
# ... with 355 more rows

這是因?yàn)榫酆虾瘮?shù)遵循缺失值的一般規(guī)則:如果輸入中有缺失值,那么輸出也會(huì)是缺失值。好在所有聚合函數(shù)都有一個(gè)na.rm 參數(shù),它可以在計(jì)算前除去缺失值:

> flights %>%
+   group_by(year, month, day) %>%
+   summarize(mean = mean(dep_delay,na.rm= TRUE))
`summarise()` regrouping output by 'year', 'month' (override with `.groups` argument)
# A tibble: 365 x 4
# Groups:   year, month [12]
    year month   day  mean
   <int> <int> <int> <dbl>
 1  2013     1     1 11.5 
 2  2013     1     2 13.9 
 3  2013     1     3 11.0 
 4  2013     1     4  8.95
 5  2013     1     5  5.73
 6  2013     1     6  7.15
 7  2013     1     7  5.42
 8  2013     1     8  2.55
 9  2013     1     9  2.28
10  2013     1    10  2.84
# ... with 355 more rows

在這個(gè)示例中,缺失值表示取消的航班,我們也可以通過(guò)先去除取消的航班來(lái)解決缺失值
問(wèn)題。保存這個(gè)數(shù)據(jù)集,以便我們可以在接下來(lái)的幾個(gè)示例中繼續(xù)使用:

not_cancelled <- flights %>%
 filter(!is.na(dep_delay), !is.na(arr_delay))
> not_cancelled %>%
+   group_by(year, month, day) %>%
+   summarize(mean = mean(dep_delay))
`summarise()` regrouping output by 'year', 'month' (override with `.groups` argument)
# A tibble: 365 x 4
# Groups:   year, month [12]
    year month   day  mean
   <int> <int> <int> <dbl>
 1  2013     1     1 11.4 
 2  2013     1     2 13.7 
 3  2013     1     3 10.9 
 4  2013     1     4  8.97
 5  2013     1     5  5.73
 6  2013     1     6  7.15
 7  2013     1     7  5.42
 8  2013     1     8  2.56
 9  2013     1     9  2.30
10  2013     1    10  2.84
# ... with 355 more rows

3.6.3 計(jì)數(shù)

聚合操作中包括一個(gè)計(jì)數(shù)(n())或非缺失值的計(jì)數(shù)(sum(!is_na()))是個(gè)好主意。這樣你就可以檢查一下,以確保自己沒(méi)有基于非常少量的數(shù)據(jù)作出結(jié)論。例如,我們查看一下具有最長(zhǎng)平均延誤時(shí)間的飛機(jī)(通過(guò)機(jī)尾編號(hào)進(jìn)行識(shí)別):

delays <- not_cancelled %>%
  group_by(tailnum) %>%
  summarize(
    delay = mean(arr_delay)
  )
ggplot(data = delays, mapping = aes(x = delay)) +
  geom_freqpoly(binwidth = 10)

接下來(lái),畫(huà)一張航班數(shù)量和平均延誤時(shí)間的散點(diǎn)圖,以便獲得更深刻的理解:

delays <- not_cancelled %>%    
  group_by(tailnum) %>%  #--根據(jù)tailnum對(duì)not_cancelled分組
  summarize(
    delay = mean(arr_delay, na.rm = TRUE), 
    n = n()  #--根據(jù)每個(gè)組求arr_delay的平均值并計(jì)數(shù)
  )
# A tibble: 4,037 x 3
   tailnum  delay     n
   <chr>    <dbl> <int>
 1 D942DN  31.5       4
 2 N0EGMQ   9.98    352
 3 N10156  12.7     145
 4 N102UW   2.94     48
 5 N103US  -6.93     46
 6 N104UW   1.80     46
 7 N10575  20.7     269
 8 N105UW  -0.267    45
 9 N107US  -5.73     41
10 N108UW  -1.25     60
# ... with 4,027 more rows
ggplot(data = delays, mapping = aes(x = n, y = delay)) +
  geom_point(alpha = 1/10)

當(dāng)航班數(shù)量非常少時(shí),平均延誤時(shí)間的變動(dòng)特別大。這張圖的形狀非常能夠說(shuō)明問(wèn)題:當(dāng)繪制均值(或其他摘要統(tǒng)計(jì)量)和分組規(guī)模的關(guān)系時(shí),你總能看到隨著樣本量的增加,變動(dòng)在不斷減小。

查看此類(lèi)圖形時(shí),通常應(yīng)該篩選掉那些觀測(cè)數(shù)量非常少的分組,這樣你就可以避免受到特
別小的分組中的極端變動(dòng)的影響,進(jìn)而更好地發(fā)現(xiàn)數(shù)據(jù)模式。

> delays %>%
+   filter(n > 25) %>%
+   ggplot(mapping = aes(x = n, y = delay)) +
+   geom_point(alpha = 1/10)

3.6.4 常用的摘要函數(shù)

只使用均值、計(jì)數(shù)和求和是遠(yuǎn)遠(yuǎn)不夠的,R 中還提供了很多其他的常用的摘要函數(shù)。

位置度量

我們已經(jīng)使用過(guò)mean(x),但median(x) 也非常有用。均值是總數(shù)除以個(gè)數(shù);中位數(shù)則
是這樣一個(gè)值:50% 的x 大于它,同時(shí)50% 的x 小于它。

> not_cancelled %>%
+   group_by(year, month, day) %>%
+   summarize(
+     # 平均延誤時(shí)間:
+     avg_delay1 = mean(arr_delay),
+     # 平均正延誤時(shí)間:
+     avg_delay2 = mean(arr_delay[arr_delay > 0])
+   )
`summarise()` regrouping output by 'year', 'month' (override with `.groups` argument)
# A tibble: 365 x 5
# Groups:   year, month [12]
    year month   day avg_delay1 avg_delay2
   <int> <int> <int>      <dbl>      <dbl>
 1  2013     1     1     12.7         32.5
 2  2013     1     2     12.7         32.0
 3  2013     1     3      5.73        27.7
 4  2013     1     4     -1.93        28.3
 5  2013     1     5     -1.53        22.6
 6  2013     1     6      4.24        24.4
 7  2013     1     7     -4.95        27.8
 8  2013     1     8     -3.23        20.8
 9  2013     1     9     -0.264       25.6
10  2013     1    10     -5.90        27.3
# ... with 355 more rows

分散程度度量:sd(x)、IQR(x) 和mad(x)

均方誤差(又稱(chēng)標(biāo)準(zhǔn)誤差,standard deviation,sd)是分散程度的標(biāo)準(zhǔn)度量方式。四分位距IQR() 和絕對(duì)中位差mad(x) 基本等價(jià),更適合有離群點(diǎn)的情況:

> # 為什么到某些目的地的距離比到其他目的地更多變?
> not_cancelled %>%
+   group_by(dest) %>%
+   summarize(distance_sd = sd(distance)) %>%
+   arrange(desc(distance_sd))
`summarise()` ungrouping output (override with `.groups` argument)
# A tibble: 104 x 2
   dest  distance_sd
   <chr>       <dbl>
 1 EGE         10.5
 2 SAN         10.4
 3 SFO         10.2
 4 HNL         10.0
 5 SEA          9.98
 6 LAS          9.91
 7 PDX          9.87
 8 PHX          9.86
 9 LAX          9.66
10 IND          9.46
# ... with 94 more rows

秩的度量:min(x)、quantile(x, 0.25) 和max(x)

分位數(shù)是中位數(shù)的擴(kuò)展。例如,quantile(x, 0.25) 會(huì)找出x 中按從小到大順序大于前25% 而小于后75% 的值:

> # 每天最早和最晚的航班何時(shí)出發(fā)?
> not_cancelled %>%
+   group_by(year, month, day) %>%
+   summarize(
+     first = min(dep_time),
+     last = max(dep_time)
+   )
`summarise()` regrouping output by 'year', 'month' (override with `.groups` argument)
# A tibble: 365 x 5
# Groups:   year, month [12]
    year month   day first  last
   <int> <int> <int> <int> <int>
 1  2013     1     1   517  2356
 2  2013     1     2    42  2354
 3  2013     1     3    32  2349
 4  2013     1     4    25  2358
 5  2013     1     5    14  2357
 6  2013     1     6    16  2355
 7  2013     1     7    49  2359
 8  2013     1     8   454  2351
 9  2013     1     9     2  2252
10  2013     1    10     3  2320
# ... with 355 more rows

定位度量:first(x)、nth(x, 2) 和last(x)

這幾個(gè)函數(shù)的作用與x[1]、x[2] 和x[length(x)] 相同,只是當(dāng)定位不存在時(shí)(比如嘗試從只有兩個(gè)元素的分組中得到第三個(gè)元素),前者允許你設(shè)置一個(gè)默認(rèn)值。例如,我們可以找出每天最早和最晚出發(fā)的航班:

> not_cancelled %>%
+   group_by(year, month, day) %>%
+   summarize(
+     first_dep = first(dep_time),
+     last_dep = last(dep_time)
+   )
`summarise()` regrouping output by 'year', 'month' (override with `.groups` argument)
# A tibble: 365 x 5
# Groups:   year, month [12]
    year month   day first_dep last_dep
   <int> <int> <int>     <int>    <int>
 1  2013     1     1       517     2356
 2  2013     1     2        42     2354
 3  2013     1     3        32     2349
 4  2013     1     4        25     2358
 5  2013     1     5        14     2357
 6  2013     1     6        16     2355
 7  2013     1     7        49     2359
 8  2013     1     8       454     2351
 9  2013     1     9         2     2252
10  2013     1    10         3     2320
# ... with 355 more rows

計(jì)數(shù)

已經(jīng)使用過(guò)n(),它不需要任何參數(shù),并返回當(dāng)前分組的大小。如果想要計(jì)算出非缺失值的數(shù)量,可以使用sum(!is.na(x))。要想計(jì)算出唯一值的數(shù)量,可以使用n_distinct(x):

> # 哪個(gè)目的地具有最多的航空公司?
> not_cancelled %>%
+   group_by(dest) %>%
+   summarize(carriers = n_distinct(carrier)) %>%
+   arrange(desc(carriers))
`summarise()` ungrouping output (override with `.groups` argument)
# A tibble: 104 x 2
   dest  carriers
   <chr>    <int>
 1 ATL          7
 2 BOS          7
 3 CLT          7
 4 ORD          7
 5 TPA          7
 6 AUS          6
 7 DCA          6
 8 DTW          6
 9 IAD          6
10 MSP          6
# ... with 94 more rows

因?yàn)橛?jì)數(shù)太常用了,所以dplyr 提供了一個(gè)簡(jiǎn)單的輔助函數(shù),用于只需要計(jì)數(shù)的情況:

> not_cancelled %>%
+   count(dest)
# A tibble: 104 x 2
   dest      n
   <chr> <int>
 1 ABQ     254
 2 ACK     264
 3 ALB     418
 4 ANC       8
 5 ATL   16837
 6 AUS    2411
 7 AVL     261
 8 BDL     412
 9 BGR     358
10 BHM     269
# ... with 94 more rows

還可以選擇提供一個(gè)加權(quán)變量。例如,你可以使用以下代碼算出每架飛機(jī)飛行的總里程數(shù)(實(shí)際上就是求和):

> not_cancelled %>%
+   count(tailnum, wt = distance)
# A tibble: 4,037 x 2
   tailnum      n
   <chr>    <dbl>
 1 D942DN    3418
 2 N0EGMQ  239143
 3 N10156  109664
 4 N102UW   25722
 5 N103US   24619
 6 N104UW   24616
 7 N10575  139903
 8 N105UW   23618
 9 N107US   21677
10 N108UW   32070
# ... with 4,027 more rows

邏輯值的計(jì)數(shù)和比例:sum(x > 10) 和mean(y == 0)

當(dāng)與數(shù)值型函數(shù)一同使用時(shí),TRUE 會(huì)轉(zhuǎn)換為1,F(xiàn)ALSE 會(huì)轉(zhuǎn)換為0。這使得sum() 和mean()非常適用于邏輯值:sum(x) 可以找出x 中TRUE 的數(shù)量,mean(x) 則可以找出比例。

> # 多少架航班是在早上5點(diǎn)前出發(fā)的?(這通常表明前一天延誤的航班數(shù)量)
> not_cancelled %>%
+   group_by(year, month, day) %>%
+   summarize(n_early = sum(dep_time < 500))
`summarise()` regrouping output by 'year', 'month' (override with `.groups` argument)
# A tibble: 365 x 4
# Groups:   year, month [12]
    year month   day n_early
   <int> <int> <int>   <int>
 1  2013     1     1       0
 2  2013     1     2       3
 3  2013     1     3       4
 4  2013     1     4       3
 5  2013     1     5       3
 6  2013     1     6       2
 7  2013     1     7       2
 8  2013     1     8       1
 9  2013     1     9       3
10  2013     1    10       3
# ... with 355 more rows
> # 延誤超過(guò)1小時(shí)的航班比例是多少?
> not_cancelled %>%
+   group_by(year, month, day) %>%
+   summarize(hour_perc = mean(arr_delay > 60))
`summarise()` regrouping output by 'year', 'month' (override with `.groups` argument)
# A tibble: 365 x 4
# Groups:   year, month [12]
    year month   day hour_perc
   <int> <int> <int>     <dbl>
 1  2013     1     1    0.0722
 2  2013     1     2    0.0851
 3  2013     1     3    0.0567
 4  2013     1     4    0.0396
 5  2013     1     5    0.0349
 6  2013     1     6    0.0470
 7  2013     1     7    0.0333
 8  2013     1     8    0.0213
 9  2013     1     9    0.0202
10  2013     1    10    0.0183
# ... with 355 more rows

3.6.5 按多個(gè)變量分組

當(dāng)使用多個(gè)變量進(jìn)行分組時(shí),每次的摘要統(tǒng)計(jì)會(huì)用掉一個(gè)分組變量。這樣就可以輕松地對(duì)數(shù)據(jù)集進(jìn)行循序漸進(jìn)的分析

> daily <- group_by(flights, year, month, day)
> (per_day <- summarize(daily, flights = n()))
`summarise()` regrouping output by 'year', 'month' (override with `.groups` argument)
# A tibble: 365 x 4
# Groups:   year, month [12]
    year month   day flights
   <int> <int> <int>   <int>
 1  2013     1     1     842
 2  2013     1     2     943
 3  2013     1     3     914
 4  2013     1     4     915
 5  2013     1     5     720
 6  2013     1     6     832
 7  2013     1     7     933
 8  2013     1     8     899
 9  2013     1     9     902
10  2013     1    10     932
# ... with 355 more rows

> (per_month <- summarize(per_day, flights = sum(flights)))
`summarise()` regrouping output by 'year' (override with `.groups` argument)
# A tibble: 12 x 3
# Groups:   year [1]
    year month flights
   <int> <int>   <int>
 1  2013     1   27004
 2  2013     2   24951
 3  2013     3   28834
 4  2013     4   28330
 5  2013     5   28796
 6  2013     6   28243
 7  2013     7   29425
 8  2013     8   29327
 9  2013     9   27574
10  2013    10   28889
11  2013    11   27268
12  2013    12   28135

#可以發(fā)現(xiàn)day分組已經(jīng)消失

3.6.6 取消分組

如果想要取消分組,并回到未分組的數(shù)據(jù)繼續(xù)操作,那么可以使用ungroup() 函數(shù):

> daily %>%
+     ungroup() %>% # 不再按日期分組
+     summarize(flights = n()) # 所有航班
# A tibble: 1 x 1
  flights
    <int>
1  336776

3.7 分組新變量

雖然與summarize() 函數(shù)結(jié)合起來(lái)使用是最有效的,但分組也可以與mutate() 和filter()函數(shù)結(jié)合,以完成非常便捷的操作。

找出每個(gè)分組中最差的成員:

> flights_sml %>%
+     group_by(year, month, day) %>%
+     filter(rank(desc(arr_delay)) < 10)
# A tibble: 3,306 x 7
# Groups:   year, month, day [365]
    year month   day dep_delay arr_delay distance air_time
   <int> <int> <int>     <dbl>     <dbl>    <dbl>    <dbl>
 1  2013     1     1       853       851      184       41
 2  2013     1     1       290       338     1134      213
 3  2013     1     1       260       263      266       46
 4  2013     1     1       157       174      213       60
 5  2013     1     1       216       222      708      121
 6  2013     1     1       255       250      589      115
 7  2013     1     1       285       246     1085      146
 8  2013     1     1       192       191      199       44
 9  2013     1     1       379       456     1092      222
10  2013     1     2       224       207      550       94
# ... with 3,296 more rows

找出大于某個(gè)閾值的所有分組:

> popular_dests <- flights %>%
+   group_by(dest) %>%
+   filter(n() > 365)
> popular_dests
# A tibble: 332,577 x 19
# Groups:   dest [77]
    year month   day dep_time sched_dep_time dep_delay
   <int> <int> <int>    <int>          <int>     <dbl>
 1  2013     1     1      517            515         2
 2  2013     1     1      533            529         4
 3  2013     1     1      542            540         2
 4  2013     1     1      544            545        -1
 5  2013     1     1      554            600        -6
 6  2013     1     1      554            558        -4
 7  2013     1     1      555            600        -5
 8  2013     1     1      557            600        -3
 9  2013     1     1      557            600        -3
10  2013     1     1      558            600        -2
# ... with 332,567 more rows, and 13 more variables:
#   arr_time <int>, sched_arr_time <int>, arr_delay <dbl>,
#   carrier <chr>, flight <int>, tailnum <chr>, origin <chr>,
#   dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
#   minute <dbl>, time_hour <dttm>

對(duì)數(shù)據(jù)進(jìn)行標(biāo)準(zhǔn)化以計(jì)算分組指標(biāo):

> popular_dests %>%
+   filter(arr_delay > 0) %>%
+   mutate(prop_delay = arr_delay / sum(arr_delay)) %>%
+   select(year:day, dest, arr_delay, prop_delay)
# A tibble: 131,106 x 6
# Groups:   dest [77]
    year month   day dest  arr_delay prop_delay
   <int> <int> <int> <chr>     <dbl>      <dbl>
 1  2013     1     1 IAH          11  0.000111
 2  2013     1     1 IAH          20  0.000201
 3  2013     1     1 MIA          33  0.000235
 4  2013     1     1 ORD          12  0.0000424
 5  2013     1     1 FLL          19  0.0000938
 6  2013     1     1 ORD           8  0.0000283
 7  2013     1     1 LAX           7  0.0000344
 8  2013     1     1 DFW          31  0.000282
 9  2013     1     1 ATL          12  0.0000400
10  2013     1     1 DTW          16  0.000116
# ... with 131,096 more rows

轉(zhuǎn)載請(qǐng)注明周小釗的博客>>R4ds2

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,505評(píng)論 6 533
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,556評(píng)論 3 418
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 176,463評(píng)論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 63,009評(píng)論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,778評(píng)論 6 410
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 55,218評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,281評(píng)論 3 441
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,436評(píng)論 0 288
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,969評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,795評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,993評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,537評(píng)論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,229評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 34,659評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 35,917評(píng)論 1 286
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,687評(píng)論 3 392
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,990評(píng)論 2 374