R言語徹底解説を読む (1) ようこそRプログラミング

この記事が想定する読者層

もしあなたが「プログラマー」ならば、この記事はまるで不要かもしれません。

ここで言うプログラマーとは、たとえば以下のような習慣を持っている人です。

  1. ほとんど同じ処理をソースコード中に2回以上書いていたら違和感を感じる
  2. 出力結果が変わらなくても、実行速度や理解しやすさのためにソースコードを書き直すことがある
  3. Gitなどのバージョン管理システムを使うことができ、過去のソースコードを「日付の含まれたファイル名でバージョンごとに別ファイルとして保存しておけばよい」とは考えない
  4. 動作テストを自動化し、ソースコードを書き換えてもそれぞれの関数の挙動が意図したものになっているかを確認できる

この記事は、ひょんなことからRに出会い、コードをコピペで動かせるようになり、

「いつかコピペじゃないコードが書けるようになりたい」
「他のプログラミング言語もできるようになりたい」

とぼんやり思っているうちに月日が流れてしまい、漠然とした未達成感を味わいながらも何から始めたらいいのかまるでわからなかった僕のような人に読んでもらえたらと思って書きました。

......そんな人がいるのかはさておき。

それでは、挫折しないための「R言語徹底解説」通読法 で予告した、感想ブログ、はじめます。

 

得意なところと欠けているもの

R言語は「データ分析に特化したプログラミング言語」であるとよく言われます。では、「特化」とは具体的にはどういう状態なのでしょうか。

2009年の2月にアメリカのサンフランシスコで行われた、Bay Area R User Group キックオフイベント*1での発表では、次の3つがRの得意分野として挙げられています。

  1. データの操作 (data manipulation)
  2. 統計 (statistics)
  3. データの可視化 (data visualization)

これを受けて、続く発表において、当時Googleにいた応用経済学者のBo Cowgil*2は次のように言っています。

The best thing about R is that it was developed by statisticians. The worst thing about R is that… it was developed by statisticians.

これは、R言語本体に限った話ではありません。Rがデータ分析に特化した言語であるのと同時に、Rユーザーもまた「分析に特化」した存在であることが多いのです。

R言語徹底解説』1章には次のような指摘があります。

Rのユーザは,特にデータ分析の再現性を保証するためにも、質の高いコードを書くように心がけて欲しいのだが,そのためのスキルが充分に身についていないのも事実だ.本書を通じて,読者がRの単なるユーザから能動的なプログラマに変貌を遂げる,あるいは他言語のプログラマがRに貢献しようという意欲を抱いてくれることに筆者は期待している.

一般論として、Rのユーザは具体的にどんなスキルが欠けているのでしょうか。

他の言語のユーザーたちに比べると、 Rのユーザたちは過程ではなく結果を重視する傾向にある.また,ソフトウェア工学で作業を効率化する実践手法に関する知識も断片的である.例えば,ソースコードを管理するためのツールを利用したり,動作テストを自動化するRプログラマも少ない.

プログラミング言語なんて所詮なにかの問題を解決するための道具じゃないか、道具の習得にそんな時間をかけられない」という声が聞こえてきそうですが、ちょっと待ってください。次のような逸話をどこかで目にしたことはありませんか?

刃を研ぐ

 森のなかで、必死で木を切り倒そうとしている人に出会ったとしよう。
「何をしているんです?」とあなたは聞く。
すると男は投げやりに答える。
「見ればわかるだろう。この木を切っているんだ」
「疲れているみたいですね。いつからやっているんですか?」
あなたは大声で尋ねる。
「もう五時間だ。くたくただよ。大変な仕事だ」
「それなら、少し休んで、ノコギリの刃を研いだらどうです? そうすれば、もっとはかどりますよ」とあなたは助言する。
すると、男は吐き出すように言う。
切るのに忙しくて、刃を研ぐ時間なんてあるもんか!

7つの習慣という書籍の、第七の習慣として紹介されている「刃を研ぐ」という項目で、よく紹介される逸話です。

本来の意味は知識を深めろ技術を習得しろというだけではなく、運動した方がいいとか、瞑想した方がいいとか、人に奉仕して役に立とうみたいな内容も含んでいるようですが、大丈夫です。

約1kg弱の重さがある『R言語徹底解説』を通勤通学の際に持ち歩くことはかなりの運動になりますし、「著者のHadleyはどういう想いでこの文章を書いているのだろう」と考えることは瞑想になります。7つの習慣では聖書を読むことを勧めているので、敬虔なRユーザなら何を読めばよいかはもう分かりますよね。さらに、Rを学べば、人に奉仕して役に立つ機会はすぐにやってきます!

まんがでわかる 7つの習慣

まんがでわかる 7つの習慣

 冗談はさておき、1章に散りばめられた項目のいくつかは、この「刃を研ぐ」ことの必要性を説いているとして解釈できます。以下に、独断と偏見で再構成した内容を載せました。本来の内容を知りたい方はぜひ原著を参照して下さい。

  1. プログラマにとって大切なことが書いてある」本を読む
  2. 他の人の書いたソースコードを読む
  3. コミュニティに質問する
  4. 言語の仕組みを知るための本を読む

プログラマにとって大切なことが書いてある」本を読む

1章の推薦図書の項目では、良いプログラマになりたいのならばThe Pragmatic Programmer(邦題:『達人プログラマー』)を読むべきだ、と書かれています。

The Pragmatic Programmer: From Journeyman to Master

The Pragmatic Programmer: From Journeyman to Master

この本は1999年の出版でありながら未だに内容が古びていない良書なのですが、残念ながら日本語版は絶版です。いい本がどんどん絶版になってアクセスできなくなるのは重大な損失だと思うのですが、ここでそれを嘆いてもはじまりません。

同じような内容が得られる本として、たとえばリーダブルコードがあります。

"楽しく気軽に読んでもらいたい。できれば1〜2週間で読んで欲しい" とあるとおり、非常に読みやすい本です。重さもせいぜい400gくらいです。以下に、リーダブルコードの中で目についた記述をいくつかピックアップして載せます。

  • コードは他の人が最短時間で理解できるように書かなければいけない。
  • 名前が「他の意味と間違えられることはないだろうか?」と何度も自問自答する。
  • コメントの目的は、書き手の意図を読み手に知らせることである。
  • 巨大な式は飲み込みやすい大きさに分割する。
  • 一度に1つのタスクを行う。
  • 最初にコードを言葉で説明する。その説明を元にしてキレイな解決策を作る。
  • 最も読みやすいコードは、何も書かれていないコードだ

訳も軽妙で面白いので、ぜひ一読をおすすめします。

また、他にも「プログラマが知るべき97のこと」というド直球なタイトルの本もあります。

プログラマが知るべき97のこと

プログラマが知るべき97のこと

こちらは英語版ならばWEBで無料で読むこともできます。
Contributions Appearing in the Book - Programmer 97-things

特に、No. 14 の Code Reviews や No. 95 の Write Tests for People は必見です。

 

他の人の書いたソースコードを読む

他の人の書いたソースコードを読んでみましょう。

ソースコードなら、入門書でけっこう読んだよ......」と思われるかもしれませんが、それらはあくまでサンプルであり、ソースコードとしては断片に過ぎません。

では、具体的には何を読めばいいのでしょうか?

まずは自分自身がよく利用しているパッケージや関数のソースコードを眺めることから始めるといいだろう.

Hadleyはさらっとこんなことを書いてますが,パッケージや関数がどのように構造化されているかを知らないまま、いきなりソースコードを読もうとしても、リターンが得られるかはやや疑問です。

僕は、ミニマムなパッケージを自作してみるのが、一見回り道なようで実は「パッケージや関数のソースコードを読めるようになる」近道だと思います。パッケージとその構成要素である関数の構造が理解できるだけでなく、「自分でパッケージを作る」ことで他のパッケージがどのようにつくられているのかという興味が湧くようになるからです。

手前味噌ですが、Qiitaに投稿した以下の記事を参考にしていただければと思います。パッケージを作るようになると、Gitでのバージョン管理に伴う種々のコマンドを覚えたり、テストコードを書くようになったりという副次効果もあります!

qiita.com

パッケージのおおまかな構造が理解できたら、ぜひいろいろなパッケージのコードを読んでみてください。hadley作のパッケージの中から、個人的に好きな関数の実装を幾つか貼っておきます。

コミュニティに質問する

Rの作業で行き詰まり、解決策を見いだせないけれど、気軽に質問できるRプログラマが近くにいない人は少なくないでしょう。

R言語徹底解説入門には、Stack overflowとR-helpメーリングリストを頼れ、と書かれています。ですが、英語で質問をするのはハードルが高いと思われるかもしれません。日本にも、Tokyo.R をはじめとするローカルコミュニティを中心に形成された r-wakalangというネット上のコミュニティがあります。r-wakalangについては、以下の記事をぜひ参照して下さい。

qiita.com

質問を投稿する前に

質問を投稿する際に3つほどのアドバイスがあり、これは他のコミュニティに質問を投げる際にも有効なチェックポイントとなるでしょう。

  • Rとパッケージのバージョンが最新であるか確認しよう
  • 再現可能な例を用意しよう
  • 類似の質問がないか探そう
Rとパッケージのバージョンが最新であるか確認する

最新バージョンに上げたい場合はupdate.packages( )関数などがあります。

また、現在のバージョンを確認したい場合は、devtools::session_info( )関数を使いましょう。githubなどからインストールした場合、コミットのハッシュ値なども確認できて便利です。

> devtools::session_info()
Session info -------------------------------------------------------------------
 setting  value                       
 version  R version 3.3.1 (2016-06-21)
 system   x86_64, darwin13.4.0        
 ui       RStudio (0.99.491)          
 language (EN)                        
 collate  ja_JP.UTF-8                 
 tz       Asia/Tokyo                  
 date     2016-07-10                  

Packages -----------------------------------------------------------------------
 package  * version    date       source                       
 devtools   1.12.0     2016-06-24 CRAN (R 3.3.0)               
 digest     0.6.9      2016-01-08 CRAN (R 3.3.0)               
 magrittr   1.5        2014-11-22 cran (@1.5)                  
 memoise    1.0.0      2016-01-29 CRAN (R 3.3.0)               
 purrr    * 0.2.2.9000 2016-07-10 Github (hadley/purrr@ee29e87)
 Rcpp       0.12.5     2016-05-14 cran (@0.12.5)               
 withr      1.0.2      2016-06-20 CRAN (R 3.3.0)               
再現可能な例を用意する

この項については、扱う範囲が広すぎて別途記事にしたほうがいいくらいなのですが、ひとまず以下の記事をぜひ参照して下さい。

stackoverflow.com

また、上のなかでdput( )を用いる方法については、hadleyによって

Reproducibility · Advanced R.

にまとめられています。

言語の構造を知るための本を読む

与えられた関数やデータ構造をただ使うだけでなく、なぜこのような実装になっているのかといったことが気になりだしたら、ぜひ言語の構造に関する本を読んでみてください。ここではひとつだけ挙げることにします。

計算機プログラムの構造と解釈(SICP

SICPStructure and Interpretation of Computer Programs )は、MITのコンピュータ学科の1年生の教科書です。

日本では翔泳社から翻訳版第2版*3が刊行されているほか、WEB上で読みたい場合は真鍋氏によって無償で翻訳・公開されている非公式日本語版PDFも存在します。和田版は訳が固いためやや読みにくい箇所もあるので、書籍版をお持ちの場合でも真鍋版の併読はおすすめできます。原著サポートページがMITのドメイン下に存在し、そこからリンクを辿って原文を読むこともできます。

Hadleyによれば、本書は以下の項目について理解するのに非常に役立ったそうです。

Rでの総称関数に相当する項目は、SICPでは2.4節「汎用手続き(generic procedure)」および2.5節「汎用計算のシステム」に記載されています。R言語徹底解説では、総称関数について第7章でとりあげています。

計算機プログラムの構造と解釈 第2版

計算機プログラムの構造と解釈 第2版

 SICPはさすが教科書なだけあって練習問題が非常に充実しており、総称関数の辺りだけを読み解くだけでもかなりの分量になります。本来こうした練習問題は自分で解いたほうが理解は進むのでしょうが、先人たちがどのように読んだのか知りたい、という方はぜひ以下の記事を参照して下さい。

そしてもちろん、R言語徹底解説自体が、言語の構造について説明した本でもあります。改めて各章で得られるものを列挙してみます。

R言語徹底解説 各章のクリア報酬

  • 2,3章:データ型を理解し、効率的に扱えるようになる
  • 4章: 既存の関数のうち重要かつ有用なものがわかる
  • 5章: コーディングスタイルについて意識できるようになる
  • 6章: 関数の原理とつくりかたについて理解できる
  • 7章: 4つのオブジェクト指向システム(基本データ型、S3、S4、参照クラス)の仕組みを認識できる
  • 8章: 変数のスコープを制御する「環境(Environment)」について理解を深めることができる
  • 9章: エラーが生じた箇所を突き止められるようになる。また、そもそもバグを防ぐための技術を知ることができる。
  • 10,11,12章: 関数型プログラミングの意味とデータ分析にとっての重要性が認識できる
  • 13,14章: メタプログラミングの長所と短所が理解できる
  • 15章: 環境、汎関数、非標準評価、メタプログラミングなど8〜14章の内容を幅広く再確認できる
  • 16, 17,18章: Rで処理が遅く、またメモリが大量に消費されるケースを予測することができ、パフォーマンスのボトルネックを探り当てるプロファイリングと、コードの最適化ができるようになる
  • 19, 20章: C++の高速な関数を実装することでパフォーマンスの高いコードを書いたり、Rに含まれるC言語のコードを理解する準備ができるようになる

 

ようこそRプログラミング 

 長々と書いてきましたが、第1章を通じて、著者のHadleyがもっとも伝えたかったであろう箇所を引用して一旦終わりにしようと思います。

I hope to show that, despite its frustrating quirks, R is, at its heart, an elegant and beautiful language, well tailored for data analysis and statistics.

Rはかなり癖のある言語なので時にイライラさせられるが、それでもRが本質的にはエレガントで美しい言語であり,データ分析や統計処理を実行するのに適した工夫に満ちていることを,本書を通じて示したい.

 

わかる。

f:id:wakuteka:20160607010356p:image  (c) 武田綾乃宝島社/『響け!』製作委員会

 

 

 

 

 

次回予告

次回は「よろしくデータフレーム」 と題して、第2章を読みます。

R言語徹底解説

R言語徹底解説