R の filter 関数:
データフレームの行を選択する
UBC/informatics/r/filter
このページの最終更新日: 2024/09/30広告
概要: filter() 関数とは
filter 関数は、データフレームから行を抽出する R の関数である。dplyr という パッケージ に含まれており、R のデフォルト関数ではないので、インストールされていないならまず install.packages("dplyr") でインストールし、library(dplyr) で読み込んでから使う。
以下のようなページと関連が深い。
- データフレームからの抽出
- select 関数: 列の選択
tidyverse を読み込むと dplyr::filter() masks stats::filter() という表示が出る。これは、stat というパッケージにも filter という関数があること、tidyverse がそれを立ち上げないように mask していることを意味している。
したがって、単に filter で十分であるが、dplyr::filter という書き方の方がさらに安心である (参考)。このサイトでは、省略している部分もあるが、なるべく dplyr::filter という表記で統一する。
基本的な使い方
文字列の一致
組み込みデータセット chickwts を使って試してみる。これは horsebeanm, linseed などの餌を与えられて育ったニワトリの体重データである。
ここから feed が horsebean の行のみを取り出すには、
とする。まず .data でデータセットを指定する。その次には論理式がくる。A %in% B は R baseにある演算子で、「B の要素のどれか 1 つにマッチしたら TRUE、どれにもマッチしなければ FALSE」を返す (1)。filter 関数と共によく使われる。feed %in% c("horsebean") で、feed が horsebean である行のみを取り出せることになる。
これはもっと単純に、
でも同じ結果になるが、次の例を考えると、%in% の方が応用の範囲が広く、こちらで覚えておくべきだろう。
文字列の部分一致
いくつか方法はあるが、stringr パッケージの str_detect 関数を使う方法が便利である。feed から l を含む行のみを抽出する例を示す。
str_detect で、ベクターを使いたい場合は、paste() または paste0() を使う。collapse = "|" は「または」、つまり horse か lin のいずれかの文字列が feed に含まれる行が選択される。
dplyr::filter(.data = chickwts, str_detect(feed, paste0(vector, collapse = "|")))
ベクターのいずれかと一致
文字列が複数あるときは、ページ下の 複数の条件を指定する のように書いても良いが、%in% をベクターにすれば「ベクターのいずれかと一致」する行を抽出できる。
数値の大小など
数値の大小で指定することもできる。
複数の条件を指定する
複数の条件をカンマ , で繋ぐと and 指定 (条件 A かつ 条件 B)、| で繋ぐと or 指定 (条件 A または 条件 B) になる。
filter 関数に変数を含める
行名をベクターで指定する
まず、上の例で feed をベクターにすると、該当する行が見つからない。つまり、feed の部分にはベクターを入れることはできない。
同様に、c("feed") をオブジェクトとして保存し、これを filter 関数に含めてもダメ。
c("feed") をオブジェクトとして保存し、paste 関数、paste0 関数を使ってもダメだった。
正しくは、このように
chickwts[["A"]] だと、A の変数を読み込まずに A という行を探すのだろう。これはエラーになる。
この推察が正しいことを裏付けるように、chickwts[[feed]] はエラーになり、chickwts[["feed"]] は chickwts[[A]] と同じ結果になる。
for loop 内で filter() 関数を使う
for loop に filter 関数を組み込みたい場合など。
これを for loop に組み込んでみる。
パターン 1 では、for loop は回るものの、なぜか何も出力されない。
パターン 2 のように、一度 filter の結果をオブジェクトに格納し、それを print すると、予想通りの結果になる。print のかわりに解析を追加すれば、for loop の中に filter を組み込めることになる。
これは、paste0 関数を入れても大丈夫。これを利用すると、たとえば feed1, feed2... という列がある場合に、入れ子の for loop にすることも可能になる。
その他メモ
library dplyr を読み込んでいないと、なぜか filter 関数が見つからないというエラーではなく、オブジェクトが見つからないというエラーが出る。以下のような感じ。
Error in Blood_type %in% c("A")) : object 'Blood_type' not found
広告
References
- 行の選択 - filter関数. Link: Last access 2022/05/24.
- dplyrで変数を使いfor文で繰返し処理を行う方法. Link: Last access 2022/10/18.
- 【R】データフレームをフィルタリングする方法|filter関数. Link: Last access 2022/10/18.
コメント欄
サーバー移転のため、コメント欄は一時閉鎖中です。サイドバーから「管理人への質問」へどうぞ。