LoginSignup
19
18

More than 5 years have passed since last update.

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

Posted at

はじめに

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

dplyr::filter()とは?

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

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の行を抽出することも可能です。

#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つの値しかないのでこの書き方でも大きな問題ではないですが、値が複数存在する場合一個ずつ記述していくのは面倒ですし、変更時の手間が大きくなります。
なので、それらをオブジェクトに代入しておいて、指定ができたら便利です。

#指定したい値をオブジェクトに代入
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%を使うと実現でき、かつ可読性が高くなります。

#指定したい値をオブジェクトに代入
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を返してくれます。

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

19
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
18