略称はr4dsらしい。tidyverseの作者自ら書いたデータ分析の入門書。
tidyverseを使ってデータ分析をしよう、という本。tidyverseはggplot2とかdplyrとかをすべて含めたもの。
web上で公開されているのが十分BOOXで読みやすかったので、webを読む。コードをCopyボタンでコピーしてR Studioで試す事が出来るので、便利で良いね、web版。
ちょっと3章のbar chartのidentityの説明で、挙動が想像と違ったので、実際のデータで試したくなる。 R Studioをインストールするか。 brewとかも探せばありそうだが、この本のintroductionのやり方に従ってインストールする事にする。
手元のMacは12.0.1なのであまり記述がないけれど、指示通りにやってみよう。
Rに4系列というのが出来ているな。RStudioは対応しているんだろうか?R Studioは3.0以上と書いてあるが…
まぁいいか、最新のを入れてみよう。 という事でR-4.1.2.pkgをインストールする。
そのあとRStudioをインストールしたが普通に動いた。4系列で問題無さそうね。よしよし。
3章はggplot2の入門。この辺はもう十分詳しいのでサラサラ読む。
3章のbar chardのidentityの説明が、色が変わっているだけに見えて、おや?と思ってR Studioをインストールして試してみる。 良く見ると左のカウントが変わっていて、高さの比が同じに見えるのは単なる偶然っぽい。 これはややこしいな。
やはりidentityは原点からすべて重なってプロットしているようだ。
4章はRの入門。さすがに分からない事はほとんど無いが、R Studioに関わる事は知らないものもあるので軽く眺めてはおく。
dplyrの入門。 ggplot2本で少し見た事があるが、実際に触ってみるのは今回が初。
なかなか素晴らしいね、dplyr。分かりやすいし強力だし。データ整形をこう解決出来る、と気づいたのは凄いよなぁ。
filterやmutateで順番を変えないように統一する所が発明だよな。 普通に実装すればfilterする時にarrangeもされてしまう訳だが、それをしないように実装する事で、これらを組み合わせる事が出来るようになる。
自分の普段のプログラムにもきっとこういう要素はあるのだろうな。 個々の要素をちょっと面倒にする事で全体がすごく簡単になる、という。
5.7を見ていたら、こんな感じの例があった(実際はちょっと違うが論点を明確にする為に変更している、元の記事を見たい人はこちら 5 Data transformation - R for Data Science)
> flights %>%
+ select(year, month, day, arr_delay, dep_time) %>%
+ filter(rank(desc(arr_delay)) < 10)
# A tibble: 9 × 5
year month day arr_delay dep_time
<int> <int> <int> <dbl> <int>
1 2013 1 9 1272 641
2 2013 1 10 1109 1121
3 2013 12 5 878 756
4 2013 3 17 915 2321
5 2013 4 10 931 1100
6 2013 6 15 1127 1432
7 2013 7 22 989 845
8 2013 7 22 895 2257
9 2013 9 20 1007 1139
filterの中にdescがある。これはarr_delayのトップ10を表示している事は分かる。 だが、結果はarr_delayでソートされていない。
arrangeじゃないから当然ではある。
> flights %>%
+ select(year, month, day, arr_delay, dep_time) %>%
+ arrange(desc(arr_delay))
# A tibble: 336,776 × 5
year month day arr_delay dep_time
<int> <int> <int> <dbl> <int>
1 2013 1 9 1272 641
2 2013 6 15 1127 1432
3 2013 1 10 1109 1121
4 2013 9 20 1007 1139
5 2013 7 22 989 845
6 2013 4 10 931 1100
7 2013 3 17 915 2321
8 2013 7 22 895 2257
9 2013 12 5 878 756
10 2013 5 3 875 1133
# … with 336,766 more rows
確かにトップ10にはなってそう。filterはどう動いているのだろうか?
rankを求めるにはdescにソートする必要はあるだろう。 一番ナイーブに考えれば、元の並び順を覚えておきつつsortして、rankのカラムを追加し、それを元の並び順に戻せば、あとは普通の条件式になる。
でもどうしてこの場合にそう振る舞うのかがいまいち納得いかないな。もうちょっとfilter全般の挙動を理解出来るような考え方がありそうなものだが。
ようするにfilterが各rowを見ていく時にTRUEかFALSEがわかればいいんだよな。 つまり、descはその値とrowindexのペアをソートして、そのrowindexを添え字とした配列で、条件式のTRUE、FLASEを格納すればいいのか。 実際にそういう実装になっているかは置いといてこんな感じに解釈すれば一般的に考えられる気がするな。
つまりfilterの中の条件はrowindexのTRUE, FALSEの配列を作るようなものになっている。
その少しあとでこんな例がある。
popular_dests <- flights %>%
group_by(dest) %>%
filter( n() > 365)
これは各グループのサイズが365以上のグループだけ残す訳だが、summariseはされてないのでグループに属する各行が残る。 これをどう考えるべきだろうか?
group_byはヘルプを見るとgrouped_dfというのを返すとなっている。
group_by(year, month, day)とすると365とインデックスの数が出ていて、yearはどうもこのデータでは2013年のしか無さそうなので、 monthとdayのタプルのユニークなペアの数になっているな。
つまり、year, month, dayとあったら、(year, month, day)のタプルをsortしてrankしたものをidとするようなカラムを追加すると思えば良いのだろう。
で、nはこの各グループidごとにカウントしたものとなるが、filter出来る為にはグループごとに潰す前のrowindexからこの値を見る事が出来るべきだよなぁ。
一番単純に考えれば、n()
はグループごとに個数を計算したあとに、元のgrouped_dfの各rowindexに対してグループidを引いてその値を新しいカラムに追加していく、と考えればいいんだろうか。
グループのidは配列の添字として使えるのでそんなに遅くも無いか。
なんか無駄は多い気もするが、そこから先は最適化の範疇だろう。
追記:5.7の最後にgrouped filterはgrouped mutateのあとにungrouped filterが続くような挙動だ、と書いてあった。自分の理解は割と正しそうだな。vignette("window-functions")
を読めと書いてあったので読んでみたが大半は本書と同じ内容だった。
6章はRStudioの使い方なのでサラッと読む。
7章は実際に仮説を立ててvisualizeしてさらに新しい仮説を立てて〜というのを実際にやってみるという章。 気になったものは写経してみて少しいじったりするが、 この話はggplot2本ですでにやっているので適当に読み飛ばす。
今回初めてRStudioと ggplot2+dplyrを使ってみたが、なかなかいいね。 昔Rを触って感じたRの良さが増幅されている。この辺を作ってる人たちは良く分かっているよな。 小規模データを快適にいじれる大切さ、みたいなの。
tibbleは初めて学ぶのでちゃんと読む。Rのdata.frameの癖のある所を現代風に直したものだな。
11章のimportはそんな難しい事も無いのでさっと読む。
tidy dataの論文はhttpsじゃない所に置いてある。http://www.jstatsoft.org/v59/i10/paper。 そのうち読みたい。
影響されて、ファイル操作の文法というのを考えてみる。GoFO
pivot_longer, pivot_wider, separateの3つとmissing value関連が基本か。 割と単純だがこれだけで十分なんだろうか?最後の例はなかなか複雑で、これがここまで素直に扱えるならだいたいのケースでOKという気もするが。
tapplyとか使うよりはずっと楽だね。
joinとかの便利関数についての説明。relational algebraを自前で実装している感じだな。 それほど驚きの何かがある訳では無い。
19.6.2でパイプライン関数の書き方という説明がある。 パイプラインは大きくtransformationとside-effectに分けられて、side-effectはinvisiblyに自身を返すべきだ、という事が書いてある。
invisibleという関数があってこれで返すとrepl上に表示されないらしい。へー。
パイプについては多くの関数型っぽい言語で良く使われているが、 パイプでコードを書く時の原則みたいなものはそんなに深堀りされていない気がするな。 難しく考えなくても書けるのが良い所でもあるけれど、 良いコーディング原則はこういう新しいもの(というほど新しくも無いが)に対してもちゃんと考えられるべきだよなぁ。
29.6 R Markdown formats, dashboards
おー、簡単に作れていいな。 こういうUIを簡単に作る系はいろんなところでいろんな人が独自に作ってる感じがあるが、 それぞれ良さがあるよねぇ。
flexdashboardというのを使うらしい。 R Markdown Format for Flexible Dashboards • flexdashboard
これは結構興味ある話題なので独立したページを作る。 LabNotebook
理論には詳しいがプログラムは素人、みたいなRの入門者向けの、データ分析の入門書。 ggplot2やdplyrで有名なHadley Wickhamみずから書いた入門書。なかなかこういう本は無いよなぁ。
扱う内容も幅広く、プログラムの基礎みたいなもの、tidyverse関連、モデル関連、R Markdownといった事を扱う。 しかも開幕がggplot2とかビジュアライズ周りから始まる。
そんな幅広い事を扱う入門者向けのものではあるが、tidyrを使ったデータ整形やdplyrを使った変形などはかなり複雑な例もあり、 tidyverse関連の内容としてはかなり詳しい方に属するんじゃないか。 自分もその辺を知りたくて読んだのだが、そこに関しては非常に満足の行くものだった。 ggplot2とdplyrは素晴らしいよなぁ。
一方でさすがにforループだとか関数だとか条件分岐や文字列やdateの扱いなどの話は自分にはあまり必要な内容では無かった。 そういうところは適宜読み飛ばしていくのが正しい読み方だろう(自分は結構読んでみたが)。
昔Rを結構使ってた自分だが、いろいろと落とし穴の多いところに関しては代替のパッケージがいろいろと生まれていて、 言語組み込みのライブラリよりそちらを使う方が良いようで、 そういうものの紹介が多いのも今風のRの入門として良いように思う。 そういう訳でベテランのプログラマであっても最近のRを知らなければ得るものは思ったより多い。
なお、本来のターゲットである、ちゃんと理論を勉強した人向けのデータ分析の実務の入門書としては、なかなか素晴らしいんじゃないか。 本がどうこう、というより、R Studioおよびtidyverse周辺の環境は、Pythonよりもデータ分析屋向けだよなぁ、と思った。 知らないといけない事が少ないし、 少ないプログラムやライブラリの知識でより多くが出来る。 逆にそういう人が多い組織はRを選ぶメリットは大きいとも言える。 ただ本が良く出来ているという側面も確かにある。 やはりWickham御大自らが書く本は説得力が違うよなぁ。 たぶん現存するデータ分析の本の中で、圧倒的にもっともプログラム能力の高い人間の書いた本だよなぁ、これ。 こんな本が無料で公開されてしまっているって凄い話だ。
自分は、当初はtidyverse関連の章だけ読んで終わりにするつもりだったが、結局だいたいは読んでしまった。 自分のようなプログラマでもそれなりに得るものがある、と思うような内容だったのだろう。
データ分析の仕事を結構してきたが、分析のある程度分かるプログラマというのはだいたいインフラ周りに行きがちで、 分析自体をする人は少なかった。分析をする人でもプログラムの能力はMLOpsというか、 デプロイとかそっち側に注がれる事が多い気がする。
また、プログラムも出来るとイキりたい若者などはデータ分析にとどまらずサービス開発もやる、というスタンスを取りたがり、 やがて単なるサービス開発屋になるというのがパターンに思った。
でも本来、プログラマが分析も出来るというなら、やるべきは分析の力をプログラミングで強化する事で、 それはまさにtidyverseみたいなライブラリとかを整備していく事だよなぁ。 ある程度分析屋が居て分析対象が同じような対象である組織なら、きっとそういう仕事はあった方が良いと思う。 特にtibbleとかdplyrを作るってほとんどのデータ分析屋には不可能なのだから、 ちゃんとしたプログラマが関わる必要があるよな。 そういう仕事はもっとやってみてもいいんじゃないか。
そんな事が出来るのは地球にはWickhamただ一人しか存在しない可能性もあるけれど。