dplyr::filter()で複数の条件をうまいこと指定したい

#はじめに
みなさん、**tidyverse使ってますか！？**
私はtidyverse信者なので、Rを起動したらまず`library(tidyverse)`を書いています。
今日は`tidyverse`内の`dplyr::filter()`に関する小ネタです。


#dplyr::filter()とは？
簡単に言うと、データフレーム内の条件に一致した行だけを抽出する関数です。
百聞は一見にしかずということで、例を挙げてみます。

```R
library(tidyverse)
data("iris")

#データの確認 ------------------------------------------------------------------
head(iris)
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          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.0         3.6          1.4         0.2  setosa
6          5.4         3.9          1.7         0.4  setosa

summary(iris$Species)
    setosa versicolor  virginica 
        50         50         50 


#dplyr::filter()を使って、Speciesがversicolorのものだけを抽出する。 ------------------------------------------------------------------
dat <- iris %>% 
  filter(Species == 'versicolor')


#抽出結果の確認
head(dat)
  Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
1          7.0         3.2          4.7         1.4 versicolor
2          6.4         3.2          4.5         1.5 versicolor
3          6.9         3.1          4.9         1.5 versicolor
4          5.5         2.3          4.0         1.3 versicolor
5          6.5         2.8          4.6         1.5 versicolor
6          5.7         2.8          4.5         1.3 versicolor

summary(dat$Species)
    setosa versicolor  virginica 
         0         50          0 
```

この様に、特定の列に対して、特定の値かどうか（又は、以上、以下など）を判定して抽出することが可能です。


#複数の条件を指定する
例えば、Speciesがversicolor、もしくはsetosaの行を抽出することも可能です。

```R
#Speciesがversicolor、もしくはsetosaの行を抽出する
dat <- iris %>% 
  filter(Species == 'versicolor' | Species == 'setosa')

#データの確認
head(dat)
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          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.0         3.6          1.4         0.2  setosa
6          5.4         3.9          1.7         0.4  setosa

summary(dat$Species)
    setosa versicolor  virginica 
        50         50          0 
```

複数の条件を指定したい場合は、`|`（or）を使ってあげることで実現できます。
irisのSpeciesは3つの値しかないのでこの書き方でも大きな問題ではないですが、値が複数存在する場合一個ずつ記述していくのは面倒ですし、変更時の手間が大きくなります。
なので、それらをオブジェクトに代入しておいて、指定ができたら便利です。

```R
#指定したい値をオブジェクトに代入
choice <- c('setosa', 'versicolor')

dat <- iris %>% 
  filter(Species == choice)

#データの確認
head(dat)
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.7         3.2          1.3         0.2  setosa
3          5.0         3.6          1.4         0.2  setosa
4          4.6         3.4          1.4         0.3  setosa
5          4.4         2.9          1.4         0.2  setosa
6          5.4         3.7          1.5         0.2  setosa
> 

summary(dat$Species)
    setosa versicolor  virginica 
        25         25          0  #うまくいっていない
```

上記の方法だともともと50行ずつあったデータが、半分の25個ずつになってしまっています。



#複数の条件をうまいこと指定したい
あるオブジェクト内のいずれかに一致する行のみを抽出する際は、`%in%`を使うと実現でき、かつ可読性が高くなります。

```R
#指定したい値をオブジェクトに代入
choice <- c('setosa', 'versicolor')

dat <- iris %>% 
  filter(Species %in% choice)


#データの確認
head(dat)
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          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.0         3.6          1.4         0.2  setosa
6          5.4         3.9          1.7         0.4  setosa

summary(dat$Species)
    setosa versicolor  virginica 
        50         50          0   #　うまくいった！
```

#%in%とは？
`base::match()`をより直感的に記述したもののようです。
`match`なので、例えば`'setosa' %in% choice`とすると、`TRUE`を返してくれます。


というわけで今日は以上でした。ばいばーい！