自在に操る

データの選択 | 行の選択

2021年6月6日

概要

  • 行の選択は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()ではどの列にフィルターをかけるか指定する必要がないため、フィルターの条件だけ指定すれば大丈夫です。

-自在に操る