read.csv/read.table

<間違い1>CSVファイルを作るときついつい自分が読みやすいようにスペースを入れてしまう.

32, 3, yes, no
13, 6, yes, no
32, 5, no, yes
57, 2, yes, yes
  :

ファイルからデータを読み込む際に、read.csv使って, <間違い2>V3が "yes"かどうかで論理型にしようとする

> data.score <- read.csv("score.csv", header=F)
> data.score
  V1 V2   V3   V4
1 32  3  yes   no
2 13  6  yes   no
3 32  5   no  yes
4 57  2  yes  yes
5 33  3   no   no
     :
> data.score[,3] == "yes"
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

あれれ〜? と思ったけど文字列は以下のように・・・

> data.score[,3]
[1]  yes  yes  no   yes  no   no   no   yes  yes
Levels:  no  yes
> class(data.score[,3])
[1] "factor"

factor型なのか。ちょっと調べてみてfactor()で作れるらしいことを知る。

> yes <- factor("yes", levels=c("no", "yes"))
> yes
[1] yes
Levels: no yes

ふーん。factorの実体は数値らしい。

> as.numeric(data.score[,3])
[1] 2 2 1 2 1 1 1 2 2

なるほど。
ここまでくれば<間違い3>あとは比較するだけ、と勇むが大失敗。

> data.score[,3] == yes
 以下にエラー Ops.factor(data.score[, 3], yes) : 
   因子の水準セットが異なっています 

あれれ〜?

> levels(data.score[,3])
[1] " no"  " yes"

あ、、、、、、、、頭にスペースが、、、、、

というネタ。素直に read.table 使うのが吉かな。そもそもCSV形式を拡大解釈した自分が悪い。
実はread.csvは単にread.table呼んでるだけだし。

> read.csv
function (file, header = TRUE, sep = ",", quote = "\"", dec = ".", 
    fill = TRUE, comment.char = "", ...) 
read.table(file = file, header = header, sep = sep, quote = quote, 
    dec = dec, fill = fill, comment.char = comment.char, ...)
<environment: namespace:utils>

read.tableの引数のas.is = !stringsAsFactors のところを替えればfactorに変更しなくなるのかな。まだここは調べ切れてない。

追記:
オプション as.is = c(3,4)のようにすると 3,4列をfactorへ変換しなくなった。わかりやすい。
また、colClasses="character"してもいいけど、こうすると1,2行目とか数値で入ってほしいところまで文字列になってしまう。なるほど。
空白無視はないのかな ;_;
ってすぐ見つけちゃったよ strip.white。

> read.csv("score.csv", strip.white=T, as.is=3)[,3]
[1] "yes" "no"  "yes" "no"  "no"  "no"  "yes" "yes"

流石十得ナイフ。