2012年12月5日水曜日

R解析用データフォーマット例 (解析用データの作り方)


R講座などをやるようになって、もっとも必要性を痛感しているトピックです。コンピュータを用いてあらゆる統計解析を実行する上で、ごく基本的なデータフォーマットの作り方が案外知られていないようなので紹介しておきます。

下記のような形式にするのが一般的です。これ以外の形式で作られたデータセットはケースバイケースな変換が必要であり極めて扱いづらいです。あらゆるデータは日常的に全てこの形式で作成することをお勧めします。また私の知る限り、現行ではこの形式を受け付けられない統計用ソフトウェアはありません(Excelでさえ、カテゴリーごとの集計が可能なsumifなどの関数群がちゃんと用意されています)。

以下は、Rに内蔵のデータセット"Chile"の一部です(これの表示の仕方は末尾に。なお、わずかに改変してあります)。



Excelで集計した表を作るのに慣れてきた方は、この例のregionの列のように同じアルファベットがダラダラと並んでいるのを気持ち悪く感じるかもしれませんが、集計したいという時はRの基本的な関数(pivot_longer, pivot_widerやcount、map、summariseなど)で簡単に変換することができます。逆に集計されたデータからこの形式に還元するのは困難な場合が多いです(往々にして1から作り直すハメになり、その作業が現実的にデータ解析の時間の大半を占めることも多々あります)。

ただし、簡単な構造のものならば、少ない労力で集計データからの変換は自動処理可能な場合があります。こちらの記事が参考になるでしょう(→ 集計データ←→データフレーム型の変換)。
実際問題、データ入力の時点で多少は集計している方が楽ではあるのですよね…この記事はそんなニーズの1つの助けになると思います。



##### 解析用データ作成の注意点 ###################
解析用データの形式で構築できているか否かが自分で分からない場合の判断基準にもなるでしょう。:

1. 1行目を見出しとして用います。下に連ねるデータは横一行あたり1データセットとなるように配置します。こうすると、データを追加または削除するなどの編集もごく容易です(このフォーマットを推奨する大きな理由の1つでもあります)。

2. つまり、新しいデータが追加された時に、一番下の行に単に付け足すだけで結合できることもチェックポイントになります。もしどこかにフォーマットの変更や計算・集計し直しが必要となるならば、それは既に集計されてしまっているデータフォーマットであることを意味します。

3. データの階層構造は横方向にする。よく、2行以上にわたる階層的な見出しを見掛けますが、これも解析には不向きです。階層構造は列で対応してください。この"Chile"の例ではregionの列が階層を表しています。このような階層を表す列を含めることで複数行にわたる階層的な見出しは無くすことができます。

4. インデックスは要素名でなく、カテゴリー名を表します。上記の例ではA列はregionというカテゴリー名であり、このなかにN、C、Sという3つの要素名が含まれます。ありがちな誤用としてN、C、Sをインデックスにしてしまい、該当する場合は1、そうでない場合は0などとするケースを見受けます。この程度なら簡単にプログラム処理できますが、思いつかないと煩雑な修正が必要となってしまいます。

5. Excelで複数のワークシートを用いないでください。1つの目的のデータはワークシート1枚に収めましょう。データ管理・解析の用途ではExcelの豊富な"親切"機能のご利用はなるべくご遠慮ください…。

6. とにかく、見た目の整然さを追求したい気持ちは捨ててください。とくにExcelの"セルの結合"は厳禁、手作業で解除しないとRで読み込めません(セル結合の対処については下記のトラブルシューティングも参照)。見た目の区切りを分かりやすくするための空白列や行を挟むのも不要です。
Rにデータを読みこませる際にはふつう、.csvのファイル形式(comma-separated valuesの意味)にするため、テキストファイルをカンマで区切っているだけのデータとしてRに送られます。それ以外の要素(フォントや色、セルの結合など)はRに伝わらないばかりかエラーのもとになるということです。繰り返しますが、集計された"きれいな"表を作りたければ、RやExcelの自動処理機能を駆使していくらでも事後作成が可能です。

7. 個々のデータ記述のルール:
数字と文字を切り分けること。個体数や体長のような、数字であるべきデータ列の中に、メモやオス・メスなどの変則的なデータが混じっているケースを見掛けます。これがひとつでも混じっていると、そのデータ列は文字列として認識され、数値解析ができなくなるので要注意です。備考のようなコメントは最後の列にまとめておけばよいです。そうすればRへの読み込みの際にはその列を除去するなど簡単に対処できます。
機種依存文字(ソフトウェア依存の特殊文字)は厳禁。○の中に数字・英数字などが該当します。アルファベットのバリエーションに注意。öやôのような文字、これらは機種依存文字を使わなくても入力可能です(この例ではMacの場合、option+u→o、option+i→o)。
全角(日本語など2バイト文字のこと。全角スペースはとくにダメ)はなるべく使わない、読み込みの際に"不正なマルチバイト文字があります"のようなエラーが起こったりするし、コードを書いていく際にもエラーの温床となります。全角の数値もエラーのもとです。余計なエラーを回避するためにも、初心の方はとくに半角のみを用いることをオススメします。
・全角を含むファイルが読めない場合のほとんどは、異なるPC間でのやり取りで起こることが多いと思います。Window環境で作成された全角を含むファイルが、Macで読めない場合: read.csv(でーた, fileEncoding="cp932")。逆に、Macで作成されたファイルがWindowsで読めない場合は、read.csv(でーた, fileEncoding="UTF-8")
(2020.12.20追記)→もはやExcelファイルで読み込むようにした方が文字に関するトラブルが少ないのではと思い始めています。readxlパッケージのread_excel関数で.xlsxを読み込む方法ならば、環境や文字をほとんど問わないです。それでもセルの結合や2行の見出しなどは依然ダメです。
欠損値(データの抜けている箇所)は NA と記述しておいた方がよいです(NA: Non availableの略)。こうしておくと「あぁ、ここのデータは抜けてしまっているんだね」とRが理解してくれます。ただし、現行(Mac版 R2.15.1)で見ている限りでは、欠損値を空白のままでもNAとして読みこんでくれる模様。現在ではたぶん大丈夫です。read.csv("ファイル名", na.strings="NA") とすれば万全です。
単語先頭や末のスペース、空白セルのスペースを避ける。どこにエラーがあるのか発見が難しいです。ハイフンは、なるべく負の数値を表記する時のみに留めましょう。別の文字におきかわってしまったりすることがあります。なお、ピリオドの使用はOKです。
数字から始まる見出し、ハイフン(-)、ピリオド、半角スペースは避ける。Rのread.csvなどで読み込もうとした際に "readTableHeader で不完全な最終行が見つかりました"のようなエラーが出るはず。アンダーバー( _ )は安全です。
見出しの文字の中にスペースを入れない。例えば「Homo sapiens」を変数に用いる場合は、「Homo_sapiens」のようにアンダーバーなどで埋めておきましょう。スペースが入ったままでは、見出し名で取り出す場合にdata$`Homo sapiens’のような一手間が発生します。なおデータ部分では問題にならないようです。


##### トラブルシューティング ########################
実際、なんだかよく分からないけれどデータが正常に読み込めないということが多いと思います。
もしや!?と思ったら下記を参考にしてみるとよいでしょう。

1. データが読み込めない(read.csvなどで読み込みを試すものの、何らかのエラーが出てしまう場合)
"〜に不正なマルチバイト文字があります" は、次のようにエンコード指定で解決できる場合もけっこうあります: read.csv("ファイル名.csv", fileEncoding="cp932")。それがダメなら, fileEncoding="shift-jis"。これはたぶんWin環境で作られたファイルをMacで読み込むケースです。逆にMac環境で作られたファイルをWin環境で読む際のエラーが生じたときは、fileEncoding="UTF-8"とすればよいかと。
・最近(2019.06追記)のExcelではUTF-8のcsvファイルを出力できるようになりましたが、"BOM"というヘッダー付きのcsvになっています。これをmacで読み込むと不具合が生じています(しかもエラーメッセージが出ない)。これを回避するにはread.csv("ファイル名.csv", fileEncoding="UTF-8-BOM")のようにエンコーディング指定すればOKです。
・上記 7 のデータ記述のルールに引っ掛かっていないか、再度チェックしてみる
・データの一部が末尾の列にはみ出ていたり(欠損値があるどころじゃなく、数個のデータだけがある列ができてしまっているとか)すると、自覚なく読み込めないことがあります。何も起こらないサイレントエラーが出たこともあり厄介。
・データが5行(N = 5)未満の場合はNAのみの行を追加して5行以上にする。なぜか、これより少ないとエラーになる(read.csvなどで読み込もうとすると"readTableHeader で不完全な最終行が見つかりました"が出る)。
・"In scan(file, what, nmax, sep, dec, quote, skip, nlines, na.strings,  :
   入力コネクション 'ファイル名.csv' に不正な入力がありました "
機種依存文字が混じっていた時に発生します。これの対処として最近いい手を思いつきました。Excelファイルを読み込む関数を使用すると読み込めるようです。
openxlsxパッケージのread.xlsx関数や、readxlパッケージのread_excel関数で機種依存文字入りのファイル(.xlsxファイルで保存しておくこと)も読むことができました、fileEncoding指定も不要でした。read.xlsx("ファイル名.xlsx") のように使います。

2. Excelのセルの結合を解除しデータ整形する場合のコツ:Excelでシート全面を選択し"セルの書式"で"セルの結合"チェックボックスをオフにすれば一括で解除できます。すると結合されていたセルの1番上のセルにのみデータが残りますが、if関数を使って容易にデータ補完が可能です。次の例は、ExcelでA列に元データがある場合にB列に補完後のデータを作成する場合です:B2に、=IF(A2="",B1,A2) と入力し、後は下に向かってコピペするだけです。
ちなみにRではtidyverseパッケージ群のひとつ、tidyrパッケージのfill関数で容易に対応可能、標準設定で上の値を参照して補間することができます。

3. 数値のはずのデータでなぜか計算ができない(文字として認識されてしまう)
まずは次のような方法でエラーの原因となっているデータがあるかどうかチェックしましょう:
・数値のつもりが文字が混じっている場合、Excelでそのセルだけは左寄せになるので見つけやすいでしょう(文字は左寄せ、数値は右寄せ)
・Excelのデータチェック関数も利用できます。数値か否かはISNUMBER()、文字か否かはISTEXT()
・Rのstr()関数でデータの構造をチェックしてみましょう:
str(data)のようにすると、数値は"int"、文字は"Factor"となります。下記はYにわざと入力ミスを混ぜてみた場合の例
# str(data)
# 'data.frame': 200 obs. of 4 variables:
# $ X : int 1 1 1 1 1 1 1 1 1 1 ...
# $ F: Factor w/ 2 levels "A","B": 1 1 1 1 1 1 1 1 1 1 ...
# $ Y : Factor w/ 148 levels "101","103","104",..: 94 45 71 55 55 67 51 45 24 45 ...

→tidyverseパッケージ群のread_csv関数や、readxlパッケージのread_excelパッケージで読み込むと、変数型を表示したtibble形式で読み込まれるので、これによっても確認できます。

*数値となるはずがなぜか文字として認識されてしまうケースには以下のようなミスが考えられます:
・全角の数値が混じってる(すると、文字扱いになったりします)
・数値にうっかり文字をくっつけてしまっている(例:入力作業中でいったん"保存"をするつもりが、ショートカットのコマンドを押しそこねていて"s"を入力してるとか)
・数値のゼロ(0)の代わりに、アルファベットのoやOを入力している
・小数点が二回連続してしまっている(例: 1.2としたいところが、1..2となっている)
・小数点の代わりにカンマ(,)が入っている(例: 3.5としたいところが、3,5となっている)


cf. 冒頭のデータセットの表示のさせ方:Rに以下のようにコードを入力すると表示させることができます(# 以降は説明なので入力不要、コピペしてもコード実行の障害にはなりません)。
library(car) # carというパッケージを呼び出す(インストール要)
data(Chile) # データChileを呼び出す(Rは大文字と小文字を区別するので注意)
Chile # と入力すると大量のデータが表示される
head(Chile,30) # 上から30データ目までを表示(大量表示を回避できる関数。下からの場合、tail()が使える)

pairs(Chile) # 全データ間の関係を対戦表形式で図示できる。対戦表でゼロ表示される対角線の部分に見出が入っている。タテ・ヨコ方向にデータが対応する。

0 件のコメント:

コメントを投稿