read.tableが使えない事情があって、そのまま読み込むことになり苦戦したのでメモ。
もっとスマートな方法があるかもしれない。
前提条件として「C:\hoge\piyo.csv」を読み込むとする。Windows機でやったけどLinuxとかでもできると思う。
test1,test2,test3
1,2,3
4,5,6
7,8,9
普通のread.tableを使った読み込み
# CSVファイルからデータフレームへ読み込み
d <- read.table("C:\\hoge\\piyo.csv", sep=",", skip=0, header=T, stringsAsFactors=F)
> d
test1 test2 test3
1 1 2 3
2 4 5 6
3 7 8 9
> class(d)
[1] "data.frame"
> sapply(d, class)
test1 test2 test3
"integer" "integer" "integer"
データフレーム型で中身はintegerとなっている。
read.tableを使わない読み込み
strsplitで分割する際にリストの中のリストになるのでそれを取り出す作業が必要になる。
# ファイルオープン
kInputFile <- file("C:\\hoge\\piyo.csv","r") # ファイル読込みモード
line <- readLines(kInputFile) # ファイル読込み
sp <- strsplit(line,",") # カンマ区切りで分割(この時点でspの中身がリストの中のリストになる)
# データ格納領域の初期化
matx <- NULL # 途中の作業用として作成
d <- data.frame() # 最終的にデータフレームで処理したいのでデータフレーム型で作成
# マトリックス型に格納
for (i in 1:length(sp)) {
matx <- rbind(matx, sapply(sp[[i]], as.character)) # リストの中のリストから取り出し、マトリックス型に格納していく
}
# 列名設定
colnames(matx) <- sp[[1]] # 最初の行=タイトル行を各列名として設定
# タイトル削除
matx <- matx[2:length(sp),] # 最初の行の削除(実際はmatxの2行目~最後の行までを格納しなおす)
# マトリックス型→データフレーム型へ
d <- as.data.frame(matx)
# ファイルクローズ
close(kInputFile)
> d
test1 test2 test3
1 1 2 3
2 4 5 6
3 7 8 9
> class(d)
[1] "data.frame"
> sapply(d, class)
test1 test2 test3
"factor" "factor" "factor"
このままだと中身がファクター型になっているため以下を追加。
d$test1 <- as.character(d$test1)
d$test1 <- as.integer(d$test1)
d$test2 <- as.character(d$test2)
d$test2 <- as.integer(d$test2)
d$test3 <- as.character(d$test3)
d$test3 <- as.integer(d$test3)
一度character型へ変換しているのは、
ファクター型ではlabelがcharacter型、levelがnumeric型(labelのインデックス)になっていて、そのままas.integerするとlevelの値つまりlabelのインデックス値が返ってくる。
そのため一度characterへ変換して、labelの値を引き出す必要がある。
この部分のコードはもっと短くできそう。
追記:data.frame()
とかas.data.frame()
などにもstringsAsFactorsの指定ができるみたい。
これによりas.character(d$test1)
などの処理は省ける。
d <- as.data.frame(matx)
↓
d <- as.data.frame(matx, stringsAsFactors=F)
あとは中身を見てみる。
> sapply(d, class)
test1 test2 test3
"integer" "integer" "integer"
これで同じように使える!
「sp <- strsplit(line,",")
」の「","
」を変えればカンマ区切り以外のものにも対応できる。
また、ファイルオープンの際にUTF-8で読込みたい場合は~~「encoding="UTF-8"
」を追加する。~~
ファイルオープン時の読み込みエンコード指定はこっちでした「fileEncoding="UTF-8"
」