dplyrパッケージにある関数で、data.frameの列をピックアップしていく関数。data.frameは列が基本となるため、データハンドリングの基本かつ必須関数

select関数とは

使い方

select(.data, ...)

引数

.data

対象とするデータセットを指定。

ピックアップする変数(列)を指定。指定方法にはいろいろな方法があります(後述)。

試しに、irisデータよりSepal.LengthSpeciesを取り出してみましょう:

library(dplyr)

select(.data = iris, Sepal.Length, Petal.Length, Species)

このように、引数の...にピックアップしたい引数を指定すると持ってきてくれます。

ちょっと込み入った話

select関数で一番のポイントは、いかにして効率よくselect関数に変数を引き渡すかです。ちなみにこのselect関数は...で受け取った内容を列番号へと変えて、それを使って列選択しています。よって、列番号をそのまま与えても反応します:

select(iris, 1, 3, 5)

また、基本的にはbase::subset()で用いるような変数指定も可能です。よく使うのが-を使った方法で、もちろん利用可能です:

select(iris, -Species)
select(iris, -c(Sepal.Length, Petal.Length))

エクササイズ1

irisデータセットには、以下の変数が含まれています:

names(iris)
## [1] "Sepal.Length" "Sepal.Width"  "Petal.Length" "Petal.Width" 
## [5] "Species"

では、Petal.Widthだけ取り除いてみてください。

これでOKです:

select(iris, -Petal.Width)

列選択のための便利関数

dplyrには、この列選択のための便利関数がいくつも準備されています:

  • starts_with()
  • ends_with()
  • contains()
  • matches()
  • num_range()
  • one_of()
  • everything()

これらを使えば、かなり思うように列を選択できるようになります。

列名の前方一致 starts_with()

列名を前方一致で持ってきます:

select(iris, starts_with("petal"))

なお、上記の通りデフォルトでは大文字小文字の区別はしません。区別させたければ、引数としてignore.case = FALSEを指定してください:

select(iris, starts_with("petal", ignore.case = FALSE))
select(iris, starts_with("Petal", ignore.case = FALSE))

列名の後方一致 ends_with()

列名を後方一致で持ってきます:

select(iris, ends_with("Width"))

上述のstarts_with()の後方一致版ですので、大文字小文字の扱いも含め同一です。

列名の部分一致 contains()

列名を部分一致で持ってきます:

select(iris, contains("etal"))

指定した文字列を含む列をすべて選択します。大文字小文字の扱いは上記と同一です。

列名の正規表現による一致 matches()

正規表現を用いてmatchした列名を全て持ってきます:

select(iris, matches(".t."))

正規表現については省略しますが、少しでも使えるようになると文字列操作が格段に楽になりますのでぜひ機会を見つけて練習してみてください。

列名の通し番号を利用した選択 num_renge()

よく列名にx1, x2, x3, ...というのがあると思います。これを簡単に選択するためのものです。これはirisデータセットではできないのでサンプルデータを準備します:

df <- as.data.frame(matrix(1:30, nrow = 3, ncol = 10))
colnames(df) <- c(paste0("beer", 1:5), paste0("sake0", 1:5))
ls(df)
##  [1] "beer1"  "beer2"  "beer3"  "beer4"  "beer5"  "sake01" "sake02"
##  [8] "sake03" "sake04" "sake05"

たとえば、ここで「beer1からbeer3までを選択したい」と思ったとします。このような場合には以下のようにします:

select(df, num_range(prefix = "beer", range = 1:3, width = 1))

引数の意味は以下のとおりです;

prefix

連番変数の根っこ部分。文字列で指定。

range

連番の範囲。数値ベクトルで指定。

width

連番の桁数を指定

ポイントは引数widthです。これがあるおかげで、以下のようなことが可能です:

select(df, num_range("sake", 2:4, 2))

このように、かなり面倒な「01, 02, 03…」といった連番でも指定することが可能です。これらをbase関数群で実現しようとするとかなり苦労しますがこれなら一発です。

列名を文字列ベクトルで指定 one_of()

変数を文字列ベクトルで引き渡すのに用います:

var_list <- c("Sepal.Length", "Petal.Width")
select(iris, one_of(var_list))

なんとなく「別にこの関数を使わなくてもいけるんじゃね?」と思いそうですが、dplyrはこれを受け付けません。これは理由があるのですが省略します。気になる方はdplyr::current_varsdplyr::selectから、気づいたら「tidyevalって…rlangって…」って言いたくなるような奥深くに進んでみてください。

全ての列を選択 everything()

すべての列を持ってきます:

select(iris, everything())

これを単独で使うことはまずありません(そのまま持ってくることになるため)。よくあるのが順番を入れ替える時です:

select(iris, Species, everything())

他にもあるのですが、応用編に回します。

エクササイズ2

先ほど説明した便利関数を使ってみましょう。

  1. irisデータセットから“S”で始まる変数だけを取り出してみましょう
  2. irisデータセットから“th”で終わる変数だけを取り出してみましょう
  3. irisデータセットから“ep”を含む変数だけを取り出してみましょう
  4. dfデータセットから“beer3-beer5”と“sake01-sake03”を取り出してみましょう

実行例

こんな感じです:

# 1の実行例
select(iris, starts_with("S"))
# 2の実行例
select(iris, ends_with("th"))
# 3の実行例
select(iris, contains("ep"))
# 4の実行例
select(df, num_range("beer", 3:5, 1), num_range("sake", 1:3, 2))

応用編

select関数には、変数を指定する際に名前をつけることでまた違った動きをするようになります:

select(iris, Sepal.Length, kosaki = Species)

さらにこれの展開として、以下のようなことができます:

select(iris, kosaki = starts_with("Petal"), everything())

つまり、(付けたい名前) = (ターゲットの列名)ということが可能で、しかもそのターゲットが複数ある場合には自動的に連番を振ってくれるというのがあります。

これは実に汚いデータセットの前処理をする際に抜群の効果を発揮します。このあたりまで来ると、もうdplyrなしで作業できなくなるでしょう。

Copyright © 2017 Kazutan.R.