2014年9月19日金曜日

colClassesで特定の列の読み込み型だけを指定、他の列はRの判断にまかせる(read.csv、read.table)

例えば↓こんなCSVデータがあったとして、

ファイル名: "data.csv"


id,name,age
001,taro,41
002,hanako,40
003,ichiro,11
004,jiro,2

↓ごく普通に読み込むと・・・

> data <- read.csv("data.csv")
> data
  id   name age
1  1 ichiro  41
2  2 hanako  40
3  3   taro  11
4  4   jiro   2


idの先頭につけていた00がなくなってしまうんですよね。

str関数で型を見てみると、

> str(data)
'data.frame':   4 obs. of  3 variables:
 $ id  : int  1 2 3 4
 $ name: Factor w/ 4 levels "hanako","ichiro",..: 2 1 4 3
 $ age : int  41 40 11 2


idはint型として読み込まれています。idのような用途だと先頭のゼロは残しておきたいってときがありますよね。

そんなときは、colClassesで読み込み時の型を指定してやればいいです。

> data <- read.csv("data.csv", colClasses="character")
> data
   id   name age
1 001 ichiro  41
2 002 hanako  40
3 003   taro  11
4 004   jiro   2


文字列として読み込まれ先頭のゼロも残りました。ただ、上記のように一律「文字列」と指定してしまうと、ageまで文字列になってしまい、↓数値的な処理ができなくなってしまいます。

> mean(data$age)
[1] NA
 警告メッセージ: 
In mean.default(data$age) :
   引数は数値でも論理値でもありません。NA 値を返します 


で、それに対してはすべての列に対して読み込み時の型を指定してやることで対処できます。

> data <- read.csv( "data.csv",
                    colClasses=c("character", "character", "integer"))
> str(data)
'data.frame':   4 obs. of  3 variables:
 $ id  : chr  "001" "002" "003" "004"
 $ name: chr  "ichiro" "hanako" "taro" "jiro"
 $ age : int  41 40 11 2


ageは整数にしておいたので、平均も計算できます。

> mean(data$age)
[1] 23.5


が、このcolClassesにすべての型を明に指定するというのは、列が10個も20個もある場合はかなり面倒くさいです。

やっと本題に来ました。

やりたいこととしては、「idの列は文字列で読み込みたいけど、その他の列はRの判断に任せるよ」ってな感じですね。

そんなときは、Rのデフォルトで読み込んでほしい列に対応するベクトルの要素を、NAにしておけばOKです。

> data <- read.csv("data.csv", colClasses=c("character", NA, NA))
> str(data)
'data.frame':   4 obs. of  3 variables:
 $ id  : chr  "001" "002" "003" "004"
 $ name: Factor w/ 4 levels "hanako","ichiro",..: 2 1 4 3
 $ age : int  41 40 11 2


↑1列目は強制的に文字列で読み込みましたが、他の列の判断はRに任せました。

ちなみに、例はread.csvで書いていますが、read.tableでも同様の方法が使えます。

列がたくさんあってNAを書くのが面倒な場合は、NAのベクトルを作っておいて、指定したい箇所だけを上書きすれば楽かもしれません。

CC      <- rep(NA, 20) # NAだけのベクトル
CC[1]   <- "character" # 1つ目だけ"character"に書き換える
manycol <- read.csv("manycol.csv", colClasses=CC)


たくさん列のあるデータを読み込むんだけど、使うのはいくつかの列だけ、なんてことも結構ありますからね。




0 件のコメント:

コメントを投稿