5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Rでread.tableを使わずに同じようにデータフレームとしてCSVを読み込む

Last updated at Posted at 2015-10-08

read.tableが使えない事情があって、そのまま読み込むことになり苦戦したのでメモ。
もっとスマートな方法があるかもしれない。

前提条件として「C:\hoge\piyo.csv」を読み込むとする。Windows機でやったけどLinuxとかでもできると思う。

piyo.csv
test1,test2,test3
1,2,3
4,5,6
7,8,9

普通のread.tableを使った読み込み

read.table.R
# 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で分割する際にリストの中のリストになるのでそれを取り出す作業が必要になる。

no_read.table.R
# ファイルオープン
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"

5
4
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?