##目的
Rのdplyrパッケージを使って感動している人はとても多いと思います。dplyrのfilter_関数が便利だと気づいたので紹介します。
dplyrって何?という方は、コチラなど参照サイトを一読して見て下さい。下記のようなことができます。
- selectで必要な列だけ抽出できる。
- filterで条件に合致したレコードを抽出できる。
- mutateは新しい列を追加し、ifelseオプションで条件によるリコードができる。
- いわゆるSQLの group byが使える。
##(1)filter関数-フィールド名指定による方法
filterを使って任意のカラムの条件を満たしたレコードを抽出する場合、こうなります。
df %>% dplyr::filter(fac_imp_PC==1) %>% head(3)
サンプルデータ
#サンプルデータdf
#データは全くのダミーです。
#fac_grp〜fac_imp_PC_SPは、0か1かの因子データです
> head(df)
PC_sales SP_sales fac_grp fac_imp_PC fac_imp_SP fac_imp_PC_SP
1 276290.03 15059.80 0 0 0 0
2 216598.62 21534.34 0 0 0 0
3 -96522.45 -32613.39 0 0 0 0
4 -308115.25 -61048.30 0 0 0 0
5 -357115.00 29930.80 0 0 0 0
6 36775.66 96377.52 0 0 0 0
「fac_imp_PC」==1のレコードが抽出されます↓
df %>% dplyr::filter(fac_imp_PC==1) %>% head(3)
PC_sales SP_sales fac_grp fac_imp_PC fac_imp_SP fac_imp_PC_SP
1 -59106.74 -39891.102 0 1 1 0
2 138817.89 -7932.581 0 1 1 0
3 -469832.00 -67553.340 0 1 1 0
この時に、filterで指定する列名を文字列でいちいち書かずに、列番号で指定できれば便利と思いましたが、やってみるとできませんでした。
#条件に使う変数の変数番号
i<-4
varname<-colnames(df)[i]
df %>% dplyr::filter(varname ==1)
結果↓
##(2)filter_関数を使い列番号で条件指定する方法
filterではなく、filter_を使うというやり方をstack overflawで見つけました。
filterとfilter_の違いについて調べた所、filter_のようにアンダーバーが付いた関数のことをSE(通常評価)といい、filterのようにアンダーバーが付いていない関数をNSE(Non-Standard Evaluation):非標準評価というようです。Rの data.table と data.frame を dplyr で区別なく扱うの最後の「まとめ」で
特に Standard Evaluation関数(アンダースコア付の関数)によって変数名を文字列として扱う
と2つの区別が紹介されています。
下はfilter_を使うやり方です。
#データフレームdfから i列目の変数==1のレコードを抽出し、j列目のみ抽出する
#下の例の場合、dfからfac_imp_PC==1のレコードを抽出する
i<-4 #条件抽出に使う列の列番号
#条件抽出する列名をvarnameとして取得
varname <-colnames(df)[i]
#filterではなくfilter_関数を使い、paste()で条件指定文字列を作って与える。
x<-df %>% dplyr::filter_(paste(varname,"==",1))
結果↓
> df %>% dplyr::filter_(paste(varname,"==",1)) %>% head(3)
imp_grp imp_PC imp_PC_SP imp_SP PC_sales SP_sales fac_imp_PC fac_imp_SP
1 0 1174525 0 1010756 -59106.74 -39891.102 1 1
2 0 1544899 0 1446243 138817.89 -7932.581 1 1
3 0 1849013 0 1546996 -469832.00 -67553.340 1 1
###補足
コメントを頂いたので、SEとNSEの違いついても深堀して調べました。
##参考にしたページ