と。

Github: https://github.com/8-u8

データ分析をちゃんと管理しよう with R 【フォルダ構成編】

年間50記事執筆から逃げるな

はい……

Rは統計解析に特化した言語で、統計解析に特化した人間がよく用います。
ただR言語を使用する人は必ずしもコンピュータサイエンスに特化した人間とは限りません。

きぬいとはRを使って統計解析をしますが、お世辞にもエンジニアを名乗れるスキルセットはありません。ロンヨリショウコダ

加えて、Rに触れたばかりの人は、とにかくデータを読み込んで summary(dat) するのでも精一杯なことがあるでしょう。
逆に言えば、プログラム言語未経験の人が触れたばかりでも summary(dat) まですぐにたどり着けることを意味します。
これはコードやその使い方が日本語で読め、コミュニティも活発であることの証左だと思います。これは良いことです。
一方、極めて実用に近い言語、というのがRの特徴ですが、これにはメリット・デメリットがあると考えています。

メリット: 目的達成までのルートが近い(「とりあえずデータを読み込んで線型回帰」までは短期間で行える)
デメリット: 目的達成までのルートを近くするために「プログラム言語」としての前提をいろいろすっ飛ばしてしまう

Rは割と書き手の気持ちを汲んでくれるやさしい言語です。一方で、やさしさがときに傷つくときもあります。
きぬいとの場合、「Rのコード」と「入力データ」と「出力結果」が全て1つのファイルで管理されていたときに、それを感じました。

今回はそんなお話と、「せめて、ファイル管理をしようね」というお話です。

「本に書いてるコードは実行できるのに、自分でやろうとするとなんかエラーになる」問題

こんな気持ちになった

昨今は機械学習の台頭により、コンピュータサイエンティストやエンジニアが統計解析に接触しやすくなり、
多くの実務的な場面ではエンジニアリングによる統計解析のシステムやソリューションへの実装によって、
統計解析がよりソフトウェアの中で価値を出しやすくなりました。
加えてRStudio Serverなど、自分のPCにRをインストールせずとも解析ができるような環境が進んでいます。
これは非常に良い傾向である一方、分析の再現性を大きく揺るがす側面もあると個人的には懸念します。

ソフトウェアの開発やアプリケーションの開発において、コードやデータ・ファイルを上手に管理することは
非常に重要な技術です。それが煩雑だとそれらの更新や機能追加などが難しくなり、非効率だからです。
これはおそらく実験管理においても重要な場面が多い、はずなのですが。。。

統計解析は、ソフトウェア・アプリケーションへの実装や実験管理を必ずしも必要せずとも可能です。
つまり「分析できりゃあいいだろ?」というモチベーションでも「できてしまう」ということです。

SPSSなど、有料の統計解析ソフトウェアは分析に必要な構成を「プロジェクト」という機能で一括で管理するように設計されてます。
それゆえ、SPSSからR言語に移った人などは、こうした構成を自分で作る方法論が醸成されていないため、
1つの「分析」フォルダにソースコードとデータと解析結果とグラフとドキュメントが全て存在するような状態になっているんじゃないでしょうか。
実際、学生時代のきぬいともそうでした。カオスってた。当時のコードはもう誰も読み解けない。
仕事でもそういう煩雑なフォルダ管理によって大やらかしをしてしまったり、
kedroという機械学習パイプラインライブラリに触れ、開発者とのコミュニケーションを通して、
「しっかりファイルを管理するって大事なんだなあ」ということを学びました。

socinuit.hatenablog.com

未だに「本と同じようにコードを書いたのに読み込めない」という相談を見聞きします。
大抵はフォルダのパスが違うことに起因します。このつまづきを撲滅するのがこの記事の野望です。

なんでファイルを分けるの?めんどくさい。

過去の自分の仕事を、今の自分が理解できるようにするためです。
各位、Rで分析するときフォルダは下のようになっていないでしょうか。

分析プロジェクト
├ 実験データ①.csv
├ 実験データ②.csv
├ 今日の実験データ.csv
├ 結果①.csv
├ 結果2.csv
├ 結果3.csv
├ 結果4.csv
├ 結果5.csv
├ 結果ろく.csv
├ 結果あああ.csv
├ 結果ああああ.csv
├ グラフ.png
├ グラフ改良.png
├ 分析.R
├ 分析(先輩).R
└ 分析(本番).R

「なってるww」って人はこれを今すぐ改める方法を考えましょう。
何が問題かといえば全部ですが、まず以下。

  • 入力・出力・コードが1つのフォルダで管理されてしまっている
  • 名前だけでどの入力・結果を使うのかが分からない
  • コードのバージョン管理ができていない
  • 上記故にデータ分析の再現ができるかが個人の記憶に依存する

これは誰も悪いわけではないのですが、多くの入門書ではフォルダ管理については明言しません。
Rは統計解析に特化した言語なので、その手法の手軽な実装力と可視化力が大きな強みであり、
それの紹介と実例の提供が多くのドキュメントでの目的だからです。
そして、それを参考にしてRを使うので、こうした管理以外の方法を知らないのは仕方のないことなのです。

だからここで管理の仕方を学ぶきっかけを得てくれたらいいなあとおもいました。

まず、コードのバージョン管理は難しいので、一旦脇に置きます*1 システムに組み込む為の管理ではないので厳密性はあまりありませんが、
以下のようにするだけでも未来の自分に優しくできます。

分析プロジェクト
├ 入力データ
 |    ├ 20200806_実験データ.csv
 |    ├ 20200807_実験データ.csv
 |    └ 20200808_実験データ.csv
├ 出力データ
 |    ├ csvファイル
 |     |    ├ 20200806_140340_実験回帰分析結果.csv
 |     |    ├ 20200807_143040_実験回帰分析結果.csv
 |     |    └ 20200808_145520_実験回帰分析結果.csv
 |    ├ グラフ
 |     |    ├ 20200808_153422_回帰直線.png
 |     |    └ 20200808_173006_残差プロット.png
├ ソースコード
 |   ├ 20200805_前処理自動化.R 
 |   ├ 20200806_回帰分析.R
 |   ├ 20200807_回帰分析.R
 |   └ 20200808_回帰分析.R
├ 実験管理
 |   └ 分析実施記録.txt

なにを改善したかというと全部ですが、具体的には以下。

  • いつ作ったファイルなのかをファイル名に書いている。
    • 基本日次。日に数度起こりうる場合時間も書いている
    • 名前に規則性をもたせている
  • 何をした結果なのかをファイル名に書いている
    • 分析とは具体的になにをした結果なのかを書いている。
    • 具体的にどんなグラフなのかを書いている
  • 「入力」「出力」「ソースコード」「実験管理」にフォルダをわけている

これによって、未来の自分はまず「分析実施記録」を参照すればよいということが分かり、
その情報を元に入力、出力、ソースコードそれぞれを参照すれば良いので、
同じ結果を再現できる可能性が飛躍的に向上します。これだけで。
でもめんどくさい。Windowsならエクスプローラを立ち上げて右クリックして「新しいフォルダ」を4回押して名前変更して……
Rでやりたいですよね。できます。

ファイル管理が重要なのは分かった。Rでどうにかならん?

なるようになる。
ここは以下も参考になります。

stats.biopapyrus.jp

heavywatal.github.io

Rがデータをすぐに読み込める場所を知りたい

最近だとRstudioでRprojectを作るので、Rがすぐにデータを読み込める場所(「カレントディレクトリ」といいます)についてはあまり心配がいらないかも知れません。
データ分析始めましたで躓くエラーに No such file or directory があると思います。これを解決したい。
Rにおいて、カレントディレクトリを調べる関数はgetwd()関数です。
デフォルトであれば{ユーザ名}\Documents(Windowsの場合)、Rproject下であれば、たとえば{ユーザ名}\Documents\{プロジェクトファイル名}がコンソールに表示されます*2。、

また、任意の場所をカレントディレクトリにする方法もあります。setwd()関数です。
ですが、上記のファイル管理を徹底する場合、この関数はあまり使わないほうが良いと思います。
デスクトップにデータがあるのであれば、プロジェクトファイルにデータをコピーしてもってくる方が絶対に良いという信仰が(個人的に)あります。

相対パス絶対パス

情報系の資格を勉強すると間違いなく出てくるやつ。パスってなんだよ。という気持ちになりますね。
簡単に言えば、プロジェクトファイルの「入力データ」にアクセスする方法が2パターンあります。
1つが、「どのデバイスの、どのユーザの、どこどこの場所にあるこのファイル」という指定の仕方で、これを「絶対パス」といいます。
もう1つは「このフォルダにあるこのファイル」という指定の仕方で、これを「相対パス」といいます。
絶対パスは、たとえば C:\Users\{ユーザ名}\{プロジェクトファイル名}\入力データという形で入力します。
相対パスは、仮に getwd(){ユーザ名}\Documents\{プロジェクトファイル名}と表示されたときに、
.(ドット)\入力データだけでファイルを指定・参照できます。
たとえば、以下のコードでカレントディレクトリやファイルを確認して、データを読み込むことができると思います。
>で表現しているところは、R側からの回答だと思ってください。

getwd()
> [1] `キヌイト=サン/Documents/データ分析プロジェクト`

# (応用)カレントディレクトリの「入力データ」にあるファイル一覧の表示
list.files("./入力データ")

> [1]  "20200806_実験データ.csv"  "20200807_実験データ.csv"  "20200808_実験データ.csv"

# 相対パスによるデータの読み込み
jikken_data <- read.cst("./入力データ/20200806_実験データ.csv")

フォルダを「作る」

いちいちプロジェクトフォルダでファイルを新しく作るのが面倒な人は、dir.create()関数を覚えましょう。
これも、相対パスでサブフォルダを作成できます。

dir.create("./実験データ")

list.files()

> [1]  "実験データ"

つまり、Rprojectを作ったら、雑に以下のコードを1回実行すればよいのです。
プログラマさんには怒られますが僕らはピヨピヨアナリスト。シッタコッチャネエヤ

dir.create("./入力データ")
dir.create("./出力データ")
dir.create("./ソースコード")
dir.create("./実験管理")

# ちゃんとできているか確認
list.files()

その他

フォルダに関しては、Rでも作成・削除・名前の変更・コピーなどが可能です。
詳細は先に挙げたサイトを参照しながら使ってみてください。

次回予告

次回は統一的なファイル名を作るための情報を引っ張ってくる方法について検討します。

  • Rで日程や時間をとってくる(Sys.Date()とか)
  • Rでとってきた日程や時間をファイル名にくっつける(paste0()とか)
  • 特定の文字を含むのファイルだけを読み込む(grep()正規表現について) など……

よりEnjoyするために……

*1:同じ解析を同じパラメータで実施するためのコードの書き方の技術、gitなどを使ったバージョン管理はまた別の話です

*2:これを「値を返す」と表現するのですが、学生時代この表現を使ったら「誰に?」という反応をされた記憶があります