Edited at

R で文字列を POSIX time に変換するには lubridate::parse_date_time2() がちょっぱや #rstatsj

More than 3 years have passed since last update.

こういう話がある。


日時を表す文字列を内部形式に変換する as.POSIXct() が遅すぎてどうにもなりません。


https://oku.edu.mie-u.ac.jp/~okumura/stat/datatable.html

リンク先での解決策は fasttime パッケージを使えということですが、fasttime は CRAN に登録されておらず、RForge からインストールしなければなりません。

そこでみなさんに朗報です。

lubridate パッケージには fasttime から引き継いだ高速に POSIX time に変換できる関数が備わっています。


Lubridate has an inbuilt very fast POSIX parser, ported from the fasttime package by Simon Urbanek.


http://cran.r-project.org/web/packages/lubridate/lubridate.pdf

ここでは、従来の変換方法(strptime(), as.POSIXlt(), as.POSIXct()) と lubridate の高速変換関数(fast_strptime(), parse_date_time(), parse_date_time2()) の速度を比較してみます。

まずは、POSIX time に変換するための日付の文字列データを作成します。

データ作成には easyRFM パッケージの rfm_generate_data() 関数で生成したデータの date のみを取り出して使用します(参考:R でランダムに日付を生成する)


R

library(easyRFM)

data <- rfm_generate_data(10000, date_type = "POSIXlt")
dates <- as.character(data$date)
head(dates, 3)



結果

[1] "2014-12-23 11:55:49" "2014-12-20 13:10:27" "2014-12-30 11:36:13"


速度比較には microbenchmark パッケージを使用します(参考:Performance - Advanced R.)


R

library(lubridate)

library(microbenchmark)

format <- "%Y-%m-%d %H:%M:%S"
microbenchmark(
strptime(dates, format), # POSIXlt
as.POSIXlt(dates), # POSIXlt
as.POSIXct(dates), # POSIXct
fast_strptime(dates, format), # POSIXct
parse_date_time(dates, format, locale="C"), # POSIXct
parse_date_time2(dates, format) # POSIXct
)



結果

Unit: milliseconds

expr min lq mean median uq max
strptime(dates, format) 119.282499 121.572364 125.532569 123.448221 126.284024 226.923822
as.POSIXlt(dates) 356.200412 361.551208 370.189893 366.233237 373.489523 482.525819
as.POSIXct(dates) 461.641756 470.231105 479.100893 475.003683 483.682588 527.847680
fast_strptime(dates, format) 1.754354 1.842088 1.994004 1.935617 2.024675 4.292026
parse_date_time(dates, format, locale = "C") 12.997912 13.606424 14.342025 13.951237 14.918299 18.339108
parse_date_time2(dates, format) 1.409045 1.486185 1.667954 1.589646 1.697741 3.779194

結果は、lubridateparse_date_time2() 関数がちょっぱやという結果になりました。

enjoy!