8
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

tidyverse tips

Last updated at Posted at 2020-03-12

よく使う&いつも忘れるtidyverseのイディオム集。

複数列を一挙に処理する

多変量データを扱う場合には、各変数をチマチマ処理していたのではらちがあかない(IS2010ベースライン特徴量は1592もある)。そこで _all とか _at の出番。

各列を標準化する

Sepal.Length列からPetal.Width列までをそれぞれ標準化(平均0,標準偏差1)する。mutate_atを使う。mutate_each は古いやり方。

library(tidyverse)
iris %>%
  mutate_at(vars(Sepal.Length:Petal.Width), scale)
    Sepal.Length Sepal.Width Petal.Length   Petal.Width    Species
1    -0.89767388  1.01560199  -1.33575163 -1.3110521482     setosa
2    -1.13920048 -0.13153881  -1.33575163 -1.3110521482     setosa
3    -1.38072709  0.32731751  -1.39239929 -1.3110521482     setosa
4    -1.50149039  0.09788935  -1.27910398 -1.3110521482     setosa
.
.
.

標準化でなく中心化(平均0)をしたい場合、x - mean(x) という関数を ~ で作ればよい。

iris %>%
  mutate_at(vars(Sepal.Length:Petal.Width), ~ (. - mean(.)))
    Sepal.Length Sepal.Width Petal.Length   Petal.Width    Species
1    -0.74333333  0.44266667       -2.358 -0.9993333333     setosa
2    -0.94333333 -0.05733333       -2.358 -0.9993333333     setosa
3    -1.14333333  0.14266667       -2.458 -0.9993333333     setosa
4    -1.24333333  0.04266667       -2.258 -0.9993333333     setosa

各列の平均と標準偏差を求める

Sepal.Length列からPetal.Width列までの平均を品種ごとに求める。

iris %>%
  group_by(Species) %>%
  summarise_at(vars(Sepal.Length:Petal.Width),mean)
  Species    Sepal.Length Sepal.Width Petal.Length Petal.Width
1 setosa             5.01        3.43         1.46       0.246
2 versicolor         5.94        2.77         4.26       1.33 
3 virginica          6.59        2.97         5.55       2.03 

品種ごとの平均を元のデータに新しい列として加えたい場合には summarise は使えない。1つの変数だけなら mutate で簡単だが、複数列に対して一挙に生成したい場合には、 mutate_at の関数リストを指定するところで、新しい列の名前に付ける接尾辞を指定する。下の例では、各列の品種ごとの平均値を表す列に _mu を付けるように指定している。

iris %>%
  group_by(Species) %>%
  mutate_at(vars(Sepal.Length:Petal.Width),funs(mu=mean))
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
3          4.7         3.2          1.3         0.2  setosa
4          4.6         3.1          1.5         0.2  setosa
.
.
.
  Sepal.Length_mu Sepal.Width_mu Petal.Length_mu Petal.Width_mu
1           5.006          3.428           1.462          0.246
2           5.006          3.428           1.462          0.246
3           5.006          3.428           1.462          0.246
4           5.006          3.428           1.462          0.246
.
.
.

複数の関数を適用してそれぞれ新しい列として加えたい場合には、関数リストに関数名を並べて書く。このときは、新しい列の名前に付ける接尾辞は省略してもよい(勝手に関数名と同じ接尾辞が付く)。

iris %>%
  group_by(Species) %>%
  mutate_at(vars(Sepal.Length:Petal.Width),funs(mean,sd))
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
3          4.7         3.2          1.3         0.2  setosa
4          4.6         3.1          1.5         0.2  setosa
.
.
.
  Sepal.Length_mean Sepal.Width_mean Petal.Length_mean
1             5.006            3.428             1.462
2             5.006            3.428             1.462
3             5.006            3.428             1.462
4             5.006            3.428             1.462
.
.
.
  Petal.Width_mean Sepal.Length_sd Sepal.Width_sd Petal.Length_sd
1            0.246       0.3524897      0.3790644        0.173664
2            0.246       0.3524897      0.3790644        0.173664
3            0.246       0.3524897      0.3790644        0.173664
4            0.246       0.3524897      0.3790644        0.173664
.
.
.
  Petal.Width_sd
1      0.1053856
2      0.1053856
3      0.1053856
4      0.1053856

最大値を取る列を見つける

anscombeデータセットを利用して適当に作ったデータで説明する。

anscombe %>%
  select(y1:y4) %>%
  mutate(id=rownames(.)) -> data
print(data)
      y1   y2    y3    y4 id
1   8.04 9.14  7.46  6.58  1
2   6.95 8.14  6.77  5.76  2
3   7.58 8.74 12.74  7.71  3
4   8.81 8.77  7.11  8.84  4
5   8.33 9.26  7.81  8.47  5
6   9.96 8.10  8.84  7.04  6
7   7.24 6.13  6.08  5.25  7
8   4.26 3.10  5.39 12.50  8
9  10.84 9.13  8.15  5.56  9
10  4.82 7.26  6.42  7.91 10
11  5.68 4.74  5.73  6.89 11

戦略は以下の通り。

  1. long形式にする前にidを振っておく。(各例に名前が付いたデータなら不要)
  2. pivot_longer でlong形式に変換する。以前ならgatherを使う場面。これで、各例ごとに1変数1行のデータになる。
  3. 各例ごとに which.maxで何行目が最大かを見つけ、slice でその行だけ取り出す。
  4. これを元のwide形式のデータに right_join で注入する。
data %>%
  mutate(id=rownames(.)) %>%
  group_by(id) %>%
  pivot_longer(y1:y4,names_to="variable",values_to="value") %>%
  mutate(variable=as_factor(variable)) %>%
  slice(which.max(value)) %>%
  rename(argmax=variable,max=value) %>%
  ungroup() %>%
  right_join(data,by="id") %>%
  select(-id)
   argmax   max    y1   y2    y3    y4
1      y2  9.14  8.04 9.14  7.46  6.58
2      y2  8.14  6.95 8.14  6.77  5.76
3      y3 12.74  7.58 8.74 12.74  7.71
4      y4  8.84  8.81 8.77  7.11  8.84
5      y2  9.26  8.33 9.26  7.81  8.47
6      y1  9.96  9.96 8.10  8.84  7.04
7      y1  7.24  7.24 6.13  6.08  5.25
8      y4 12.50  4.26 3.10  5.39 12.50
9      y1 10.84 10.84 9.13  8.15  5.56
10     y4  7.91  4.82 7.26  6.42  7.91
11     y4  6.89  5.68 4.74  5.73  6.89

(続く)

8
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?