【R】続・csvデータを読み込むときに出てくるエラーを解消したい。


最強の統計処理系オープンソースプログラミング言語「R」において、初歩の初歩である、データの読み込みで苦戦しています。


以前、こんなエントリーを書きました。
demacassette2.hateblo.jp

実は、これでは完全にエラーが解消したわけではございませんでした。その後もエラーに悩まされた日々が続き、やっとこさ解決しました。

csv等で保存されたデータを読み込む際、文字列や数値などが混在していると、R側が勝手にデータの型を判断して読み込んでくれます。


しかしそこには、意外な落とし穴が!!


データの型とは?

主なデータ型は以下の通りです。

  • 実数・・・real
  • 整数・・・integer
  • 文字列・・・factor,character

詳しくは、こちらを参照くださし。
データ型 | R のデータ型・モード・クラス


そして、例えばcsvデータを読み込む際の最もシンプルなコードはこちら。

#data.csvというファイルにあるデータを、変数dとして読み込む
d <- read.csv("data.cv")

もし、csvデータの中に、文字列と数値が混在していた場合は、以下のようなエラーが出ることがあります。
f:id:demacassette:20170712230759p:plain

これに悩まされていました。

もし、こんなエラーが出ると、何が困るのか?

  1. 数値として読み込んでほしいのに、文字列として読み込んでいるので、計算ができない。
  2. 文字列から数値に変換する手間が一つ増える。
  3. データ列が多い場合、そんなことやってられない


とにかく、正常に思い通りにcsvデータが読み込まれてほしい!



考えられる解消法は試したが。。。

このエラーの解消法として、いろんなことを試していました。

解消法 code
データ型が混在しても混乱しないおまじない as.is=T
文字列をfactor型として読み込まないようにする stringsAsFactors=F
読み込むデータのエンコードをきちんと指定する encoding="Shift-JIS"
読み込むデータのデータ型を列ごとに指定する colClasses="character"
colClasses=c("character","integer","rear", ....)
読み込んだ後に、整数や実数に変換する as.numeric()
as.integer()

以下、参考元
R:read.csv / read.tableで型と列名を指定して読み込む。 - Qiita
data.frameに変換する時文字列が因子になるのを避ける - 盆栽日記
R:read.csv / read.tableで型と列名を指定して読み込む。 - Qiita
colClassesで特定の列の読み込み型だけを指定、他の列はRの判断にまかせる(read.csv、read.table) - Rプログラミングの小ネタ

・・・結果、どれも解決しない!

そして、私は気づいたのです。



「データ側の原因をちゃんと見たか?」


エラーの原因はいたってシンプルだった。

そう、エラーが出る理由は、いたってシンプルでした。

数値として読み込みたい列の表示形式を、エクセルの保存時に「数値」として保存していなかったのです!

エラーの解消方法

エクセルのデフォルト設定だと、「標準」という表現になっていますが、このままだと、Rでは文字列として認識してしまうようです。

これ。
f:id:demacassette:20170712231458p:plain

この状態だと、Rは不機嫌になります。(私の場合)
そこで、このようにするだけ。(データ全体を選択して、実行しても大丈夫なはず)
f:id:demacassette:20170712231836p:plain


そして、解決した結果がこちら。

テスト用のデータ
※身長、体重は適当です!あまりワンピース詳しくないしw


データ読み込みとデータ型の確認コード。

#csvデータの読み込み
test <- read.csv("data/read_test.csv",stringsAsFactors=F)

#先頭10行のレビュー
head(test)

#各列要素の呼び出し
test$name
test$身長
test$体重

#読みこんだデータ型の確認
sapply(test, class)
str(test)


結果


head(test)
 No       name 体重  身長
1  1     ルフィ   55 170.5
2  2     サンジ   65 175.1
3  3 チョッパー   40 140.9
4  4       ゾロ   70 180.6
5  5 フランキー  100 195.5
6  6       ナミ   45 162.4
test$name
[1] "ルフィ"     "サンジ"     "チョッパー" "ゾロ"       "フランキー" "ナミ"

test$身長
[1] 170.5 175.1 140.9 180.6 195.5 162.4
test$体重
[1]  55  65  40  70 100  45

#読みこんだデータ型の確認
sapply(test, class)
        No        name        体重        身長
 "integer" "character"   "integer"   "numeric"
str(test)
'data.frame':   6 obs. of  4 variables:
$ No  : int  1 2 3 4 5 6
$ name: chr  "ルフィ" "サンジ" "チョッパー" "ゾロ" ...
$ 体重: int  55 65 40 70 100 45
$ 身長: num  170 175 141 181 196 ...

これで、中身が確認できました。


エラーなく、データを読み込めた時の安堵感はすごい。

 やはり、データ解析は始めるまでが大変ですよね。

どんな結果を導きたいか、そのためにどんな計算処理が必要か、そのためにどんなデータが必要か、そのデータ形式はどのようなものが適切か、どうやってそのデータを集めるか、効率よくバグ取りするか。

この初歩の初歩である。データのバグ取りの部分で、ずっとモヤモヤしていました。


やっと、私のR人生に光が差してきたかも??


参考図書

Rビジネス統計分析 [ビジテク]

Rビジネス統計分析 [ビジテク]