いつかギャフンと言わせたい

平凡な企業研究員が、いつか周りをギャフンと言わせるための野心的かもしれないゆるい記録

【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ビジネス統計分析 [ビジテク]