参考資料
- dplyr of Datacamp: 実はこんなもん読むよりこっちのホームページへアクセスして実習した方が100倍いいと思う。
- Introduction to dplyr
dplyrはR業界の神様、Hadley Wickhamが作成したRのパッケージである。 R内蔵の関数でもデータの管理はできるが、dplyrを使うと生産性は何倍も向上する。
dplyrの主な使い道は以下のとおり
関数名 | 機能 |
---|---|
filter
|
ある条件に合ったケースだけを抽出 |
arrange
|
データをある基準に合わせて揃える |
select
|
指定した変数のみを抽出 |
mutate
|
計算した結果を新しい変数として定義 |
summarise
|
データの要約 |
これらの機能を最大限発揮するために、いくつかの良き友達がいる
関数名 | 機能 |
---|---|
group_by
|
データのグループ化 |
%>% (注)
|
複数の処理を逐次的に実行 |
※なぜか2行目は%>%
と表示されていますが、正しいのは%>%
です。
実習の準備
まずは、dplyrのインストールと読み込みである。dplyrはCRANに登録されているので、install.packages()
でインストールできる。
install.packages("dplyr")
library(dplyr)
##
## Attaching package: 'dplyr'
## The following object is masked from 'package:kableExtra':
##
## group_rows
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
実習用データは有名なnycflights13
データを使う。これはニューヨーク出発の航空便のデータで、336,776のケースが含まれている。インストールされていない場合、install.packages("nycflights13")
でインストールしておこう。
まず、データを読み込み、中身を見てみよう。
library(nycflights13)
head(flights) # データの中身を見る(最初の6行だけ)
## # A tibble: 6 x 19
## year month day dep_time sched_dep_time dep_delay arr_time sched_arr_time
## <int> <int> <int> <int> <int> <dbl> <int> <int>
## 1 2013 1 1 517 515 2 830 819
## 2 2013 1 1 533 529 4 850 830
## 3 2013 1 1 542 540 2 923 850
## 4 2013 1 1 544 545 -1 1004 1022
## 5 2013 1 1 554 600 -6 812 837
## 6 2013 1 1 554 558 -4 740 728
## # … with 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>
filter()
filter()
はある条件に合ったケースのみを抽出する関数である。使い方はfilter(データ, 条件)
である。ここでデータはflights
である。試しに3月のデータだけを抽出してみる。月はmonth
変数である。
filter(flights, month == 3)
## # A tibble: 28,834 x 19
## year month day dep_time sched_dep_time dep_delay arr_time sched_arr_time
## <int> <int> <int> <int> <int> <dbl> <int> <int>
## 1 2013 3 1 4 2159 125 318 56
## 2 2013 3 1 50 2358 52 526 438
## 3 2013 3 1 117 2245 152 223 2354
## 4 2013 3 1 454 500 -6 633 648
## 5 2013 3 1 505 515 -10 746 810
## 6 2013 3 1 521 530 -9 813 827
## 7 2013 3 1 537 540 -3 856 850
## 8 2013 3 1 541 545 -4 1014 1023
## 9 2013 3 1 549 600 -11 639 703
## 10 2013 3 1 550 600 -10 747 801
## # … with 28,824 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>
ここで注意すべきなのはmonth = 3
ではなく、month == 3
ということだ。 ほとんどの言語で=
は代入を意味する。「同じ」を意味するわけではない。
簡単にまとめてみよう
演算子 | 意味 |
---|---|
A == B | AとBは同値 |
A < B | AはBより小さい(未満) |
A > B | AはBより大きい(超過) |
A <= B | AはBより小さいか、同じ(以下) |
A >= B | AはBより大きいか、同じ(以上) |
A != B | AとBは同じではない |
先ほどの例では3月(month == 3
)のデータを抽出したが、もっと条件を絞ることもできる。
たとえば、3月10日に絞りたい場合の条件式はmonth == 3 & day == 10
である。
filter(flights, month == 3 & day == 10)
## # A tibble: 908 x 19
## year month day dep_time sched_dep_time dep_delay arr_time sched_arr_time
## <int> <int> <int> <int> <int> <dbl> <int> <int>
## 1 2013 3 10 6 2359 7 336 338
## 2 2013 3 10 41 2100 221 230 2257
## 3 2013 3 10 44 2355 49 416 340
## 4 2013 3 10 153 2253 180 302 14
## 5 2013 3 10 454 500 -6 628 648
## 6 2013 3 10 512 515 -3 742 814
## 7 2013 3 10 535 540 -5 819 850
## 8 2013 3 10 553 600 -7 815 830
## 9 2013 3 10 555 600 -5 848 910
## 10 2013 3 10 556 600 -4 801 805
## # … with 898 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>
&
はANDを意味する。もし、3月10日と11日のデータがほしいなるどうすればいいか。 この場合、OR表現が必要となる。ORは|
と書く。
filter(flights, month == 3 & (day == 10 | day == 11))
## # A tibble: 1,888 x 19
## year month day dep_time sched_dep_time dep_delay arr_time sched_arr_time
## <int> <int> <int> <int> <int> <dbl> <int> <int>
## 1 2013 3 10 6 2359 7 336 338
## 2 2013 3 10 41 2100 221 230 2257
## 3 2013 3 10 44 2355 49 416 340
## 4 2013 3 10 153 2253 180 302 14
## 5 2013 3 10 454 500 -6 628 648
## 6 2013 3 10 512 515 -3 742 814
## 7 2013 3 10 535 540 -5 819 850
## 8 2013 3 10 553 600 -7 815 830
## 9 2013 3 10 555 600 -5 848 910
## 10 2013 3 10 556 600 -4 801 805
## # … with 1,878 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>
ここで条件式はANDとORの組み合わせになっている。簡単に表現すると「A and (B or C)」である。これは
- (AかつB) あるいは(AかつC)
を意味する。ちなみに以上のコマンドはもっと省略できる。
filter(flights, month == 3 & (day == 10 | 11))
## # A tibble: 28,834 x 19
## year month day dep_time sched_dep_time dep_delay arr_time sched_arr_time
## <int> <int> <int> <int> <int> <dbl> <int> <int>
## 1 2013 3 1 4 2159 125 318 56
## 2 2013 3 1 50 2358 52 526 438
## 3 2013 3 1 117 2245 152 223 2354
## 4 2013 3 1 454 500 -6 633 648
## 5 2013 3 1 505 515 -10 746 810
## 6 2013 3 1 521 530 -9 813 827
## 7 2013 3 1 537 540 -3 856 850
## 8 2013 3 1 541 545 -4 1014 1023
## 9 2013 3 1 549 600 -11 639 703
## 10 2013 3 1 550 600 -10 747 801
## # … with 28,824 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>
day ==
を一回書くだけでも結果は同じ。ちなみに、OR演算の他の表現法もある。それは%in%である。 A %in% (1, 2, 3, 4)
は「Aが1, 2, 3, 4どっちかに該当するか」を意味する。これを使って先のコマンドを書きなおしてみよう。
filter(flights, month == 3 & (day %in% c(10, 11)))
## # A tibble: 1,888 x 19
## year month day dep_time sched_dep_time dep_delay arr_time sched_arr_time
## <int> <int> <int> <int> <int> <dbl> <int> <int>
## 1 2013 3 10 6 2359 7 336 338
## 2 2013 3 10 41 2100 221 230 2257
## 3 2013 3 10 44 2355 49 416 340
## 4 2013 3 10 153 2253 180 302 14
## 5 2013 3 10 454 500 -6 628 648
## 6 2013 3 10 512 515 -3 742 814
## 7 2013 3 10 535 540 -5 819 850
## 8 2013 3 10 553 600 -7 815 830
## 9 2013 3 10 555 600 -5 848 910
## 10 2013 3 10 556 600 -4 801 805
## # … with 1,878 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>
やはり結果は変わらない。ちなみに、Rで複数の要素(数字でも文字でも)を並ぶときにはc()
を使う。ただし、一つのベクトルに数字が文字が混在されることはない。
このデータを使っては実習できないが、欠損値のあるケースを除去したい場合もあろう。 たとえば、year
が欠損値になってるケースが除去したいならfilter(flights, year == NA)
で良いだろうか。
実は違う。
この場合はis.na(year)
と書く。理由は聞かないでほしい。
arrange()
arrange
はケースをある基準に合わせて並べ直す関数である。
特に意味はないが、データをmonth
が小さい順に並べてみよう。
arrange(flights, month)
## # A tibble: 336,776 x 19
## year month day dep_time sched_dep_time dep_delay arr_time sched_arr_time
## <int> <int> <int> <int> <int> <dbl> <int> <int>
## 1 2013 1 1 517 515 2 830 819
## 2 2013 1 1 533 529 4 850 830
## 3 2013 1 1 542 540 2 923 850
## 4 2013 1 1 544 545 -1 1004 1022
## 5 2013 1 1 554 600 -6 812 837
## 6 2013 1 1 554 558 -4 740 728
## 7 2013 1 1 555 600 -5 913 854
## 8 2013 1 1 557 600 -3 709 723
## 9 2013 1 1 557 600 -3 838 846
## 10 2013 1 1 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>
もし、大きい方から表示したいならdesc()
を使う。
arrange(flights, desc(month))
## # A tibble: 336,776 x 19
## year month day dep_time sched_dep_time dep_delay arr_time sched_arr_time
## <int> <int> <int> <int> <int> <dbl> <int> <int>
## 1 2013 12 1 13 2359 14 446 445
## 2 2013 12 1 17 2359 18 443 437
## 3 2013 12 1 453 500 -7 636 651
## 4 2013 12 1 520 515 5 749 808
## 5 2013 12 1 536 540 -4 845 850
## 6 2013 12 1 540 550 -10 1005 1027
## 7 2013 12 1 541 545 -4 734 755
## 8 2013 12 1 546 545 1 826 835
## 9 2013 12 1 549 600 -11 648 659
## 10 2013 12 1 550 600 -10 825 854
## # … 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>
次は「month
の順で並べて、もし同じなら、次はday
の順で並べたい」である。どうすればいいだろうか。実はこれも簡単だ。 条件式に次の基準となる変数名を入れるだけでいい。
arrange(flights, month, day)
## # A tibble: 336,776 x 19
## year month day dep_time sched_dep_time dep_delay arr_time sched_arr_time
## <int> <int> <int> <int> <int> <dbl> <int> <int>
## 1 2013 1 1 517 515 2 830 819
## 2 2013 1 1 533 529 4 850 830
## 3 2013 1 1 542 540 2 923 850
## 4 2013 1 1 544 545 -1 1004 1022
## 5 2013 1 1 554 600 -6 812 837
## 6 2013 1 1 554 558 -4 740 728
## 7 2013 1 1 555 600 -5 913 854
## 8 2013 1 1 557 600 -3 709 723
## 9 2013 1 1 557 600 -3 838 846
## 10 2013 1 1 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>
これを「month
は12から1へ、day
も31から1の順で並べたい」と思うなら
arrange(flights, desc(month), desc(day))
## # A tibble: 336,776 x 19
## year month day dep_time sched_dep_time dep_delay arr_time sched_arr_time
## <int> <int> <int> <int> <int> <dbl> <int> <int>
## 1 2013 12 31 13 2359 14 439 437
## 2 2013 12 31 18 2359 19 449 444
## 3 2013 12 31 26 2245 101 129 2353
## 4 2013 12 31 459 500 -1 655 651
## 5 2013 12 31 514 515 -1 814 812
## 6 2013 12 31 549 551 -2 925 900
## 7 2013 12 31 550 600 -10 725 745
## 8 2013 12 31 552 600 -8 811 826
## 9 2013 12 31 553 600 -7 741 754
## 10 2013 12 31 554 550 4 1024 1027
## # … 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>
最後に、欠損値(NA
)は常に一番最後の行になる。
select()
これは指定した変数のみを抽出する関数である。
まず、year
, month
, day
列のみを抽出してみよう。
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
は「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
まで表示するのではなくyear
からday
までを表示させないこともできる。その時に使うのが-
である。
select(flights, -(year:day))
## # A tibble: 336,776 x 16
## dep_time sched_dep_time dep_delay arr_time sched_arr_time arr_delay carrier
## <int> <int> <dbl> <int> <int> <dbl> <chr>
## 1 517 515 2 830 819 11 UA
## 2 533 529 4 850 830 20 UA
## 3 542 540 2 923 850 33 AA
## 4 544 545 -1 1004 1022 -18 B6
## 5 554 600 -6 812 837 -25 DL
## 6 554 558 -4 740 728 12 UA
## 7 555 600 -5 913 854 19 B6
## 8 557 600 -3 709 723 -14 EV
## 9 557 600 -3 838 846 -8 B6
## 10 558 600 -2 753 745 8 AA
## # … with 336,766 more rows, and 9 more variables: flight <int>, tailnum <chr>,
## # origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
## # minute <dbl>, time_hour <dttm>
-year:day
でなく、-(year:day)
であることに注意しよう。もし:
を使わないなら-c(year, month, day)
のように書く。
select(flights, -c(year, month, day))
## # A tibble: 336,776 x 16
## dep_time sched_dep_time dep_delay arr_time sched_arr_time arr_delay carrier
## <int> <int> <dbl> <int> <int> <dbl> <chr>
## 1 517 515 2 830 819 11 UA
## 2 533 529 4 850 830 20 UA
## 3 542 540 2 923 850 33 AA
## 4 544 545 -1 1004 1022 -18 B6
## 5 554 600 -6 812 837 -25 DL
## 6 554 558 -4 740 728 12 UA
## 7 555 600 -5 913 854 19 B6
## 8 557 600 -3 709 723 -14 EV
## 9 557 600 -3 838 846 -8 B6
## 10 558 600 -2 753 745 8 AA
## # … with 336,766 more rows, and 9 more variables: flight <int>, tailnum <chr>,
## # origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
## # minute <dbl>, time_hour <dttm>
これだけでもselect()
は大変便利な関数だが、もっと高度な使い方もある。
まずは、そのリストから
演算子 | 意味 |
---|---|
starts_with("ABC")
|
変数名がABCで始まる変数 |
ends_with("XYZ")
|
変数名がXYZで終わる変数 |
contains("LMN")
|
変数名にLMNが含まれている変数 |
matches("(.)\\1")
|
正規表現パターン |
num_range("X", 1:3)
|
X1, X2, X3 |
まずは、変数名がdep
で始まる変数のみを抽出してみる。
select(flights, starts_with("dep"))
## # A tibble: 336,776 x 2
## dep_time dep_delay
## <int> <dbl>
## 1 517 2
## 2 533 4
## 3 542 2
## 4 544 -1
## 5 554 -6
## 6 554 -4
## 7 555 -5
## 8 557 -3
## 9 557 -3
## 10 558 -2
## # … with 336,766 more rows
続いて、変数名がtime
で終わるやつ
select(flights, ends_with("time"))
## # A tibble: 336,776 x 5
## dep_time sched_dep_time arr_time sched_arr_time air_time
## <int> <int> <int> <int> <dbl>
## 1 517 515 830 819 227
## 2 533 529 850 830 227
## 3 542 540 923 850 160
## 4 544 545 1004 1022 183
## 5 554 600 812 837 116
## 6 554 558 740 728 150
## 7 555 600 913 854 158
## 8 557 600 709 723 53
## 9 557 600 838 846 140
## 10 558 600 753 745 138
## # … with 336,766 more rows
最後に_
(アンダーバー)が含まれているやつ
select(flights, contains("_"))
## # A tibble: 336,776 x 8
## dep_time sched_dep_time dep_delay arr_time sched_arr_time arr_delay air_time
## <int> <int> <dbl> <int> <int> <dbl> <dbl>
## 1 517 515 2 830 819 11 227
## 2 533 529 4 850 830 20 227
## 3 542 540 2 923 850 33 160
## 4 544 545 -1 1004 1022 -18 183
## 5 554 600 -6 812 837 -25 116
## 6 554 558 -4 740 728 12 150
## 7 555 600 -5 913 854 19 158
## 8 557 600 -3 709 723 -14 53
## 9 557 600 -3 838 846 -8 140
## 10 558 600 -2 753 745 8 138
## # … with 336,766 more rows, and 1 more variable: time_hour <dttm>
matches
に関しては私も詳しくない。正規表現を使う時はいつもネットを参照しているので…
num_range
はこのデータでは使えないがselect(data, num_range("X", 3:5))
と書いたら、data
というデータからX3
, X4
, X5
のみを抽出せよという意味である。
個人的にあまり使わない機能だが、抽出後、新しい名前を付けることもできる。
select(flights, 年 = year, 月 = month, 日 = day)
## # A tibble: 336,776 x 3
## 年 月 日
## <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
mutate()
mutate
はデータを計算し、その結果を新しい変数として格納する関数である。
使い方はmutate(データ, 新しい変数名 = 計算式)
である。
とくに意味はないが、年(year
)を2倍にし、double_year
という変数として表示させてみよう。 (変数が多すぎて画面上に表示されないので、year
からday
まで抽出したデータ(flights2
)を使う。)
flights2 <- select(flights, year:day)
mutate(flights2, doble_year = year * 2)
## # A tibble: 336,776 x 4
## year month day doble_year
## <int> <int> <int> <dbl>
## 1 2013 1 1 4026
## 2 2013 1 1 4026
## 3 2013 1 1 4026
## 4 2013 1 1 4026
## 5 2013 1 1 4026
## 6 2013 1 1 4026
## 7 2013 1 1 4026
## 8 2013 1 1 4026
## 9 2013 1 1 4026
## 10 2013 1 1 4026
## # … with 336,766 more rows
ちゃんとdouble_year
という列さ生成されて、year
の2倍になっていることが分かる。
次はyear
、month
、day
を全部足し、sum_data
と名付けよう。
mutate(flights2, sum_date = year + month + day)
## # A tibble: 336,776 x 4
## year month day sum_date
## <int> <int> <int> <int>
## 1 2013 1 1 2015
## 2 2013 1 1 2015
## 3 2013 1 1 2015
## 4 2013 1 1 2015
## 5 2013 1 1 2015
## 6 2013 1 1 2015
## 7 2013 1 1 2015
## 8 2013 1 1 2015
## 9 2013 1 1 2015
## 10 2013 1 1 2015
## # … with 336,766 more rows
これ以外にもcumsum
、log
などの関数を使うこともできるし、平均値を引くことも出来る。
例としてday
からday
の平均値を引いた値をcentered_day
として表示させてみる。
mutate(flights2, centered_day = day - mean(day))
## # A tibble: 336,776 x 4
## year month day centered_day
## <int> <int> <int> <dbl>
## 1 2013 1 1 -14.7
## 2 2013 1 1 -14.7
## 3 2013 1 1 -14.7
## 4 2013 1 1 -14.7
## 5 2013 1 1 -14.7
## 6 2013 1 1 -14.7
## 7 2013 1 1 -14.7
## 8 2013 1 1 -14.7
## 9 2013 1 1 -14.7
## 10 2013 1 1 -14.7
## # … with 336,766 more rows
summarise()
summarise
は変数の平均、中央値、標準偏差などの統計量を表示させる関数である。
使い方はsummarise(データ, 新しい変数名 = 関数(変数))
である。
ここではflight
データに戻ってdep_time
とarr_time
の平均値を見てみたい。 dep_time
の平均値はdep.mean
、arr_time
の平均値はarr.mean
としよう。
summarise(flights, dep.mean = mean(dep_time), arr.mean = mean(arr_time))
## # A tibble: 1 x 2
## dep.mean arr.mean
## <dbl> <dbl>
## 1 NA NA
mean()
関数は欠損値が含まれているとNA
を返すので、これを無視するように引数としてna.rm = TRUE
を付ける。
summarise(flights,
dep.mean = mean(dep_time, na.rm = TRUE),
arr.mean = mean(arr_time, na.rm = TRUE))
## # A tibble: 1 x 2
## dep.mean arr.mean
## <dbl> <dbl>
## 1 1349. 1502.
ちゃんと出来た。
ここでのmean()
以外に標準偏差(sd()
)、IQR(IQR()
)、中央値(median()
)なども使える。 また、よく使われるものとしてケース数(n()
)がある。
summarise
関数はこれから紹介するgroup_by
と一緒に使う時が多い。
group_by()と%>%
pipeline (%>%)
まずは%>%
から紹介する。実はこれはdplyr独特のものではないが、dplyrとの相性がいい。
先ほど、flights
の変数が多すぎてyear:day
のみ抽出し、mutate
を使ったの例を考えてみる。 まずはflights2
を作って、そこからmutate
をした。まぁ、二行で終わったし、そこまで面倒くさくはないかも知れない。
それでは次の例を考えてみよう。
year
,month
,day
,dep_delay
,carrier
を抽出- 3月のデータのみ抽出
dep_delay
を60で割って、sixty_delay
と名付ける。sixty_delay
が大きい順に並べ替える。
これをこれまでの方式でやってみよう。
temp.flights <- select(flights, year:day, dep_delay, carrier)
temp.flights <- filter(temp.flights, month == 3)
temp.flights <- mutate(temp.flights, sixty_delay = dep_delay / 60)
arrange(temp.flights, desc(sixty_delay))
## # A tibble: 28,834 x 6
## year month day dep_delay carrier sixty_delay
## <int> <int> <int> <dbl> <chr> <dbl>
## 1 2013 3 17 911 DL 15.2
## 2 2013 3 18 800 DL 13.3
## 3 2013 3 8 470 FL 7.83
## 4 2013 3 18 443 EV 7.38
## 5 2013 3 8 430 F9 7.17
## 6 2013 3 8 420 EV 7
## 7 2013 3 24 408 UA 6.8
## 8 2013 3 14 406 UA 6.77
## 9 2013 3 12 394 B6 6.57
## 10 2013 3 8 393 UA 6.55
## # … with 28,824 more rows
これを%>%を使って短めにする。
flights %>%
select(year:day, dep_delay, carrier) %>%
filter(month == 3) %>%
mutate(sixty_delay = dep_delay / 60) %>%
arrange(desc(sixty_delay))
## # A tibble: 28,834 x 6
## year month day dep_delay carrier sixty_delay
## <int> <int> <int> <dbl> <chr> <dbl>
## 1 2013 3 17 911 DL 15.2
## 2 2013 3 18 800 DL 13.3
## 3 2013 3 8 470 FL 7.83
## 4 2013 3 18 443 EV 7.38
## 5 2013 3 8 430 F9 7.17
## 6 2013 3 8 420 EV 7
## 7 2013 3 24 408 UA 6.8
## 8 2013 3 14 406 UA 6.77
## 9 2013 3 12 394 B6 6.57
## 10 2013 3 8 393 UA 6.55
## # … with 28,824 more rows
まったく同じ結果が得られた。
これまでselect()
やfilter()
などの関数の最初の引数はデータ名だったが、それも要らなくなった。
flights %>%
は「次に処理するデータはflights
です」という意味だ。この例ではflights
データを使ってselect()
をした。
select()
で絞られたデータはそのまま次のfilter()
のデータとして使われる。
こんな感じでデータが次々へと伝達されていくのが%>%
の素晴らしいところだ。
group_by()
では、最後にgroup_by()
を見てみよう。
これはある変数(ほとんどカテゴリカル変数)でデータをグループ化するものである。
たとえば各月の平均延着時間の見たいとする。
flights %>% filter(month == 1) %>% summarise(mean.delay = mean(dep_delay))
flights %>% filter(month == 2) %>% summarise(mean.delay = mean(dep_delay))
- …
flights %>% filter(month == 12) %>% summarise(mean.delay = mean(dep_delay))
のように12回やってもいいが、month
を基準にグループ化すると一瞬で終わる。
flights %>%
group_by(month) %>%
summarise(mean.delay = mean(dep_delay, na.rm = TRUE))
## `summarise()` ungrouping output (override with `.groups` argument)
## # A tibble: 12 x 2
## month mean.delay
## <int> <dbl>
## 1 1 10.0
## 2 2 10.8
## 3 3 13.2
## 4 4 13.9
## 5 5 13.0
## 6 6 20.8
## 7 7 21.7
## 8 8 12.6
## 9 9 6.72
## 10 10 6.24
## 11 11 5.44
## 12 12 16.6
これはflights
データをmonth
を基準にグループ化し、それぞれsummarise()
した結果を表示する仕組みである。
航空会社(carrier
)ごとに見てみよう。
flights %>%
group_by(carrier) %>%
summarise(mean.delay = mean(dep_delay, na.rm = TRUE)) %>%
arrange(desc(mean.delay))
## `summarise()` ungrouping output (override with `.groups` argument)
## # A tibble: 16 x 2
## carrier mean.delay
## <chr> <dbl>
## 1 F9 20.2
## 2 EV 20.0
## 3 YV 19.0
## 4 FL 18.7
## 5 WN 17.7
## 6 9E 16.7
## 7 B6 13.0
## 8 VX 12.9
## 9 OO 12.6
## 10 UA 12.1
## 11 MQ 10.6
## 12 DL 9.26
## 13 AA 8.59
## 14 AS 5.80
## 15 HA 4.90
## 16 US 3.78
F9社 (アメリカのFrontier Airlinesらしい)の平均延着時間が最も長いらしい。
グループは一つの変数でなく、複数の変数を指定することもできる。各航空会社の月別平均延着時間は
flights %>%
group_by(carrier, month) %>%
summarise(mean.delay = mean(dep_delay, na.rm = TRUE)) %>%
arrange(desc(mean.delay))
## `summarise()` regrouping output by 'carrier' (override with `.groups` argument)
## # A tibble: 185 x 3
## # Groups: carrier [16]
## carrier month mean.delay
## <chr> <int> <dbl>
## 1 OO 1 67
## 2 OO 8 64
## 3 OO 6 61
## 4 HA 1 54.4
## 5 YV 6 42.8
## 6 FL 7 41.2
## 7 FL 6 38.8
## 8 F9 5 35.9
## 9 VX 7 35.3
## 10 YV 3 31.9
## # … with 175 more rows
もっとも延着時間が長いのは7月の9E社 (アメリカのEndeavor Air)のようだ。
大雑把にdplyrの機能を紹介したが、ここで紹介したよりも多くの機能があり、その便利さは我らの想像を超えるほどだ。 興味のある人はDatacampとか、他のチュートリアルを見てみるのもいいと思う。