readr,haven,readxl

[2016-08-05] readr 1.0.0 がCRANに入りました。

readr とは?

readr はHadley Wickham作のデータ読み込み用パッケージです。R標準の read.csv() などと比べて,ずっと高速かつ便利です(data.table パッケージの fread() がさらに高速です)。

CRANからのインストールは

install.packages("readr")

でできます。

より新しいものが GitHub の hadley/readr にあるかもしれません。その場合には次のようにすれば最新のものがインストールできます:

# install.packages("devtools")
devtools::install_github("hadley/readr")

以下ではCRAN版0.2.0について書きます。

R標準の関数と違い,read_delim()read_csv()read_tsv()read_csv2()read_fwf()read_table()read_log() のように,アンダーバーを含む名前になっています。

例えばCSVファイルを読むには

library(readr)
x = read_csv("ファイル名またはURL")

とします。主なオプションは次の通りです:

文字コード(エンコーディング)はデフォルトではUTF-8ですが,次のようにすれば任意のロケールが指定できます:

x = read_csv("test.csv", locale=locale(encoding="CP932"))  # またはSJISなど

ロケールについては locale()default_locale() を調べてください。おもしろいのは,デフォルトでは3桁ごとのカンマを含む数値をちゃんとパースできることです。Excelで3桁ごとにカンマを付けて表示しているときにCSV保存すると,例えば123456789は "123,456,789 " のように(なぜか余分なスペースも付いて)保存されます。これをR標準の read.csv() で読むと文字列になってしまいますが,read_csv() なら正しくパースできます。

おもしろい使い方として,x = read_csv(" まで打ってから,データをRコンソールにコピペし,") を打ち込むという方法も使えます。例えば

x = read_csv("魔,方,陣
2,9,4
7,5,3
6,1,8")

のような感じです。これで x と打ち込むと

  魔 方 陣
1  2  9  4
2  7  5  3
3  6  1  8

と表示されます。

現実的な例でやってみましょう。RgoogleMapsを使った放射線地図で使った福島県の放射線データ fukushima.csv は,422656地点の緯度(lat),経度(lon),放射線(radiation,μSv/h単位),日時(datetime)を収めたものです。これをローカルにダウンロードして,読み込んで,それぞれの欄の平均値を表示し,時間を計測してみましょう。

# 従来のread.csv()
system.time({x1 = read.csv("~/public_html/stat/data/fukushima.csv", as.is=TRUE)})
   ユーザ   システム       経過  
     3.324      0.060      3.438 
system.time(print(mean(x1$lat)))
[1] 37.59176
   ユーザ   システム       経過  
     0.002      0.000      0.001 
system.time(print(mean(x1$lon)))
[1] 140.4282
   ユーザ   システム       経過  
     0.002      0.000      0.001 
system.time(print(mean(as.POSIXct(x1$datetime))))
[1] "2011-07-18 01:52:49 JST"
   ユーザ   システム       経過  
    11.498      3.929     15.827 
# 新しいread_csv()
system.time({x2 = read_csv("~/public_html/stat/data/fukushima.csv")})
   ユーザ   システム       経過  
     0.283      0.015      0.298 
system.time(print(mean(x2$lat)))
[1] 37.59176
   ユーザ   システム       経過  
     0.001      0.000      0.001 
system.time(print(mean(x2$lon)))
[1] 140.4282
   ユーザ   システム       経過  
     0.001      0.000      0.002 
system.time(print(mean(as.POSIXct(x2$datetime))))
[1] "2011-07-18 01:52:49 JST"
   ユーザ   システム       経過  
    11.486      3.952     15.459 

読み込みは劇的に早くなりましたが,他の計算は当然ながら変わりません。特に,日時を表す文字列を内部形式に変換する as.POSIXct() の遅さが目立ちます。そこで,readr に含まれている parse_datetime() を使ってみます。

system.time(print(mean(parse_datetime(x2$datetime, format="%Y/%m/%d %H:%M:%S"))))
[1] "2011-07-18 01:52:49 UTC"
   ユーザ   システム       経過  
     0.136      0.004      0.141 
system.time(print(mean(parse_datetime(x2$datetime, format="%Y/%m/%d %H:%M:%S", locale=locale(tz="Asia/Tokyo")))))
[1] "2011-07-18 01:52:49 JST"
   ユーザ   システム       経過  
     2.001      0.006      2.010 

ロケールを指定しなければ2桁高速化できました。指定した場合はやや遅くなりますが,それでも as.POSIXct() よりは高速です。

次のように読み込み時点で日時のフォーマットを指定することが可能ですが,現時点ではロケールは指定できないようです:

system.time({x2 = read_csv("~/public_html/stat/data/fukushima.csv",
                           col_types=cols(
                             datetime=col_datetime(format="%Y/%m/%d %H:%M:%S")
                           ))})
   ユーザ   システム       経過  
     0.376      0.044      0.680 

haven

そのうち書きます。

readxl

とりあえずRでExcelのデータを読む方法をお読みください。


Last modified: