概要
- 行の選択はdplyr::filter()関数
- filter_at()やfilter_if()で複数の列に一気にフィルターをかけることも可能
イメージ
今回紹介する行の選択は次の図のような操作です。行の選択をするので縦の長さが短くなります。
dplyr::filter()
最も使い勝手のよい行の選択方法はdplyrパッケージのfilter()関数です。
基本的な使い方は次の通りです。
library(dplyr) filter(データフレーム, フィルター条件)
filter関数で指定するのはデータフレームとフィルター条件の2つです。
第一引数にどのデータフレームをフィルターするのか指定して、第二引数にフィルターの条件を指定します。
具体例 | 基本編
基本的な使い方の具体例としてirisデータから Sepal.Length 列が 4.5 よりも小さい行だけを取得する操作を紹介します。
実行するコードとその出力結果は以下の通りです。
library(dplyr) filter(iris, Sepal.Length < 4.5) #> Sepal.Length Sepal.Width Petal.Length Petal.Width Species #> 1 4.4 2.9 1.4 0.2 setosa #> 2 4.3 3.0 1.1 0.1 setosa #> 3 4.4 3.0 1.3 0.2 setosa #> 4 4.4 3.2 1.3 0.2 setosa
実際に出力結果に表示されるデータは全てSepal.Length < 4.5 となっていることがわかります。
具体例 | 複数条件編
複数条件で指定する場合の具体例も紹介します。複数条件でフィルターするときは 「& (AND)」 や「| (OR)」で複数条件の組み合わせ方も指定する必要があります。
「&(AND)」と「|(OR)」のイメージは以下の図の通りです。
図は条件が2つの場合のイメージを紹介しましたが、3つ以上の条件でも同様に全ての条件を満たすものがANDで、どれかを満たすものがORとなります。
具体例として iris データから Sepal.Length < 5 かつ Petal.Length > 2 となるレコードを取り出す例を紹介します。
library(dplyr) filter(iris, Sepal.Length < 5 & Petal.Length > 2) # 2つの条件を満たすものなので & でつなぐ # Sepal.Length Sepal.Width Petal.Length Petal.Width Species #> 1 4.9 2.4 3.3 1.0 versicolor #> 2 4.9 2.5 4.5 1.7 virginica
2つの条件をどちらも満たすものを選択するので、2つの条件の間を「&」でつないでいます。結果は Sepal.Length < 5 かつ Petal.Length > 2 となるものだけ選ばれています。
複数列のフィルター
filter()関数には一気に複数の列を同じ条件でフィルターするための発展的な関数が用意されています。
列ごとに指定する条件が違う場合は1つずつ列とフィルター条件を指定していくしかありませんが、複数列に同じ条件のフィルターをかけるならここで紹介する関数群が便利です。
ここではその発展的な関数も紹介したいと思います。
フィルター条件の設定法
まず複数列に同じ条件のフィルターをかける時のフィルター条件の設定法を紹介します。
複数列を一気にフィルターする時は専用のフィルター条件の指定方法があります。
条件の指定方法は以下の2つです。
- any_vers():選択した複数列のいずれかで指定条件を満たすものを残す
- all_vars():選択した複数列の全てで条件を満たすものを残す
それぞれの条件指定法のイメージは以下の通りです。
列名で指定してフィルター
filter_at()関数は列名や列の位置などで複数列を指定してフィルターをかける関数です。
今回は 列名が Sepal で始まる全ての列の値が 3.5 より大きく 5 より小さい範囲に収まる行だけ選択する例を考えます。
library(dplyr) filter_at(iris, .vars = vars(starts_with("Sepal")), .vars_predicate = all_vars(. > 3.5 & . < 5)) #> Sepal.Length Sepal.Width Petal.Length Petal.Width Species #> 1 4.6 3.6 1.0 0.2 setosa #> 2 4.9 3.6 1.4 0.1 setosa
filter_at()の基本的な引数は次の通りです。
- .vars:フィルターを適応する列の選択
- .vars_predicate:フィルター条件の指定(any_varsなどを使う)
.vars = でどのように列を指定するかを指定し、.vars_predicate = でフィルター条件となる関数を指定します。
列の中身で指定してフィルター
filter_if()関数は列の内容で複数列を指定してフィルターをかける関数です。
ここではirisデータの数値型の列全てに対して、2より大きく6.5より小さいものだけ取ってくる例を紹介します。
library(dplyr) filter_if(iris, .predicate = is.numeric, .vars_predicate = all_vars(. > 2 & . < 6.5)) #> Sepal.Length Sepal.Width Petal.Length Petal.Width Species #>1 6.3 3.3 6.0 2.5 virginica #>2 5.8 2.8 5.1 2.4 virginica #>3 6.4 3.2 5.3 2.3 virginica #>4 6.4 2.8 5.6 2.1 virginica #>5 6.4 2.8 5.6 2.2 virginica #>6 6.3 3.4 5.6 2.4 virginica #>7 6.2 3.4 5.4 2.3 virginica
filter_if()の基本的な引数は以下の通りです。
- .predicate:フィルターを適応する列を指定する関数
- .vars_predicate:フィルター条件の指定
全ての列にフィルター
filter_all()関数は全ての列に対してフィルターをかける関数です。
ここではirisデータからspecies列をあらかじめ除き、残った全ての列の中からいずれかの列で6.5より大きな値を持つものだけを選択する例を紹介します。
library(dplyr) iris %>% select(-Species) %>% filter_all(any_vars(. > 6.5)) # Sepal.Length Sepal.Width Petal.Length Petal.Width #> 1 7.0 3.2 4.7 1.4 #> 2 6.9 3.1 4.9 1.5 #> 3 6.6 2.9 4.6 1.3 #> 4 6.7 3.1 4.4 1.4 #> 5 6.6 3.0 4.4 1.4 #> 6 6.8 2.8 4.8 1.4 #> 7 6.7 3.0 5.0 1.7 #> 8 6.7 3.1 4.7 1.5 #> 9 7.1 3.0 5.9 2.1 #> 10 7.6 3.0 6.6 2.1
filter_all()ではどの列にフィルターをかけるか指定する必要がないため、フィルターの条件だけ指定すれば大丈夫です。