はじめに
今回はdplyr
パッケージのselect
関数をもっと効率よく使いこなすためのヘルパー関数について紹介したいと思います。select
関数はデータフレームから任意の列を選択して取り出す関数です。この関数を使いこなすにはヘルパー関数を使いこなす必要があります。ぜひこの記事で列を自由自在に取捨選択できるようになってください。
ちなみにselect関数の基本的な使い方は以下の記事にまとめましたのでよろしければ参考にして下さい。
ヘルパー関数一覧
ヘルパー関数はある関数を補強するために使われる関数です。今回はselect
関数の機能を補強してくれる関数を紹介します。
今回紹介する関数は以下の通りです。
- start_with():列名の接頭語で取捨選択(列名の頭にある共通の文字列などを認識させて選択)
- ends_with():列名の接尾語で取捨選択(列名の後ろにある共通の文字列などを認識させて選択)
- contains():指定した文字列が含まれる列を取捨選択
- num_range():列名に通し番号がついている場合に特定の数字範囲を指定して取捨選択
- one_of():文字列のどれかに一致する列を取捨選択
- everything():すべての列を取捨選択
- matches():正規表現で列を取捨選択
start_with()
start_with()
関数は列名の頭にある文字列を指定することができます。共通の文字列が列名の頭についているときはこの関数を使って一気に指定することができます。
今回は具体例としてtidyr
パッケージの中にあるデータセットである relig_income から 「$で始まる列」を選択したいと思います。
library(tidyverse) data = tidyr::relig_income select(data, starts_with("$"))
出力される結果の頭10行はこんな感じになります。(クリックで表示)
$10-20k | $20-30k | $30-40k | $40-50k | $50-75k | $75-100k | $100-150k | |
---|---|---|---|---|---|---|---|
1 | 34 | 60 | 81 | 76 | 137 | 122 | 109 |
2 | 27 | 37 | 52 | 35 | 70 | 73 | 59 |
3 | 21 | 30 | 34 | 33 | 58 | 62 | 39 |
4 | 617 | 732 | 670 | 638 | 1116 | 949 | 792 |
5 | 14 | 15 | 11 | 10 | 35 | 21 | 17 |
6 | 869 | 1064 | 982 | 881 | 1486 | 949 | 723 |
7 | 9 | 7 | 9 | 11 | 34 | 47 | 48 |
8 | 244 | 236 | 238 | 197 | 223 | 131 | 81 |
9 | 27 | 24 | 24 | 21 | 30 | 15 | 11 |
10 | 19 | 25 | 25 | 30 | 95 | 69 | 87 |
end_with()
end_with()
関数は列名の末尾にある文字列を指定することができます。共通の文字列が列名の末尾についているときはこの関数を使って一気に指定することができます。
今回は具体例としてdplyr
パッケージの中にあるデータセットである starwars から 「colorで終わる列」を選択したいと思います。
library(dplyr) data = dplyr::starwars select(data, name, ends_with("color"))
出力される結果の頭10行はこんな感じになります。(クリックで表示)
name | hair_color | skin_color | eye_color |
---|---|---|---|
Luke Skywalker | blond | fair | blue |
C-3PO | NA | gold | yellow |
R2-D2 | NA | white, blue | red |
Darth Vader | none | white | yellow |
Leia Organa | brown | light | brown |
Owen Lars | brown, grey | light | blue |
Beru Whitesun lars | brown | light | blue |
R5-D4 | NA | white, red | red |
Biggs Darklighter | black | light | brown |
Obi-Wan Kenobi | auburn, white | fair | blue-gray |
contains()
contains()
関数は列名に含まれている文字列を指定することができます。特定の文字列が共通して列名に入っている場合はこの関数で一気に指定することができます。start_with
やend_with
は列名の最初や最後の文字列を指定できますが、列名の両端ではなく、間の中途半端な所に共通する文字列がある場合はこちらを使うと良いです。
今回は具体例として適当に作ったデータフレームから「record」という文字列が列名に含まれる列を取り出したいと思います。
library(dplyr) library(magrittr) data = as.data.frame(cbind(LETTERS[1:5], matrix(rnorm(20), ncol = 4))) %>% set_colnames(c("SAMPLE", "A_record_before", "A_record_after", "B_record_before", "B_record_after")) select(data, contains("record"))
出力される結果はこんな感じになります。(クリックで表示)
A_record_before | A_record_after | B_record_before | B_record_after |
---|---|---|---|
-0.102787727 | -0.394289954 | -0.25336168 | 0.364581962 |
0.387671612 | -0.059313397 | 0.696963375 | 0.768532925 |
-0.053805041 | 1.100025372 | 0.556663199 | -0.112346212 |
-1.377059557 | 0.763175748 | -0.688755695 | 0.881107726 |
-0.414994563 | -0.164523596 | -0.707495157 | 0.39810588 |
ここでstart_with
、end_with
、contains
関数について列名のどこを参照しているのかを図にまとめたいと思います。これらの関数で参照している文字列は以下の通りです。
num_range()
num_range()
関数は列名に通し番号などが付いている場合に特定の番号範囲を指定することができます。全部の範囲ではなく特定の範囲に絞って列を選択したい時はstart_with
ではなくこちらの関数を使うことになります。
ここでは具体例としてtidyr
パッケージのbillboard
データから artist 列と wk8からwk12 までの列を選択するコードを紹介します。(billboardデータにはwk1からwk76までの列があります。)
library(dplyr) data = tidyr::billboard select(data, artist, num_range(prefix = "wk", range = 8:12))
出力される結果の頭10行はこんな感じになります。(クリックで表示)
artist | wk8 | wk9 | wk10 | wk11 | wk12 |
---|---|---|---|---|---|
2 Pac | NA | NA | NA | NA | NA |
2Ge+her | NA | NA | NA | NA | NA |
3 Doors Down | 53 | 51 | 51 | 51 | 51 |
3 Doors Down | 59 | 62 | 61 | 61 | 59 |
504 Boyz | 49 | 53 | 57 | 64 | 70 |
980 | 2 | 3 | 6 | 7 | 22 |
A*Teens | NA | NA | NA | NA | NA |
Aaliyah | 38 | 38 | 36 | 37 | 37 |
Aaliyah | 14 | 12 | 10 | 9 | 8 |
Adams, Yolanda | 58 | 57 | 59 | 66 | 68 |
この関数のイメージは以下の通りです。
one_of()
one_of()
関数は文字列ベクトルを用いて列を指定することができます。列名を列挙した文字列ベクトルをあらかじめ作成している時はこの関数を使うことでベクトルの中身で列を指定することができます。
select
関数では第2引数以降で列名を列挙するときにダブルクオーテーションで列名を囲う必要がありません。そのため文字列なのかオブジェクト(定義した変数)なのかこの関数内で判断することができません。このことにより列名を代入したオブジェクトを本来であれば第2引数以降で指定することができないことになっています。しかしここで紹介したone_of()
関数を使えばあらかじめ列名を列挙したオブジェクトを利用して列を選択できるようになるのです。
ここではwk1からwk5という文字列を格納した candidate 変数を作成し、この変数を使って先ほどの billboard データから列を選択したいと思います。
library(dplyr) data = tidyr::billboard candidates = paste0("wk", 1:5) select(data, artist, one_of(candidates))
出力される結果の頭10行はこんな感じになります。(クリックで表示)
artist | wk1 | wk2 | wk3 | wk4 | wk5 |
---|---|---|---|---|---|
2 Pac | 87 | 82 | 72 | 77 | 87 |
2Ge+her | 91 | 87 | 92 | NA | NA |
3 Doors Down | 81 | 70 | 68 | 67 | 66 |
3 Doors Down | 76 | 76 | 72 | 69 | 67 |
504 Boyz | 57 | 34 | 25 | 17 | 17 |
980 | 51 | 39 | 34 | 26 | 26 |
A*Teens | 97 | 97 | 96 | 95 | 100 |
Aaliyah | 84 | 62 | 51 | 41 | 38 |
Aaliyah | 59 | 53 | 38 | 28 | 21 |
Adams, Yolanda | 76 | 76 | 74 | 69 | 68 |
ちなみにこの関数では文字列ベクトルは1つだけでなく複数のベクトルを用いることができます。
everything()
everything()
関数は全ての列を指定する関数です。列の取捨選択ではあまり活躍しませんが、列の並び替えなどをおこなう際には役立ちます。
今回は relig_income データを religion, Don't know/refused をデータの左側に並び替えたいと思います。
library(tidyverse) data = tidyr::relig_income select(data, religion, `Don't know/refused`, everything())
出力される結果の頭10行はこんな感じになります。(クリックで表示)
religion | Don't know/refused | <$10k | $10-20k | $20-30k | $30-40k | $40-50k | $50-75k | $75-100k | $100-150k | >150k |
---|---|---|---|---|---|---|---|---|---|---|
Agnostic | 96 | 27 | 34 | 60 | 81 | 76 | 137 | 122 | 109 | 84 |
Atheist | 76 | 12 | 27 | 37 | 52 | 35 | 70 | 73 | 59 | 74 |
Buddhist | 54 | 27 | 21 | 30 | 34 | 33 | 58 | 62 | 39 | 53 |
Catholic | 1489 | 418 | 617 | 732 | 670 | 638 | 1116 | 949 | 792 | 633 |
Don?ft know/refused | 116 | 15 | 14 | 15 | 11 | 10 | 35 | 21 | 17 | 18 |
Evangelical Prot | 1529 | 575 | 869 | 1064 | 982 | 881 | 1486 | 949 | 723 | 414 |
Hindu | 37 | 1 | 9 | 7 | 9 | 11 | 34 | 47 | 48 | 54 |
Historically Black Prot | 339 | 228 | 244 | 236 | 238 | 197 | 223 | 131 | 81 | 78 |
Jehovah's Witness | 37 | 20 | 27 | 24 | 24 | 21 | 30 | 15 | 11 | 6 |
Jewish | 162 | 19 | 19 | 25 | 25 | 30 | 95 | 69 | 87 | 151 |
matches()
matches()
関数は正規表現で取捨選択する列を指定することができます。普通にselect
関数を使うとデータフレームの列名と全く同じ列名でないと選択できませんが、この関数を使うことで列名を曖昧に指定することができます。またこの関数が今回紹介するヘルパー関数の中では最も柔軟に列を取捨選択できる関数だと思います。
今回は billboard データから列名が a, t, d で始まる列を選択したいと思います。
library(tidyverse) data = tidyr::billboard select(data, matches("^[atd]"))
出力される結果の頭10行はこんな感じになります。(クリックで表示)
artist | track | date.entered |
---|---|---|
2 Pac | Baby Don't Cry (Keep... | 2000/2/26 |
2Ge+her | The Hardest Part Of ... | 2000/9/2 |
3 Doors Down | Kryptonite | 2000/4/8 |
3 Doors Down | Loser | 2000/10/21 |
504 Boyz | Wobble Wobble | 2000/4/15 |
980 | Give Me Just One Nig... | 2000/8/19 |
A*Teens | Dancing Queen | 2000/7/8 |
Aaliyah | I Don't Wanna | 2000/1/29 |
Aaliyah | Try Again | 2000/3/18 |
Adams, Yolanda | Open My Heart | 2000/8/26 |
まとめ
今回はselect
関数のヘルパー関数を紹介しました。列の取捨選択をより便利にしてくれるこれらのヘルパー関数を駆使してデータ解析頑張りましょう!