readr,haven,readxl

readr とは?

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

CRANからのインストールは

install.packages("readr")

でできます。

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 と打ち込むと

# A tibble: 3 x 3
     魔    方    陣
  <int> <int> <int>
1     2     9     4
2     7     5     3
3     6     1     8

と表示されます。この表示からもわかるように,結果は通常のデータフレームではなく tibble という型になります。この1行目は x[1,] で得られますが,この1列目は x[,1] とするとベクトルではなく1列の tibble になってしまいます。1列目をベクトルとして取り出すには x[[1]] とする必要があります。

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

# 従来のread.csv()
system.time({x1 = read.csv("~/public_html/stat/data/fukushima.csv", as.is=TRUE)})
   ユーザ   システム       経過  
     0.973      0.029      1.002 
system.time(print(mean(x1$lat)))
[1] 37.59176
   ユーザ   システム       経過  
     0.001      0.000      0.001 
system.time(print(mean(x1$lon)))
[1] 140.4282
   ユーザ   システム       経過  
     0.001      0.000      0.001 
system.time(print(mean(as.POSIXct(x1$datetime))))
[1] "2011-07-18 01:52:49 JST"
   ユーザ   システム       経過  
     7.978      3.138     11.164 
# 新しいread_csv()
system.time({x2 = read_csv("~/public_html/stat/data/fukushima.csv")})
Parsed with column specification:
cols(
  lat = col_double(),
  lon = col_double(),
  radiation = col_double(),
  datetime = col_character()
)
   ユーザ   システム       経過  
     0.304      0.014      0.319 
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.001 
system.time(print(mean(as.POSIXct(x2$datetime))))
[1] "2011-07-18 01:52:49 JST"
   ユーザ   システム       経過  
     7.816      3.181     11.011 

読み込みは劇的に早くなりましたが,他の計算は当然ながら変わりません。特に,日時を表す文字列を内部形式に変換する 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.082      0.001      0.084 
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"
   ユーザ   システム       経過  
     1.146      0.008      1.155 

ロケールを指定しなければ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.359      0.015      0.374 

haven

そのうち書きます。

readxl

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


Last modified: