こんにちは,shun(@datasciencemore)です!
今回は,前回予告したとおり,rowwiseの応用編です.
実にさまざまな処理が書けるので必見の記事となっておりますので,お楽しみに!
それでは,さっそくいろいろな応用を見ていきましょう.
今回も前回に引き続き,diamondsを使用していきます.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
> diamonds # A tibble: 53,940 x 10 carat cut color clarity depth table price x y z <dbl> <ord> <ord> <ord> <dbl> <dbl> <int> <dbl> <dbl> <dbl> 1 0.23 Ideal E SI2 61.5 55 326 3.95 3.98 2.43 2 0.21 Premium E SI1 59.8 61 326 3.89 3.84 2.31 3 0.23 Good E VS1 56.9 65 327 4.05 4.07 2.31 4 0.290 Premium I VS2 62.4 58 334 4.2 4.23 2.63 5 0.31 Good J SI2 63.3 58 335 4.34 4.35 2.75 6 0.24 Very Good J VVS2 62.8 57 336 3.94 3.96 2.48 7 0.24 Very Good I VVS1 62.3 57 336 3.95 3.98 2.47 8 0.26 Very Good H SI1 61.9 55 337 4.07 4.11 2.53 9 0.22 Fair E VS2 65.1 61 337 3.87 3.78 2.49 10 0.23 Very Good H VS1 59.4 61 338 4 4.05 2.39 # … with 53,930 more rows |
1.系列ごとに自作の関数を適用する.
まずは自分で作成した関数を格納して,系列ごとに適用してみましょう.
自作する関数は,データフレームを引数として,priceが5000以上の行を抽出する処理としましょう.
こんな感じで書けますね.
1 2 3 4 5 6 7 8 |
# 自作関数作成 get_df_highprice = function(df){ df_highprice = df %>% filter(price >= 5000) return(df_highprice) } |
関数の引数にデータフレームをとれるんですか??
うん,取れるよ!
オブジェクトになるものならほぼなんでも取れるよ.
例えば,データフレーム,関数,モデルなどなど.
この柔軟さがRのメリットなんだ.
慣れないと気持ち悪いかもだけど,すぐに慣れるよ~
それでは,この関数をcutでネストしたdiamondsに格納してみましょう.
ちなみに普通のオブジェクト(数値,文字列など)以外を格納するときは,listにして入れてあげてくださいね.
これ,ぼくもよく忘れちゃいます笑
忘れるとエラーが出るので,すぐに修正できますが笑
1 2 3 4 5 6 7 8 9 10 |
# 自作関数追加 diamonds_with_func = diamonds %>% nest_by(cut) %>% mutate( func = list( get_df_highprice ) ) |
1 2 3 4 5 6 7 8 9 10 |
> diamonds_with_func # A tibble: 5 x 3 # Rowwise: cut cut data func <ord> <list<tbl_df[,9]>> <list> 1 Fair [1,610 × 9] <fn> 2 Good [4,906 × 9] <fn> 3 Very Good [12,082 × 9] <fn> 4 Premium [13,791 × 9] <fn> 5 Ideal [21,551 × 9] <fn> |
右側にfuncが追加されましたね!
この列の一つ一つに先ほど作成した「get_df_highprice」という関数が格納されています.
それでは,このfuncの関数にdataのデータフレームを引数にして適用してみましょう.
1 2 3 4 5 6 7 8 9 |
# 自作関数適用 diamonds_with_highprice = diamonds_with_func %>% mutate( df_highprice = list( func(data) ) ) |
1 2 3 4 5 6 7 8 9 10 |
> diamonds_with_highprice # A tibble: 5 x 4 # Rowwise: cut cut data func df_highprice <ord> <list<tbl_df[,9]>> <list> <list> 1 Fair [1,610 × 9] <fn> <tibble [429 × 9]> 2 Good [4,906 × 9] <fn> <tibble [1,241 × 9]> 3 Very Good [12,082 × 9] <fn> <tibble [3,347 × 9]> 4 Premium [13,791 × 9] <fn> <tibble [4,721 × 9]> 5 Ideal [21,551 × 9] <fn> <tibble [4,989 × 9]> |
右側にdf_highpriceが追加されていますね.
これで,df_highpriceに格納されているデータフレームはpriceが5000以上になっています.
ほんとかよ?って気になる方はpluckを使用して,確かめてみてください.
今回の例では一つ一つの処理を見るために処理ごとに分割して書きましたが,まとめて書くこともできますよ.
というかこっちのほうが普通ですね笑
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# 処理をまとめて記述 diamonds %>% nest_by(cut) %>% mutate( func = list( get_df_highprice ), df_highprice = list( func(data) ) ) |
合わせて確認してくださいね.
2.系列ごとに画像を作成する.
次は,系列ごとに画像を作成しましょう.
今回もcutでネストして,それぞれのデータフレームに対して,x軸:carat,y軸:priceの散布図を作成してみましょう.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# 散布図作成 x:carat y:price diamonds_with_fig = diamonds %>% nest_by(cut) %>% mutate( fig = list( data %>% ggplot(aes(x = carat, y = price)) + geom_point(color = "orange") + labs(title = cut) + theme( axis.text = element_text(size = 15), axis.title = element_text(size = 15), plot.title = element_text(hjust = 0.5) ) ) ) |
1 2 3 4 5 6 7 8 9 10 |
> diamonds_with_fig # A tibble: 5 x 3 # Rowwise: cut cut data fig <ord> <list<tbl_df[,9]>> <list> 1 Fair [1,610 × 9] <gg> 2 Good [4,906 × 9] <gg> 3 Very Good [12,082 × 9] <gg> 4 Premium [13,791 × 9] <gg> 5 Ideal [21,551 × 9] <gg> |
右側にfigができていますね.
この中の1つ1つにdata列に入っているデータフレームを可視化したグラフが入っているのです.
実はこれ,{patchwork}パッケージのwrap_plots関数を使うと,それぞれのグラフを並べることができますよ.
めっちゃ便利ので,覚えておいてください!
1 2 3 4 |
# {patchework}パッケージのwrap_plots関数で複数のグラフを並べる diamonds_with_fig %>% pull(fig) %>% patchwork::wrap_plots() |
3.系列ごとにモデルを作成し,学習データを適用する.
最後に単回帰モデルの作成もやってみましょう.
今回もcutでネストして,それぞれのデータフレームに対して,説明変数:carat,目的変数:priceのモデルを作成します.
そして,作成したモデルに学習データを適用してみましょう.
モデルって何??って方はこの章を飛ばして大丈夫です.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# 単回帰モデル作成(説明変数:carat,目的変数:price)と学習データへの適用 diamonds %>% nest_by(cut) %>% mutate( model = list( lm( formula = price ~ carat, data = data ) ), pred_train = list( predict(model, data) ) ) |
1 2 3 4 5 6 7 8 9 |
# A tibble: 5 x 4 # Rowwise: cut cut data model pred_train <ord> <list<tbl_df[,9]>> <list> <list> 1 Fair [1,610 × 9] <lm> <dbl [1,610]> 2 Good [4,906 × 9] <lm> <dbl [4,906]> 3 Very Good [12,082 × 9] <lm> <dbl [12,082]> 4 Premium [13,791 × 9] <lm> <dbl [13,791]> 5 Ideal [21,551 × 9] <lm> <dbl [21,551]> |
modelとpred_trainができました.
このモデルをデータフレームに入れられることは,めっちゃ便利でその便利さは文章では表せません笑
ぼくが知っている限りPythonだとできなかったと思います.
皆さまもぜひぜひ体験して素晴らしさを味わってみてください!
まとめ
今回は,rowwiseの応用ということで以下の3点を紹介しました.
- 系列ごとに自作関数を適用する.
- 系列ごとにグラフを作成する.
- 系列ごとにモデルを作成し,学習データを適用する.
どれも頻出なので,ぜひマスターしてください.
rowwiseを使いこなせるようになると前処理が非常に楽になりますよ♪
それじゃ,お疲れさまでした!!