こんにちは,shun(@datasciencemore)です!
今回はselectについて,説明していきますね.
selectは列を選択するための関数です.
さて,selectの復習をしてみましょう.
selectは,条件を指定してあげて,その条件で指定した列を抽出するときに使用します.
今回はirisを使用していきます.
1 2 |
# irisをtibbleにする. iris = iris %>% as_tibble() |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
> iris # A tibble: 150 x 5 Sepal.Length Sepal.Width Petal.Length Petal.Width Species <dbl> <dbl> <dbl> <dbl> <fct> 1 5.1 3.5 1.4 0.2 setosa 2 4.9 3 1.4 0.2 setosa 3 4.7 3.2 1.3 0.2 setosa 4 4.6 3.1 1.5 0.2 setosa 5 5 3.6 1.4 0.2 setosa 6 5.4 3.9 1.7 0.4 setosa 7 4.6 3.4 1.4 0.3 setosa 8 5 3.4 1.5 0.2 setosa 9 4.4 2.9 1.4 0.2 setosa 10 4.9 3.1 1.5 0.1 setosa # … with 140 more rows |
目次
0.selectの内部処理
selectは,内部で以下の処理をしています.
① 条件を判定し,列ごとに論理値ベクトル(TRUE,FALSE)を作成する.
② ①の論理値ベクトルからTRUEの列の列番号を取得する.
③ ②で取得した列番号の列を抽出する.
filterの時と同様,これも何言っているのかよくわからないですね笑
具体例を見ていきましょう.
irisのSepal.Length列とSpecies列を抽出したい場合を考えてみましょう.
1 2 3 |
# Sepal.Length列, Species列を抽出 iris %>% select(Sepal.Length, Species) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# A tibble: 150 x 2 Sepal.Length Species <dbl> <fct> 1 5.1 setosa 2 4.9 setosa 3 4.7 setosa 4 4.6 setosa 5 5 setosa 6 5.4 setosa 7 4.6 setosa 8 5 setosa 9 4.4 setosa 10 4.9 setosa # … with 140 more rows |
想定どおり,抽出できましたね.
これの内部処理のイメージ図を見てみましょう.
① 条件であるSepal.Length,Speciesを判定し,列ごとに論理値ベクトル(TRUE,FALSE)を作成する.
② ①の論理値ベクトルからTRUEの列の列番号(1,5)を取得する.
③ ②で取得した列番号(1,5)の列を抽出する.
filterと似ていますよね.
filterは行を抽出していたのに対し,selectは列を抽出しています.
1番気をつけるところは,filterは,論理値ベクトルが作成されていたのに対し,selectは列番号が作成されていることです!
この処理によって,selectの中身に与えてあげる条件として列番号を与えても全く同じ動作をします.
1 2 3 |
# Sepal.Length列, Species列を抽出(列番号で指定) iris %>% select(1, 5) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# A tibble: 150 x 2 Sepal.Length Species <dbl> <fct> 1 5.1 setosa 2 4.9 setosa 3 4.7 setosa 4 4.6 setosa 5 5 setosa 6 5.4 setosa 7 4.6 setosa 8 5 setosa 9 4.4 setosa 10 4.9 setosa # … with 140 more rows |
条件を列名で指定した時と全く同じデータフレームが抽出されることが確認できました.
このことは,filterの内部処理と比較すると,そこまで使用頻度は高くないです.
なので,無理して覚えなくてもいいかもです笑
ただ,忘れたころに時々,この考え方も必要となることがあるので,頭の片隅に入れていただけたらと思います.
さて,このことを踏まえて,次章からselectの具体的な使い方を学んでいきます.
selectには便利関数がたくさんあるので,それらについてまとめていきます.
ちなみに直接指定とか範囲指定とか日本語の説明は正式名称ではなくて僕の造語です.
日本語にしたほうがイメージがわきやすいかと思ったので,適当に日本語化しました.
1.直接指定
基本中の基本,列名を直接指定して列を抽出します.
1 2 3 |
# Sepal.Length列, Species列を抽出 iris %>% select(Sepal.Length, Species) |
出力は上と全く同じなので省略します.
2.範囲指定 :
列名と列名の間に:を入れることで,それらの間の列名すべてをとってくることができます.
1 2 3 |
# Sepal.Length列からPetal.Width列までを抽出 iris %>% select(Sepal.Length:Petal.Width) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# A tibble: 150 x 4 Sepal.Length Sepal.Width Petal.Length Petal.Width <dbl> <dbl> <dbl> <dbl> 1 5.1 3.5 1.4 0.2 2 4.9 3 1.4 0.2 3 4.7 3.2 1.3 0.2 4 4.6 3.1 1.5 0.2 5 5 3.6 1.4 0.2 6 5.4 3.9 1.7 0.4 7 4.6 3.4 1.4 0.3 8 5 3.4 1.5 0.2 9 4.4 2.9 1.4 0.2 10 4.9 3.1 1.5 0.1 # … with 140 more rows |
3.間接指定 -
列名の前に-をつけることで,その列名を抽出から除くことができます.
1 2 3 |
# Sepal.Length列とPetal.Width列を除いて抽出 iris %>% select(-Sepal.Length, -Petal.Width) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# A tibble: 150 x 3 Sepal.Width Petal.Length Species <dbl> <dbl> <fct> 1 3.5 1.4 setosa 2 3 1.4 setosa 3 3.2 1.3 setosa 4 3.1 1.5 setosa 5 3.6 1.4 setosa 6 3.9 1.7 setosa 7 3.4 1.4 setosa 8 3.4 1.5 setosa 9 2.9 1.4 setosa 10 3.1 1.5 setosa # … with 140 more rows |
4.前方一致 starts_with
列名の前方部分を指定して,一致する列を抽出します.
1 2 3 |
# 前方がSepalの列名を抽出 iris %>% select(starts_with("Sepal")) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# A tibble: 150 x 2 Sepal.Length Sepal.Width <dbl> <dbl> 1 5.1 3.5 2 4.9 3 3 4.7 3.2 4 4.6 3.1 5 5 3.6 6 5.4 3.9 7 4.6 3.4 8 5 3.4 9 4.4 2.9 10 4.9 3.1 # … with 140 more rows |
5.後方一致 ends_with
1 2 3 |
# 後方がWidthの列名を抽出 iris %>% select(ends_with("Width")) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# A tibble: 150 x 2 Sepal.Width Petal.Width <dbl> <dbl> 1 3.5 0.2 2 3 0.2 3 3.2 0.2 4 3.1 0.2 5 3.6 0.2 6 3.9 0.4 7 3.4 0.3 8 3.4 0.2 9 2.9 0.2 10 3.1 0.1 # … with 140 more rows |
6.部分一致 contains
列名に含まれる文字列を指定して,一致する列を抽出します.
1 2 3 |
# l.Lが含まれるの列名を抽出 iris %>% select(contains("l.L")) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# A tibble: 150 x 2 Sepal.Length Petal.Length <dbl> <dbl> 1 5.1 1.4 2 4.9 1.4 3 4.7 1.3 4 4.6 1.5 5 5 1.4 6 5.4 1.7 7 4.6 1.4 8 5 1.5 9 4.4 1.4 10 4.9 1.5 # … with 140 more rows |
7.正規表現一致 matches
正規表現で一致する列を抽出します.
正規表現については,今回は省略します.
1 2 3 |
# 前方がSeでenが含まれるの列名を抽出 iris %>% select(matches("^Se.*en.*")) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# A tibble: 150 x 1 Sepal.Length <dbl> 1 5.1 2 4.9 3 4.7 4 4.6 5 5 6 5.4 7 4.6 8 5 9 4.4 10 4.9 # … with 140 more rows |
8.文字列指定 all_of
列名を文字列で指定します.
これは,変数に文字列を格納した時に便利です.
1 2 3 4 |
# Sepal.Length,Petal.Lengthを文字列で指定 var = c("Sepal.Length", "Petal.Length") iris %>% select(all_of(var)) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# A tibble: 150 x 2 Sepal.Length Petal.Length <dbl> <dbl> 1 5.1 1.4 2 4.9 1.4 3 4.7 1.3 4 4.6 1.5 5 5 1.4 6 5.4 1.7 7 4.6 1.4 8 5 1.5 9 4.4 1.4 10 4.9 1.5 # … with 140 more rows |
現時点(2021年1月)では,all_of()を使用しないで直接文字列で指定しても抽出できます.
1 2 3 4 |
# Sepal.Length,Petal.Lengthを文字列で直接指定(all_ofを使用しない) var = c("Sepal.Length", "Petal.Length") iris %>% select(var) |
しかし,出力されるデータフレームに警告が出ています.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
Note: Using an external vector in selections is ambiguous. ℹ Use `all_of(var)` instead of `var` to silence this message. ℹ See <https://tidyselect.r-lib.org/reference/faq-external-vector.html>. This message is displayed once per session. # A tibble: 150 x 2 Sepal.Length Petal.Length <dbl> <dbl> 1 5.1 1.4 2 4.9 1.4 3 4.7 1.3 4 4.6 1.5 5 5 1.4 6 5.4 1.7 7 4.6 1.4 8 5 1.5 9 4.4 1.4 10 4.9 1.5 # … with 140 more rows |
要約すると別のデータフレームにvarという列名があると,varに格納した変数が使えなくなるからall_of()を使ってねってことです.
将来的に直接文字列で指定することはできなくなるっぽいので,素直にall_ofを使用しましょう!
9.全列指定 everything
全列を指定します.
1 2 3 |
# 全列指定 iris %>% select(everything()) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# A tibble: 150 x 5 Sepal.Length Sepal.Width Petal.Length Petal.Width Species <dbl> <dbl> <dbl> <dbl> <fct> 1 5.1 3.5 1.4 0.2 setosa 2 4.9 3 1.4 0.2 setosa 3 4.7 3.2 1.3 0.2 setosa 4 4.6 3.1 1.5 0.2 setosa 5 5 3.6 1.4 0.2 setosa 6 5.4 3.9 1.7 0.4 setosa 7 4.6 3.4 1.4 0.3 setosa 8 5 3.4 1.5 0.2 setosa 9 4.4 2.9 1.4 0.2 setosa 10 4.9 3.1 1.5 0.1 setosa # … with 140 more rows |
これは,上のように使うことはまずないですが列名の順番を変えるときに役立ちます.
1 2 3 |
# Speciesを一番左にして,それ以外の列も選択 iris %>% select(Species, everything()) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# A tibble: 150 x 5 Species Sepal.Length Sepal.Width Petal.Length Petal.Width <fct> <dbl> <dbl> <dbl> <dbl> 1 setosa 5.1 3.5 1.4 0.2 2 setosa 4.9 3 1.4 0.2 3 setosa 4.7 3.2 1.3 0.2 4 setosa 4.6 3.1 1.5 0.2 5 setosa 5 3.6 1.4 0.2 6 setosa 5.4 3.9 1.7 0.4 7 setosa 4.6 3.4 1.4 0.3 8 setosa 5 3.4 1.5 0.2 9 setosa 4.4 2.9 1.4 0.2 10 setosa 4.9 3.1 1.5 0.1 # … with 140 more rows |
10.データ型指定 where
指定したデータ型を抽出します.
1 2 3 |
# dbl型の列を抽出する iris %>% select(where(is.double)) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# A tibble: 150 x 4 Sepal.Length Sepal.Width Petal.Length Petal.Width <dbl> <dbl> <dbl> <dbl> 1 5.1 3.5 1.4 0.2 2 4.9 3 1.4 0.2 3 4.7 3.2 1.3 0.2 4 4.6 3.1 1.5 0.2 5 5 3.6 1.4 0.2 6 5.4 3.9 1.7 0.4 7 4.6 3.4 1.4 0.3 8 5 3.4 1.5 0.2 9 4.4 2.9 1.4 0.2 10 4.9 3.1 1.5 0.1 # … with 140 more rows |
まとめ
いやー,たくさんありましたね.
selectは内部的には条件を満たす列を数値で取得し,それをもとに列を選択しています.
また,selectの具体例についてまとめると,以下のようになります.
- 直接指定
- 範囲指定 :
- 間接指定 -
- 前方一致 starts_with()
- 後方一致 ends_with()
- 部分一致 contains()
- 正規表現一致 maches()
- 文字列指定 all_of()
- 全列指定 everything()
- データ型指定 where()
多いっすね笑
一度に全部覚える必要はまったくありません.
何回も使用していくうちに自然と覚えていくのであせらないで何回も繰り返していきましょう!
それじゃ,お疲れさまでした!!
参考
1.https://kazutan.github.io/kazutanR/hands_on_170730/select.html