はじめに
今回はパイプ表現(%>%
)の中で繰り返し処理を実行する時に便利な関数であるmap
関数の使い方を紹介します。tibble
やgroup_nest
と組み合わせて使うと柔軟にデータ処理できるためおすすめです。ぜひfor
文から卒業してmap
を使いこなせるようになってください。
map関数とは
map
関数は様々な型タイプのデータに対して繰り返し処理を実行できる関数です。purrr
パッケージに含まれている関数なのでこのパッケージをインストールして呼び出せば使えます。またこのパッケージ自体がtidyverse
シリーズに含まれているのでtidyverse
パッケージをインストールして呼び出しても使うことができます。基本的な使い方は以下の通りです。
library(purrr) map( 変数, 関数)
- 変数 : 繰り返し処理の中に入れる変数
- 関数: 繰り返し実施したい関数
具体例
ベクトルの中身に関して繰り返し処理する
まず1つ目の例はfor
文とほとんど同じ使い方となるベクトルの中身を繰り返す例です。今回は平均値を1から10まで移動させながら標準偏差1の正規分布からランダムに10個の値をとってくるという処理を実施します。
library(purrr) set.seed(1) map(1:10, rnorm, n = 10, sd = 1)
出力される結果はこんな感じになります。(クリックで表示)
[[1]] [1] 0.3735462 1.1836433 0.1643714 2.5952808 1.3295078 [6] 0.1795316 1.4874291 1.7383247 1.5757814 0.6946116 [[2]] [1] 3.5117812 2.3898432 1.3787594 -0.2146999 3.1249309 [6] 1.9550664 1.9838097 2.9438362 2.8212212 2.5939013 [[3]] [1] 3.918977 3.782136 3.074565 1.010648 3.619826 2.943871 [7] 2.844204 1.529248 2.521850 3.417942 [[4]] [1] 5.358680 3.897212 4.387672 3.946195 2.622940 3.585005 [7] 3.605710 3.940687 5.100025 4.763176 [[5]] [1] 4.835476 4.746638 5.696963 5.556663 4.311244 4.292505 [7] 5.364582 5.768533 4.887654 5.881108 [[6]] [1] 6.398106 5.387974 6.341120 4.870637 7.433024 7.980400 [7] 5.632779 4.955865 6.569720 5.864945 [[7]] [1] 9.401618 6.960760 7.689739 7.028002 6.256727 7.188792 [7] 5.195041 8.465555 7.153253 9.172612 [[8]] [1] 8.475510 7.290054 8.610726 7.065902 6.746367 8.291446 [7] 7.556708 8.001105 8.074341 7.410479 [[9]] [1] 8.431331 8.864821 10.178087 7.476433 9.593946 [6] 9.332950 10.063100 8.695816 9.370019 9.267099 [[10]] [1] 9.457480 11.207868 11.160403 10.700214 11.586833 [6] 10.558486 8.723408 9.426735 8.775387 9.526599
今回のコードにおける各引数の役割は以下の通りです。
- 1:10 : 変数(1から10までの数列)
- rnorm : 関数(正規分布から値を取り出す)
- n = 10, sd = 1:
rnorm
関数の引数(サンプル数10、標準誤差1)
ちなみにmap
で出力される結果はリスト形式になっています。ただ、map_df
でデータフレームとして出力させたり、map_dbl
で数字として出力させたりすることができます。
今回のコードの動作イメージは以下のようになります。
データフレームの特定の列に関して繰り返し処理する
2つ目の使い方はデータフレームの特定の列の中身を繰り返し処理する使い方です。この時、mutate
と一緒に使うことで繰り返し処理した結果を新しい列として追加することができます。今回は1から10までの数字を2倍にする処理をしてその結果を新しい列として追加するという処理をやってみます。今回はコードを簡潔に書くために自作関数を定義し、それを使います。
library(tidyverse) f = function(x){x*2} #値を2倍にする関数を定義する data.frame(number = 11:20) %>% # 11から20までの値をnumber列として持つデータフレームを作成 mutate(double= map(number, f)) # 作成したnumber列に対して定義したf関数を1つずつ繰り返し適応
出力される結果はこんな感じになります。(クリックで表示)
number | double | |
---|---|---|
1 | 11 | 22 |
2 | 12 | 24 |
3 | 13 | 26 |
4 | 14 | 28 |
5 | 15 | 30 |
6 | 16 | 32 |
7 | 17 | 34 |
8 | 18 | 36 |
9 | 19 | 38 |
10 | 20 | 40 |
今回のコードではまずfunction
関数を用いて、入力した値を2倍にして返す自作関数を定義しています。
ちなみに自作関数についてはこちらの記事を参考にしてみてください。
そして1から10までの値をnumber列として持つデータフレームを作成し、そこにmutate
関数でdouble列を追加しています。このdouble列の中身はmap
関数を適応して処理しており、処理内容はnumber列の中身をあらかじめ定義したf
という自作関数に代入して2倍にして返しています。
ちなみにデータフレームの作成から列の追加までの間はパイプ演算子を使って処理をそのまま繋げています。
この使い方のイメージは以下の通りです
map関数の動作イメージ
動作のイメージ概要を図にまとめると次の図のようになります。
まとめ
今回はRでの繰り返し処理に使える関数map
を紹介しました。
この関数はパイプ演算子との相性が良く、パイプ演算子で繋げて処理している最中にも繰り返し処理を実施できるため重宝します。データを整えながら最終的な統計解析などの処理までをパイプで繋げておこないたい場合はこれを使いましょう!