を使用してviaにas.Date
変換character
するだけだと思います。そして、非常に遅いと思います。Date
POSIXlt
strptime
strptime
自分でトレースするには、 を入力してから を入力しas.Date
、メソッドmethods(as.Date)
を調べます。character
> as.Date
function (x, ...)
UseMethod("as.Date")
<bytecode: 0x2cf4b20>
<environment: namespace:base>
> methods(as.Date)
[1] as.Date.character as.Date.date as.Date.dates as.Date.default
[5] as.Date.factor as.Date.IDate* as.Date.numeric as.Date.POSIXct
[9] as.Date.POSIXlt
Non-visible functions are asterisked
> as.Date.character
function (x, format = "", ...)
{
charToDate <- function(x) {
xx <- x[1L]
if (is.na(xx)) {
j <- 1L
while (is.na(xx) && (j <- j + 1L) <= length(x)) xx <- x[j]
if (is.na(xx))
f <- "%Y-%m-%d"
}
if (is.na(xx) || !is.na(strptime(xx, f <- "%Y-%m-%d",
tz = "GMT")) || !is.na(strptime(xx, f <- "%Y/%m/%d",
tz = "GMT")))
return(strptime(x, f))
stop("character string is not in a standard unambiguous format")
}
res <- if (missing(format))
charToDate(x)
else strptime(x, format, tz = "GMT") #### slow part, I think ####
as.Date(res)
}
<bytecode: 0x2cf6da0>
<environment: namespace:base>
>
なぜas.POSIXlt(Date)$year+1900
比較的速いのですか?繰り返しますが、それをたどってください:
> as.POSIXct
function (x, tz = "", ...)
UseMethod("as.POSIXct")
<bytecode: 0x2936de8>
<environment: namespace:base>
> methods(as.POSIXct)
[1] as.POSIXct.date as.POSIXct.Date as.POSIXct.dates as.POSIXct.default
[5] as.POSIXct.IDate* as.POSIXct.ITime* as.POSIXct.numeric as.POSIXct.POSIXlt
Non-visible functions are asterisked
> as.POSIXlt.Date
function (x, ...)
{
y <- .Internal(Date2POSIXlt(x))
names(y$year) <- names(x)
y
}
<bytecode: 0x395e328>
<environment: namespace:base>
>
興味をそそられたので、Date2POSIXlt を掘り下げてみましょう。このビットでは、参照する .c ファイルを知るために main/src を grep する必要があります。
~/R/Rtrunk/src/main$ grep Date2POSIXlt *
names.c:{"Date2POSIXlt",do_D2POSIXlt, 0, 11, 1, {PP_FUNCALL, PREC_FN, 0}},
$
これで、 D2POSIXlt を探す必要があることがわかりました。
~/R/Rtrunk/src/main$ grep D2POSIXlt *
datetime.c:SEXP attribute_hidden do_D2POSIXlt(SEXP call, SEXP op, SEXP args, SEXP env)
names.c:{"Date2POSIXlt",do_D2POSIXlt, 0, 11, 1, {PP_FUNCALL, PREC_FN, 0}},
$
おお、datetime.c を推測できたはずです。とにかく、最新のライブコピーを見てください:
日時.c
そこを検索するD2POSIXlt
と、Date (数値) から POSIXlt への移行がいかに簡単であるかがわかります。また、POSIXlt が 1 つの実数ベクトル (8 バイト) と 7 つの整数ベクトル (それぞれ 4 バイト) であることがわかります。1 日あたり 40 バイトです。
したがって、問題の核心 (私が思う) はなぜstrptime
が非常に遅いかということであり、R で改善できる可能性があります。またはPOSIXlt
、直接的または間接的に を回避するだけです。
質問に記載されているアイテムの数 (3,000,000) を使用した再現可能な例を次に示します。
> Range = seq(as.Date("2000-01-01"),as.Date("2012-01-01"),by="days")
> Date = format(sample(Range,3000000,replace=TRUE),"%m/%d/%Y")
> system.time(as.Date(Date, "%m/%d/%Y"))
user system elapsed
21.681 0.060 21.760
> system.time(strptime(Date, "%m/%d/%Y"))
user system elapsed
29.594 8.633 38.270
> system.time(strptime(Date, "%m/%d/%Y", tz="GMT"))
user system elapsed
19.785 0.000 19.802
追い越しtz
はスピードアップするように見えますが、実際strptime
にas.Date.character
そうです。だから多分それはあなたのロケールに依存します。しかしstrptime
、犯人ではなく、犯人のようdata.table
です。この例を再実行して、自分のマシンで 90 秒かかるかどうかを確認してください。