行方向に計算する
Text Update: 12/05, 2018 (JST)

dplyrパッケージはデータフレーム内の変数に対するベクトル演算(列方向)を行う場合には非常に有用なパッケージですが、行方向(列間)の演算を行うには少々不得手なところがあります。

Packages and Datasets

本ページではR version 3.4.4 (2018-03-15)の標準パッケージ以外に以下の追加パッケージを用いています。
 

Package Version Description
dplyr 0.7.8 A Grammar of Data Manipulation
purrr 0.2.5 Functional Programming Tools
purrrlyr 0.0.3 Tools at the Intersection of ‘purrr’ and ‘dplyr’
tibble 1.4.2 Simple Data Frames
tidyr 0.8.2 Easily Tidy Data with ‘spread()’ and ‘gather()’ Functions
tidyverse 1.2.1 Easily Install and Load the ‘Tidyverse’

 
また、本ページでは以下のデータセットを用いています。
 

Dataset Package Version Description
iris datasets 3.4.4 Edgar Anderson’s Iris Data

 

行方向に計算する

例えば、irisデータセットの個体(行)ごとのSepal(萼片)の合計値と平均値を求めたい場合、dplyr::mutate関数を用いる場合、行ごとに処理するためにdplyr::rowwise関数を併用して以下のように記述します。
 

iris %>% 
  dplyr::select(dplyr::starts_with("Sepal")) %>% 
  dplyr::rowwise() %>%
  dplyr::mutate(sum = sum(Sepal.Length, Sepal.Width, na.rm = TRUE),
                mean = mean(c(Sepal.Length, Sepal.Width), na.rm = TRUE)) %>% 
  head_tail()
Sepal.Length Sepal.Width sum mean
5.1 3.5 8.6 4.3
4.9 3 7.9 3.95
4.7 3.2 7.9 3.95
6.5 3 9.5 4.75
6.2 3.4 9.6 4.8
5.9 3 8.9 4.45

 
この場合は変数(列)が少ないのでコーディングは、さほど苦になりませんし処理的にも相応の速度なのですが、対象となる変数(列)が増えるとあまり効率的なコードとは言えなくなります。また、dplyr::rowwise関数は将来的にディスコンになる可能性が高いので、今から覚える必然性もあまりなく、コードの保守性を考えても代替手段を利用すべきだと考えます。
 

purrr::mapを用いた計算方法

代替手段としては、本blogでも何度か登場しているpurrrパッケージとtidyrパッケージを利用します。tidyr::nest関数で対象となる変数をリスト型にネストしてからpurrr::map関数で処理します。これにより変数の数が増えても計算の方のコードを変更しなくても済みます。
 

iris %>% 
  dplyr::select(dplyr::starts_with("Sepal")) %>% 
  tibble::rowid_to_column("id") %>%               # 行ごとに識別できるようにする
  tidyr::nest(-id, .key = "data") %>%             # 計算対象となる変数をネストする
  dplyr::mutate(sum = purrr::map_dbl(data, ~ sum(unlist(.x), na.rm = TRUE)),
                mean = purrr::map_dbl(data, ~ mean(unlist(.x), na.rm = TRUE))) %>% 
  tidyr::unnest() %>% 
  head_tail()
id sum mean Sepal.Length Sepal.Width
1 1 8.6 4.3 5.1 3.5
2 2 7.9 3.95 4.9 3
3 3 7.9 3.95 4.7 3.2
148 148 9.5 4.75 6.5 3
149 149 9.6 4.8 6.2 3.4
150 150 8.9 4.45 5.9 3

 

purrrlyrパッケージ

purrrlyrパッケージはデータフレーム版purrrと言えるパッケージで、行ごとに処理を適用する関数を持っています。purrrパッケージを用いるよりコード的には分かりやすいとは思いますが、引数を指定する手間はdplyr::rowwaise関数を用いる時と変わりません。また、purrrlyrパッケージは開発が始まったばかりなので、今後、どのようになっていくか不透明なところがあります。
 

iris %>% 
  dplyr::select(dplyr::starts_with("Sepal")) %>% 
  purrrlyr::by_row(~ sum(.$Sepal.Length, .$Sepal.Width, na.rm = TRUE), .to ="sum") %>%
  purrrlyr::by_row(~ mean(c(.$Sepal.Length, .$Sepal.Width), na.rm = TRUE), .to = "mean") %>% 
  tidyr::unnest() %>% 
  head_tail()
Sepal.Length Sepal.Width sum mean
5.1 3.5 8.6 4.3
4.9 3 7.9 3.95
4.7 3.2 7.9 3.95
6.5 3 9.5 4.75
6.2 3.4 9.6 4.8
5.9 3 8.9 4.45

 
Enjoy!  

本blogに対するアドバイス、ご指摘等は データ分析勉強会 または GitHub まで。

CC BY-NC-SA 4.0 , Sampo Suzuki